29

I am trying to achieve the following.

Read a custom header and its value from Request:

name: username

Now, on response, I would like to return the same header name:value pair in HTTP response.

I am using Jersey 2.0 implementation of JAX-RS webservice.

When I send the request URL Http://localhost/test/, the request headers are also passed (for the time being, though Firefox plugin - hardcoding them).

On receiving the request for that URL, the following method is invoked:

@GET
@Produces(MediaType.APPLICATION_JSON)
public UserClass getValues(@Context HttpHeaders header) {
    MultivaluedMap<String, String> headerParams = header.getRequestHeaders();
    String userKey = "name";
    headerParams.get(userKey);

    // ...

    return user_object;
}

How may I achieve this? Any pointers would be great!

informatik01
  • 16,038
  • 10
  • 74
  • 104
Namenoobie
  • 541
  • 2
  • 8
  • 15

4 Answers4

58

I think using javax.ws.rs.core.Response is more elegant and it is a part of Jersey. Just to extend previous answer, here is a simple example:

    @GET
    @Produces({ MediaType.APPLICATION_JSON })
    @Path("/values")
    public Response getValues(String body) {

        //Prepare your entity

        Response response = Response.status(200).
                entity(yourEntity).
                header("yourHeaderName", "yourHeaderValue").build();

        return response;
    }
Alex P
  • 1,721
  • 1
  • 17
  • 18
  • 7
    to make it even more simple replace `.status(200).entity` with `.ok`. – Reto Gmür Oct 29 '15 at 21:21
  • This might cause issues with automatic API documentation generation using [swagger codegen](https://github.com/swagger-api/swagger-codegen). – koppor Feb 23 '17 at 15:55
38

Just inject a @Context HttpServletResponse response as a method argument. Change the headers on that

@Produces(MediaType.APPLICATION_JSON)
public UserClass getValues(@Context HttpHeaders header, @Context HttpServletResponse response) {
    response.setHeader("yourheadername", "yourheadervalue");
    ...
}
dvs
  • 12,324
  • 6
  • 38
  • 45
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • I found that this didn't work, at least not when the HttpServletResponse is a member of the class as opposed to a method argument. Instead, we implemented a ContainerResponseFilter to intercept the response and add headers to the context. – Wheezil Mar 02 '22 at 16:12
2

Return a Response (a class from JAX-RS) with UserClass as the entity. On the Response you can set HTTP headers.

0

I found that the HttpServletResponse approach did not work. Instead, we installed a custom response filter:

@Provider
public class MyFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext ctx) throws IOException {
        ArrayList<Object> valueList = new ArrayList<>();
        valueList.add("my-header-value");
        ctx.getHeaders().put("My-header", valueList);
        ...
    }
}

And the web app:

public class MyApp extends Application {
    static Set<Object> singletons = new LinkedHashSet<>();
    public static void setSingletons(Set<Object> singletons) {
        MyApp.singletons = singletons;
    }
    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

Set<Object> singletons = new LinkedHashSet<>();
singletons.add(new MyFilter());
MyApp.setSingletons(singletons);
Wheezil
  • 3,157
  • 1
  • 23
  • 36