Custom response header Jersey/Java
Asked Answered
C

4

30

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!

Colemancolemanite answered 26/7, 2013 at 13:52 Comment(0)
S
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");
    ...
}
Sharronsharyl answered 26/7, 2013 at 13:55 Comment(1)
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.Denier
W
59

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;
    }
Whimsey answered 20/1, 2014 at 9:11 Comment(2)
to make it even more simple replace .status(200).entity with .ok.Overslaugh
This might cause issues with automatic API documentation generation using swagger codegen.Creativity
S
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");
    ...
}
Sharronsharyl answered 26/7, 2013 at 13:55 Comment(1)
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.Denier
L
2

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

Libel answered 26/7, 2013 at 13:55 Comment(2)
I am sorry, I don't follow. could you elaborate?Colemancolemanite
This is not a viable approach if your method returns a body using @Produces. Our http methods typically implement interfaces that are not HTTP aware.Denier
D
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);
Denier answered 2/3, 2022 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.