我有以下拦截器:
public class SecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
response.addHeader("X-Frame-Options", "DENY");
}
}
我查了一下 - 春天在每次http resquest上调用它。
我注意到奇怪的事情。它适用于这样的控制器:
@Controller
public class AdminViewController {
@GetMapping ("data")
public String dataTemplate() {
return "data";
}
}
但它并没有像这样向控制器添加响应头:
@RestController
@RequestMapping(Constants.MY_API_URL)
public class DataServiceController {
@PostMapping(value = "/mapping", consumes = "application/json")
public ResponseEntity<Void> saveMapping(@RequestBody MappingDTO mapping, HttpServletRequest request) {
...
return new ResponseEntity<>(CREATED);
}
}
但是我可以解释它,因为拦截器正在调用。
如何为所有请求响应添加标头?
答案 0 :(得分:6)
HandlerInterceptorAdapter
无法使用@ResponseBody
和ResponseEntity
方法,因为这些方法由HttpMessageConverter
处理,在调用postHandle
之前写入响应,这使得它成为可能很难改变回应。
相反,您可以编写ResponseBodyAdvice
并将其标记为@ControllerAdvice
以添加所需的标题。
@ControllerAdvice
public class ResponseDTOFilterAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(final Object body, final MethodParameter returnType, final MediaType selectedContentType,
final Class<? extends HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest request,
final ServerHttpResponse response) {
if (body instanceof ResponseEntity) {
ResponseEntity responseEntity = (ResponseEntity) body;
responseEntity.getHeaders().add("X-Frame-Options", "DENY");
}
return body;
}
}
答案 1 :(得分:3)
我正在创建过滤器:
public class SecurityFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpRequest,
HttpServletResponse httpResponse,
FilterChain filterChain) throws ServletException, IOException {
httpResponse.setHeader("X-FRAME-OPTIONS", "DENY");
filterChain.doFilter(httpRequest, httpResponse);
}
}
并注册:
@Configuration
public class SecurityConfiguration {
@Bean
public FilterRegistrationBean dawsonApiFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SecurityFilter());
return registration;
}
}
答案 2 :(得分:1)
先生,对于特定的控制器,您可以尝试这个程序
@RestController
@RequestMapping(Constants.MY_API_URL)
public class DataServiceController {
@PostMapping(value = "/mapping", consumes =
"application/json")
public ResponseEntity<Boolean>
saveMapping(@RequestBody MappingDTO mapping) {
.........
...........
......
HttpHeaders headers = new HttpHeaders();
headers.addHeader("X-Frame-Options", "DENY");
return new ResponseEntity<Boolean>(true, headers,
HttpStatus.OK);
}
}
或
如果您的应用程序中有spring安全性,请在安全配置文件中添加此安全性。因此,我们可以为每个请求响应全局禁用xframe选项
http.headers().frameOptions().disable();
或
HandlerInterceptor的PostHandle方法并不总是非常适合与@ResponseBody和ResponseEntity方法一起使用。在这种情况下,HttpMessageConverter在调用postHandle之前写入并提交响应,这使得无法更改响应,例如添加标头。相反,应用程序可以实现ResponseBodyAdvice并将其声明为@ControllerAdvice bean或直接在RequestMappingHandlerAdapter上配置它。
https://mtyurt.net/post/spring-modify-response-headers-after-processing.html
或
@gstackoverflow帖子所有者已找到解决方案。我们可以参考他的解决方案。