1.返回值解析器介绍
返回值解析器用于解析Hanlder执行方法后的返回结果,例如将方法上标注有@ResponseBody注解的返回值解析成JSON、将方法返回的字符串作为视图名等
SpringMVC中默认的返回值解析器见RequestMappingHandlerAdapter#getDefaultReturnValueHandlers
private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);
handlers.add(new ModelAndViewMethodReturnValueHandler());
handlers.add(new ModelMethodProcessor());
handlers.add(new ViewMethodReturnValueHandler());
handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
handlers.add(new StreamingResponseBodyReturnValueHandler());
handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
handlers.add(new HttpHeadersReturnValueHandler());
handlers.add(new CallableMethodReturnValueHandler());
handlers.add(new DeferredResultMethodReturnValueHandler());
handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
handlers.add(new ModelAttributeMethodProcessor(false));
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
handlers.add(new ViewNameMethodReturnValueHandler());
handlers.add(new MapMethodProcessor());
// 添加自定义的返回值解析器
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// 兜底的解析器
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}
else {
handlers.add(new ModelAttributeMethodProcessor(true));
}
return handlers;
}
这些返回值解析器会被封装到HandlerMethodReturnValueHandlerComposite中,处理返回值时,会按照加入的顺序依次判断每个返回值解析器能否解析此任务,如果其中某个解析器能够解析此参数,则返回解析结果
2.自定义返回值解析器
在某些场景下,我们可以自定义返回值解析器,将响应的返回值转成我们希望的格式,假如我们想要将响应转换为yml格式,这时我们可以自定义注解,然后再自定义返回值解析器实现HandlerMethodReturnValueHandler接口,示例如下:
1)创建自定义注解@Yml及自定义返回值处理器YmlReturnResolver实现HandlerMethodReturnValueHandler接口
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Yml {
}
public class YmlReturnResolver implements HandlerMethodReturnValueHandler {
// 判断返回值解析器是否支持
@Override
public boolean supportsReturnType(MethodParameter methodParameter) {
Yml yml = methodParameter.getMethodAnnotation(Yml.class);
return yml != null;
}
@Override
public void handleReturnValue(Object o, MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest) throws Exception {
// 将返回值转换为yaml
String str = new Yaml().dump(o);
// 设置响应内容
HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(str);
// 设置请求已处理完毕
modelAndViewContainer.setRequestHandled(true);
}
}
2)配置类中加入自定义返回值解析器
@Configuration
@ComponentScan
public class WebConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet) {
DispatcherServletRegistrationBean dispatcherServletRegistrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/");
dispatcherServletRegistrationBean.setLoadOnStartup(1);
return dispatcherServletRegistrationBean;
}
@Bean
public MyRequestMappingHandlerAdapter requestMappingHandlerAdapter() {
MyRequestMappingHandlerAdapter handlerAdapter = new MyRequestMappingHandlerAdapter();
// 添加自定义返回值解析器
handlerAdapter.setCustomReturnValueHandlers(Arrays.asList(new YmlReturnResolver()));
return handlerAdapter;
}
}
3)创建控制器类及实体类
@Controller
public class Controller01 {
@GetMapping("/test")
@Yml
public User test() {