Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Request Headers

Tags:

java

jax-rs

How to access request headers in implementation of WriterInterceptor interface in JAX-RS?

context.getHeaders(); //This line gives a set of response headers(not request headers) in the WriterInterceptor implementation.

Complete code below:

public class GzipFilterWriterInterceptor implements WriterInterceptor {

private static final Logger LOG = LoggerFactory.getLogger(GzipFilterWriterInterceptor.class);

@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
    MultivaluedMap<String,Object> headers = context.getHeaders();
    headers.add("Content-Encoding", "gzip");


    final OutputStream outputStream = context.getOutputStream();
    context.setOutputStream(new GZIPOutputStream(outputStream));
    context.proceed();
}

}
like image 350
Shubham Kumar Avatar asked Nov 24 '16 06:11

Shubham Kumar


3 Answers

@Provider
public class GzipFilterWriterInterceptor implements WriterInterceptor
{

    private static final Logger LOG = LoggerFactory.getLogger(GzipFilterWriterInterceptor.class);

    // use a context injection
    @Context 
    private HttpHeaders httpHeaders;

    @Override
    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException
    {
        MultivaluedMap<String,Object> headers = context.getHeaders();
        headers.add("Content-Encoding", "gzip");

        // do stuff with headers
        if ("Basic Ym9iOnBhc3N3b3Jk".equals(httpHeaders.getRequestHeader("Authorization").get(0)))
        {
            //do stuff here, but be careful about the indexoutofbounds...
        }


        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }

}

The context injection will be injected per request, see the javadocs.

like image 62
Jason Pyeron Avatar answered Nov 15 '22 14:11

Jason Pyeron


You can just inject HttpHeaders. It will be a thread-local proxy when it's injected, so it's thread safe.

@Context
private HttpHeaders headers;

It has methods

  • String getHeaderString(String name)
  • List<String> getRequestHeader(String name)
  • MultivaluedMap<String,String> getRequestHeaders()

UPDATE (test)

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
import java.util.logging.Logger;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

/**
 * Run like any other JUnit test. Only one required dependency:
 * 
 *  <dependency>
 *    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
 *    <artifactId>jersey-test-framework-provider-inmemory</artifactId>
 *    <scope>test</scope>
 *    <version>${jersey.version}</version>
 *  </dependency>
 */
public class HeadersTest extends JerseyTest {

    @Path("hello")
    public static class HelloResource {
        @GET
        public String get() {
            return "Hello";
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig(HelloResource.class)
                .register(HeaderWriter.class)
                .register(new LoggingFilter(Logger.getAnonymousLogger(), true));
    }

    @Provider
    public static class HeaderWriter implements WriterInterceptor {
        @Context
        private HttpHeaders headers;

        @Override
        public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
            context.proceed();

            final String header = headers.getHeaderString("X-Request-Header");
            context.getHeaders().add("X-Response-Header", header);
        }
    }

    @Test
    public void doit() {
        final Response response = target("hello").request()
                .header("X-Request-Header", "BooYah")
                .get();
        assertThat(response.getHeaderString("X-Response-Header"), is("BooYah"));
    }
}
like image 28
Paul Samsotha Avatar answered Nov 15 '22 15:11

Paul Samsotha


You can implement below code to ,see working example at http://jerseyexample-ravikant.rhcloud.com/rest/jws/say/Hello

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class SecurityInterceptor implements ContainerRequestFilter, ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext reqCtx, ContainerResponseContext respCtx) throws IOException {

        long startTime=0;
        System.out.println("Adding ProcessingTime in response headers"); 
        if(reqCtx.getHeaderString("startTime")!=null)
        startTime = Long.parseLong(reqCtx.getHeaderString("startTime")); 
        respCtx.getHeaders().add("ProcessingTime",
                String.valueOf(System.currentTimeMillis() - startTime) + " millisecs"); 
    }

    @Override
    public void filter(ContainerRequestContext reqCtx) throws IOException {
        System.out.println("Adding start time in request headers");

        reqCtx.getHeaders().add("startTime", String.valueOf(System.currentTimeMillis()));

    }

}
like image 38
gladiator Avatar answered Nov 15 '22 15:11

gladiator