【发布时间】:2019-06-27 01:46:51
【问题描述】:
您好,我想在完成处理(执行逻辑)并以 HTTP 状态代码结束后修改我的一些 API 响应标头。
例如,如果响应是 404,则包括特定的,例如 Cache-Control Headers example dont cache,或类似的东西。
我已经注册了 2 个OncePerRequestFilter,它们工作正常——但显然我不能做逻辑——一旦处理完成。 CacheControlFilter 已经具有默认添加一些 Cache-Control 标头的逻辑 - 例如缓存 15 秒等。尽管这似乎发生在调度的早期阶段以及当它发生时(在响应中添加标头)到达执行实际Controller/Endpoint 的阶段,并且有一个异常或错误显然将由通知等处理,我不能mutate 这些已经存在的标题 - 已经由过滤器添加。
@Bean
public FilterRegistrationBean filterOne() {
Filter filter = new FilterOne();
return createFilter(filter, "FilterOne",List.of("/*"));
}
@Bean
public FilterRegistrationBean cacheControlFilter() {
Filter filter = new CacheControlFilter();
return createFilter(filter, "CacheControlFilter", List.of("/*"));
}
private FilterRegistrationBean createFilter(Filter aFilter, String filterName,
List<String> urlPatterns) {
FilterRegistrationBean filterRegBean = new FilterRegistrationBean(aFilter);
filterRegBean.addUrlPatterns(urlPatterns.toArray(new String[0]));
filterRegBean.setName(filterName);
filterRegBean.setEnabled(true);
filterRegBean.setAsyncSupported(true);
return filterRegBean;
}
我已经尝试添加HttpServletResponseWrapper,如here 和here 上的CacheControlFilter 上的这些帖子所示,但它似乎不起作用。我还看到了类似的 S.O 线程 here。
HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response) {
@Override
public void setStatus(int sc) {
super.setStatus(sc);
handleStatus(sc);
}
@Override
@SuppressWarnings("deprecation")
public void setStatus(int sc, String sm) {
super.setStatus(sc, sm);
handleStatus(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
super.sendError(sc, msg);
handleStatus(sc);
}
@Override
public void sendError(int sc) throws IOException {
super.sendError(sc);
handleStatus(sc);
}
private void handleStatus(int code) {
if(code == 404)
addHeader("Cache-Control, "xxx");
}
};
但是代码根本没有执行!因此,我只想在处理完成并且准备好返回响应之后,才在第二个过滤器上操作 Cache-Control 标头。
我不确定我是否也有,做一些清理并在错误时设置响应 - 把事情搞混了!
@ControllerAdvice
@Slf4j
public class GlobalErrorHandler
更新:请注意,当我的控制器抛出异常或错误时,上面的 GlobalErrorHandler 被调用,我在那里执行特殊处理,返回 error response。我看到的是magically 响应已经具有由过滤器(CacheControlFilter)填充的default 标头。所以它最终有点奇怪,我添加了额外的逻辑,以更改控制标头,我最终得到一个具有相同标头的响应 2 次(1 具有由 CacheControlFilter 设置的值,然后是任何特殊值我我试图覆盖ControllerAdvice
任何提示或帮助表示感谢!我使用 Spring Boot 2.1.2 和 Undertow 作为我的底层 servlet 容器。
【问题讨论】:
-
您是否使用@RestController(或Controller)来公开您的API?
-
是的,我愿意。用更多的上下文更新了问题 - 与您下面的
answer相关
标签: spring spring-boot spring-mvc servlet-filters undertow