所以注入HttpServletResponse 似乎不行。只有某些可代理的类型可以注入到单例中。我相信完整的列表如下:
HttpHeaders, Request, UriInfo, SecurityContext
这在 JAX-RS 规范中有所指出,但在 Jersey 参考指南中解释得更清楚
对于特定的请求对象存在例外,这些对象甚至可以注入到构造函数或类字段中。对于这些对象,运行时将注入能够同时处理更多请求的代理。这些请求对象是HttpHeaders、Request、UriInfo、SecurityContext。这些代理可以使用@Context 注解注入。
SecurityContext 可能是泽西岛特有的,因为规范中没有说明,但我不确定。
现在上面提到的那些类型对你来说并没有多大作用,因为它们都是请求上下文,没有什么可以设置响应。
一个想法是使用javax.ws.rs.container.ContainerResponseFilter 和HttpHeaders 来设置临时请求标头。您可以通过传递给filter 方法的ContainerRequestContext 访问该标头。然后只需通过ContainerResponseContext设置响应头,也传递给filter方法。如果标头不是特定于该资源方法的上下文,那么它就更容易了。只需在过滤器中设置标题即可。
但是假设头部依赖于资源方法的执行。然后你可以做类似的事情
@Singleton
@Path("/singleton")
public class SingletonResource {
@Context
javax.ws.rs.core.HttpHeaders headers;
@GET
public String getHello() {
String result = resultFromSomeCondition(new Object());
headers.getRequestHeaders().putSingle("X-HELLO", result);
return "Hello World";
}
private String resultFromSomeCondition(Object condition) {
return "World";
}
}
那么ContainerResponseFilter 可能看起来像这样
@Provider
public class SingletonContainerResponseFilter
implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext crc,
ContainerResponseContext crc1) throws IOException {
String header = crc.getHeaderString("X-HELLO");
crc1.getHeaders().putSingle("X-HELLO", "World");
}
}
只有单例类通过这个过滤器,我们可以简单地使用@NameBinding注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;
@NameBinding
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SingletonHeader {}
...
@SingletonHeader
public class SingletonResource {
...
@SingletonHeader
public class SingletonContainerResponseFilter
implements ContainerResponseFilter {
这是我能想到的处理这种情况的唯一方法。
资源: