对于来自 RESTEasy 的所有响应,JBoss7 将 Cache-Control、Pragma 设置为 no-cache
Posted
技术标签:
【中文标题】对于来自 RESTEasy 的所有响应,JBoss7 将 Cache-Control、Pragma 设置为 no-cache【英文标题】:JBoss7 setting Cache-Control, Pragma to no-cache for all responses from RESTEasy 【发布时间】:2016-05-07 22:45:48 【问题描述】:我正在尝试将 Cache-Control 标头添加到使用 RESTEasy 框架在 JBoss 7 中生成的响应中。但是,由于 JBoss 默认添加了 no-cache 标头,所有响应最终都会获得多个 Cache-Control 标头。
我找不到任何设置来删除它,并且添加拦截器也不起作用,因为稍后会添加无缓存标头。
谁能告诉我如何禁用 JBoss 7 中的默认编译指示和缓存控制标头?
注意:我正在使用带有无状态 EJB 的 resteasy。
@Path("/api")
@Local
public interface UCSRestServiceInterface
@GET
@Path("/token")
@Produces("application/json")
@Cache(maxAge = 3600, noTransform = true)
public Response getToken();
获取响应标头为,
"pragma": "No-cache",
"date": "Thu, 11 Feb 2016 20:16:30 GMT",
"content-encoding": "gzip",
"server": "Apache-Coyote/1.1",
"x-frame-options": "SAMEORIGIN",
"vary": "Accept-Encoding,User-Agent",
"content-type": "application/json",
"cache-control": "no-cache, no-transform, max-age=3600",
"transfer-encoding": "chunked",
"connection": "Keep-Alive",
"keep-alive": "timeout=15, max=100",
"expires": "Wed, 31 Dec 1969 19:00:00 EST"
【问题讨论】:
写一个过滤器。接受回应;并操作你想要的标题。 我对 wildfly 10 也有同样的问题(在 wildfly 8 中也似乎是这样),响应标头中总是存在以下内容:“Cache-Control: no-cache ,无商店,必须重新验证”。添加@Cache 注释只是添加了第二个标头字段。这不可能是正确的行为!你找到解决这个问题的方法了吗? 【参考方案1】:Web 应用程序中的过滤器资源基本上可以让您拦截请求和响应,并且主要设计用于通过更改请求/响应标头来工作的一些用例。更多详情here
由于您使用的是 RESTEasy,您可以使用 ContainerResponseFilter; JAX-RS 提供的过滤器接口。您可以通过实现此接口来编写自定义过滤器。过滤器类(添加一个到您的网络应用程序源代码)将如下所示:-
@Provider
public class YourCustomFilter implements ContainerResponseFilter
// you can check the actual string value by using method "getStringHeaders" on 'resp' below
private static final String CACHE_CONTROL = "cache-control";
@Override
public void filter(ContainerRequestContext req,
ContainerResponseContext resp) throws IOException
if(resp.getHeaders().containsKey(CACHE_CONTROL))
resp.getHeaders().remove(CACHE_CONTROL);
resp.getHeaders().add(CACHE_CONTROL, "no-transform, max-age=3600");
resp.getHeaders().add(CACHE_CONTROL, "no-transform, max-age=3600");
在这里,您基本上检查 Cache-Control 标头的存在,如果存在,请删除现有的并添加您自己的。
请不要忘记 jax rs 运行时需要 @Provider
注释来发现您的自定义过滤器。
请注意,使用此过滤器,所有对您的 web 应用程序的请求都将被拦截。如果想拦截某个资源或者资源方法可以探索@NameBinding的使用
让我知道这是否有效。
【讨论】:
对不起。但是添加过滤器也不能解决问题。过滤器找到的唯一标头是 content-type,这表明 JBOSS 在处理响应过滤器后添加 Pragma + Cache-Control 标头。 看起来access.redhat.com/solutions/28847 有解决方案,但我没有付费订阅来查看它。 对不起。离开 SO 几天了。您可以尝试两件事:- 1) 尝试将 @BindingPriority(0) 注释添加到您的过滤器。 2) 导航到您在我发现此解决方法包括在“Cache-Control”标头存在且“no-cache”不存在时为 Pragma 标头设置空值
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Priority(Priorities.HEADER_DECORATOR - 1)
@Provider
public class PragmaRemover implements ContainerResponseFilter
private static final String PRAGMA = "Pragma";
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
if(headers.containsKey(HttpHeaders.CACHE_CONTROL))
for (Object header : headers.get(HttpHeaders.CACHE_CONTROL))
CacheControl cacheControl = (CacheControl) header;
if(!cacheControl.isNoCache())
headers.add(PRAGMA, "");
Priorities.HEADER_DECORATOR - 1
是为了确定缓存头已经被resteasy设置好了。
别忘了将此过滤器添加到您的 Jax-Rs 应用程序中。
【讨论】:
以上是关于对于来自 RESTEasy 的所有响应,JBoss7 将 Cache-Control、Pragma 设置为 no-cache的主要内容,如果未能解决你的问题,请参考以下文章
使用 RESTeasy 和 JBoss 的外部 @EJB 注入返回 null