说明
@RestControllerpublic class HelloController { @PostMapping("/sayFrom") public User sayFrom(User user) { return user; }}
上面代码定一个了一个接口,参数上User对象,参数值也是User对象,客户端请求如下:
上面的参数解析和返回值处理默认都是使用Spring内建的解析器和处理器处理的。
默认的内建处理器
参数解析:
上面可以看到,Spring内建的参数解析器有26个,根据具体的参数类型选择对应的解析器(根据supportsParameter方法进行判断),此时获取的对应的解析器为 ServletModelAttributeMethodProcessor ,参数解析如下:
具体解析过程,大家可以自行看下。
返回值处理:
从代码中可以看到返回值最终是使用内建的处理器 MappingJackson2HttpMessageConverter进行处理,而且返回的 Content-Type=applicationo/json.
所以,我们要自定义两个东西,一个参数解析器,一个返回值的处理器。
自定义参数解析器
public class MyHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { // 参数类型判断 return User.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // TODO do resolve // 这里参数解析暂时写死 return new User("李四"); }}
定义好解析器之后,要将自定义的解析器放到内建的解析器之前,具体代码如下:
@Configurationpublic class MyWebMvcConfigurer { @Autowired private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @PostConstruct public void init() { // 获取内建的resolvers List buildInList = requestMappingHandlerAdapter.getArgumentResolvers(); // 重建resolvers List newResolvers = new ArrayList<>(buildInList.size() + 1); // 自定义的放到第一位 newResolvers.add(new MyHandlerMethodArgumentResolver()); // 再放内建的 newResolvers.addAll(buildInList); // 重设resolvers requestMappingHandlerAdapter.setArgumentResolvers(newResolvers); }}
因为内建的解析器会在自定义的解析器之前调用,所以需要重新调整顺序。
启动服务观察接口调用情况:
上面执行结果中可以看出自定义解析器已经生效了,下面我们看下返回值如何处理的。
自定义返回值处理器
public class MyHttpMessageConverter extends AbstractGenericHttpMessageConverter { @Override public boolean canWrite(Type type, Class> clazz, MediaType mediaType) { // 判断支持处理哪些类型 return User.class.isAssignableFrom(clazz); } @Override protected void writeInternal(User user, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { // 测试 user = new User("王五"); // 这里参照 MappingJackson2HttpMessageConverter ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); JsonGenerator generator = objectMapper.getFactory().createGenerator(outputMessage.getBody(), JsonEncoding.UTF8); ObjectWriter objectWriter = objectMapper.writer(); objectWriter.writeValue(generator, user); generator.flush(); }}
添加我们自定义的处理器
@Configurationpublic class MyWebMvcConfigurer implements WebMvcConfigurer { @Override public void extendMessageConverters(List> converters) { // 添加自定义处理器,且放到首位 converters.add(0, new MyHttpMessageConverter()); } ...}
启动服务观察执行结果:
从结果中可以看出我们自定义的返回值处理器已经生效了。