对于来自 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) 导航到您在 在 resteasy 中看不到任何 BindingPriority 注释。 jboss 7的standalone.xml中没有valve设置(server.xml是旧版本)。 试过@Priority 但仍然没有帮助。该问题似乎与 jax-rs 或 resteasy 无关。【参考方案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 应用程序总是返回 404

Jboss Wildfly resteasy 升级

无法在 Jboss 7 中添加 resteasy 本地模块

使用 RESTeasy 和 JBoss 的外部 @EJB 注入返回 null

Springboot 与 RestEasy 集成并部署到 Jboss 服务器

JAX-RS + JBoss 7.1.1 + RESTEasy:使用 CDI 的 NullPointException