赞
踩
准备对象
@Data
static class User {
private String name;
private int age;
@JsonCreator // 默认jackson会使用无参构造器反序列化 这里强制使用当前带参构造器
public User(@JsonProperty("name") String name, @JsonProperty("age") int age) {
this.name = name;
this.age = age;
}
}
@SneakyThrows
private static void test1() {
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
if (converter.canWrite(User.class, MediaType.APPLICATION_JSON)) {
converter.write(new User("张三", 30), MediaType.APPLICATION_JSON, outputMessage);
System.out.println("outputMessage.getBodyAsString() = " + outputMessage.getBodyAsString());
}
}
@SneakyThrows
private static void test2() {
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
if (converter.canWrite(User.class, MediaType.APPLICATION_XML)) {
converter.write(new User("张三", 30), MediaType.APPLICATION_XML, outputMessage);
System.out.println("outputMessage.getBodyAsString() = " + outputMessage.getBodyAsString());
}
}
@ResponseBody // @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) public User user() { return null; } @SneakyThrows public static void test4() { // 模拟请求 MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); ServletWebRequest servletWebRequest = new ServletWebRequest(request, response); // 配置请求头 以及 响应类型 request.addHeader("Accept", "application/xml"); response.setContentType("application/json"); // 设置ResponseBody处理的类型转换器 RequestResponseBodyMethodProcessor requestResponseBodyMethodProcessor = new RequestResponseBodyMethodProcessor( CollUtil.newArrayList( new MappingJackson2HttpMessageConverter(), new MappingJackson2XmlHttpMessageConverter() ) ); requestResponseBodyMethodProcessor.handleReturnValue( new User("张三", 30), new MethodParameter(TestMessageConverter.class.getMethod("user"), -1), new ModelAndViewContainer(), servletWebRequest ); System.out.println(new String(response.getContentAsByteArray(), StandardCharsets.UTF_8)); }
@ResponseBody 是由返回值类型处理器完成解析的,具体转换工作有消息转换器完成 MappingJackson2HttpMessageConverter
具体转换为json还是xml?
@SneakyThrows
public static void test3() {
MockHttpInputMessage inputMessage = new MockHttpInputMessage("{\"name\":\"张三\", \"age\": 30}".getBytes(StandardCharsets.UTF_8));
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
if (converter.canRead(User.class, MediaType.APPLICATION_JSON)) {
User readUser = (User) converter.read(User.class, inputMessage);
System.out.println(readUser);
}
}
准备对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class User {
private String name;
private int age;
}
准备控制器与ControllerAdvice
@Controller public static class MyController { @ResponseBody public User user() { return new User("王五", 30); } } @ControllerAdvice public static class MyControllerAdvice implements ResponseBodyAdvice<Object> { // 满足条件才转换 @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return true; } // 将返回对象转换为统一格式 @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (body instanceof JsonResponse) { return body; } return JsonResponse.ok(body); } }
// 1. 准备容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(WebConfig.class); // 2. 准备请求 MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); ServletWebRequest servletWebRequest = new ServletWebRequest(request, response); // 3. 准备servletInvocableHandlerMethod ServletInvocableHandlerMethod servletInvocableHandlerMethod = new ServletInvocableHandlerMethod( applicationContext.getBean(WebConfig.MyController.class), WebConfig.MyController.class.getDeclaredMethod("user")); // 这里没有特殊参数绑定 入参传null ServletRequestDataBinderFactory servletRequestDataBinderFactory = new ServletRequestDataBinderFactory(Collections.emptyList(), null); servletInvocableHandlerMethod.setDataBinderFactory(servletRequestDataBinderFactory); servletInvocableHandlerMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer()); servletInvocableHandlerMethod.setHandlerMethodArgumentResolvers(argumentResolverComposite(applicationContext)); servletInvocableHandlerMethod.setHandlerMethodReturnValueHandlers(returnValueHandlerComposite(applicationContext)); // 4. 准备ModelAndViewContainer容器 ModelAndViewContainer modelAndViewContainer = new ModelAndViewContainer(); // 5. 方法执行 servletInvocableHandlerMethod.invokeAndHandle( servletWebRequest, modelAndViewContainer); System.out.println(new String(response.getContentAsByteArray(), StandardCharsets.UTF_8)); // 6. 关闭容器 applicationContext.close();
参数解析器与之前一致,主要是返回值处理器中的RequestResponseBodyMethodProcessor添加自定义ControllerAdvice
private static HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite(ApplicationContext applicationContext) { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); HandlerMethodReturnValueHandlerComposite returnValueHandlerComposite = new HandlerMethodReturnValueHandlerComposite(); returnValueHandlerComposite.addHandlers(CollUtil.newArrayList( // 返回值:ModelAndView new ModelAndViewMethodReturnValueHandler(), // 返回值字符串:视图名 new ViewNameMethodReturnValueHandler(), // 返回模型数据 带@ModelAttribute注解 new ServletModelAttributeMethodProcessor(false), // 返回值:HttpEntity new HttpEntityMethodProcessor(CollUtil.newArrayList(jackson2HttpMessageConverter)), // 返回值:HttpHeaders new HttpHeadersReturnValueHandler(), // 返回值json: 带@ResponseBody注解 添加自定义ControllerAdvice new RequestResponseBodyMethodProcessor(CollUtil.newArrayList(jackson2HttpMessageConverter), CollUtil.newArrayList(applicationContext.getBean(WebConfig.MyControllerAdvice.class))), // 返回模型数据 不带@ModelAttribute注解 new ServletModelAttributeMethodProcessor(true) )); return returnValueHandlerComposite; }
关键代码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。