访问请求标头

时间:2016-11-24 06:30:15

标签: java jax-rs

如何在JAX-RS中实现WriterInterceptor接口时访问请求头?

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

完整的代码如下:

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();
}

}

4 个答案:

答案 0 :(得分:7)

你可以注入HttpHeaders

时,它会在注入时成为线程本地代理,因此它是线程安全的。

@Context
private HttpHeaders headers;

它有方法

更新(测试)

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"));
    }
}

答案 1 :(得分:3)

您可以在下面的代码中实现,请参阅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()));

    }

}

答案 2 :(得分:1)

可能不是最好的解决方案,但你可以让你的拦截器实现ReaderInterceptor。在那里你可以获得标题并将它们保存在ThreadLocal变量中,这样你就可以在WriterInterceptor中访问它了

此外,如果您有基于注释的配置,您可以尝试使用@Context注释注入ContainerRequestContext

答案 3 :(得分:1)

@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();
    }

}

将根据请求注入上下文注入,请参阅javadocs