TLDR;有没有办法为Thymeleaf模板引擎的响应编写ResponseBodyAdvice?
对于带有@RequestMapping和@ResponseBody注释的“正常”端点,我可以编写ResponseBodyAdvice来修改/处理响应,然后再将其写入输出流。现在,有没有一种方法可以使端点返回模板视图的名称(在本例中为Thymeleaf)呢?
有效的示例:
@Controller
public class MyController
{
@GetMapping("/path")
@ResponseBody
public String dispatch(final HttpServletRequest request,
final HttpServletResponse response)
throws Exception
{
return "my output string...";
}
}
@ControllerAdvice
public class MyControllerAdvice implements ResponseBodyAdvice<String>
{
@Override
public boolean supports(final MethodParameter returnType,
final Class<? extends HttpMessageConverter<?>> converterType)
{
// This is called
return true;
}
@Override
public String beforeBodyWrite(final String body,
final MethodParameter returnType,
final MediaType selectedContentType,
final Class<? extends HttpMessageConverter<?>> selectedConverterType,
final ServerHttpRequest request,
final ServerHttpResponse response)
{
// This is called
// Perform the response logic...
return body;
}
}
无效的示例:
@Controller
public class MyController
{
@GetMapping("/path")
public String dispatch(final HttpServletRequest request,
final HttpServletResponse response)
throws Exception
{
return "viewName"; // will be resolved to a view by the templating engine (Thymeleaf) - typically viewName.html - and evaluated
}
}
@ControllerAdvice
public class MyControllerAdvice implements ResponseBodyAdvice<Object>
{
@Override
public boolean supports(final MethodParameter returnType,
final Class<? extends HttpMessageConverter<?>> converterType)
{
// This is never called
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)
{
// This is never called
// Perform the response logic...
return body;
}
}
很难判断上述控制器建议是否仅与模板引擎的输出不匹配,或者是否存在针对其选择的更具体类型的控制器建议...
关于, 亵渎
答案 0 :(得分:0)
您应该可以使用HandlerInterceptorAdapter
来做到这一点:
public class MyResponseInterceptor extends HandlerInterceptorAdapter
{
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView)
throws Exception
{
// Your logic here, which will be called after the controller method returns
}
}
您还需要将此类添加到您的WebMvcConfigurerAdapter
:
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(new MyResponseInterceptor());
}
请注意,这存在相反的问题,因为它不适用于直接返回ResponseBody
的Controller方法