Spring Boot 2.x实战41-SpringWebMVC13-WebMVC配置(控制器方法参数和返回值处理设置-AbstractMessageConverterMethodProcessor)

3.6.2 示例2
我们再模仿@RequestBody和@ResponseBody的实现原理做一个简单的示例。
请求体注解:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestPerson {
}
1
2
3
4
5
返回体注解:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponsePerson {
}
1
2
3
4
5
针对Person的请求和返回处理器:

public class RequestResponsePersonMethodProcessor extends AbstractMessageConverterMethodProcessor {

    public RequestResponsePersonMethodProcessor(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }
    
    @Override //HandlerMethodArgumentResolver的重载方法
    public boolean supportsParameter(MethodParameter parameter) { 
        return  parameter.hasMethodAnnotation(ResponsePerson.class) &&
                parameter.getParameterType().equals(AnotherPerson.class); //1
    }

    @Override //HandlerMethodArgumentResolver的重载方法
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Object object = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
        return object; //2
    }

    @Override //HandlerMethodReturnValueHandler的重载方法
    public boolean supportsReturnType(MethodParameter returnType) {
        return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponsePerson.class) ||
                returnType.hasMethodAnnotation(ResponsePerson.class)) &&
                returnType.getParameterType().equals(AnotherPerson.class); //3
    }

    @Override //HandlerMethodReturnValueHandler的重载方法
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        AnotherPerson person = (Person) returnValue;
        person.setName(person.getName().toUpperCase());
        writeWithMessageConverters(person, returnType, webRequest); //4
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
参数只有注解了@RequestPerson且类型为AnotherPerson时有效;
使用HttpMessageConverter将请求体内的数据(6-foo-28)转换成AnotherPerson类,readWithMessageConverters方法使用匹配的HttpMessageConverter将请求体重的内容转换为Java对象,它是AbstractMessageConverterMethodProcessor的父类AbstractMessageConverterMethodArgumentResolver的方法;
只有方法返回上注解了@ResponsePerson且返回值类型为AnotherPerson时有效;
使用HttpMessageConverter将对象转换成数据展示给客户端,writeWithMessageConverters方法使用匹配的HttpMessageConverter将对象转成对应的数据类型,它同样是AbstractMessageConverterMethodArgumentResolver的方法。
我们通过自定义方法参数返回值处理器,同样也了解了HttpMessageConverter工作原理。下面我们注册这个处理器,这个处理器分成两个部分:HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler,我们要分别重载WebMvcConfigurer接口的addArgumentResolvers和addReturnValueHandlers方法:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    @Bean
    HttpMessageConverters httpMessageConverters(){
        return new HttpMessageConverters(new AnotherPersonHttpMessageConverter());
    }

    @Bean
    RequestResponsePersonMethodProcessor requestResponsePersonMethodProcessor(){
        return new RequestResponsePersonMethodProcessor(httpMessageConverters().getConverters()); 
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(requestResponsePersonMethodProcessor());
    }

    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        handlers.add(requestResponsePersonMethodProcessor());
    }


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
我们使用前面例子定义的AnotherPersonHttpMessageConverter来作为本例的演示所用的HttpMessageConverter,RequestResponsePersonMethodProcessor所需的converters可从HttpMessageConverters的Bean中获得。

本例使用的@ResponsePerson注解方法返回值,而@RestController的控制器方法默认每个方法都注解了@ResponseBody会让@ResponsePerson失效,所以我们在DemoController控制器进行检验:

@Controller
@RequestMapping("/demo")
public class DemoController {
    @GetMapping("/argument")
    @ResponsePerson
    public AnotherPerson argument(@RequestPerson AnotherPerson person){
        return person;
    }
}
1
2
3
4
5
6
7
8
9
为了使AnotherPersonHttpMessageConverter生效,我们的需设置请求头信息:

我们能使用AnotherPersonHttpMessageConverter正确解析请求体的内容,也能正确的生成返回体,我们的方法返回值处理器还额外将name改成了大写:


新书推荐:
我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html


主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值