spring自定义pojo参数映射原理

自定义pojo参数映射原理

HttpServlet接口

  1. 由spring实现FrameworkServlet get/post -> doService

  2. 衍生到子类DispatcherServlet实现

  3. doDispatcher来分配并执行方法,getHandler(processedRequest)获取合适的handlerExecutionChain来执行请求

  4. 找到HandlerAdapter来屏蔽方法名不同带来的差距,最终找到RequestMappingHandlerAdapter

  5. 判断是否要执行前置通知preHandler处理方法

  6. 执行目标方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

  7. RequestMappingHandlerAdapter的invokeHandlerMethod方法下的invocableMethod.invokeAndHandle(webRequest, mavContainer);

  8. 开始执行时第一步就是获取参数InvocableHandlerMethod#invokeForRequest方法中getMethodArgumentValues(request, mavContainer, providedArgs);获取请求参数

  9. 通过初始化时就注入的参数解析器HandlerMethodArgumentResolver来遍历寻找合适的参数解析器解析参数

  10. 找到ServletModelAttributeMethodProcessor 来处理并放入缓存ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>

    该解析器是ModelAttributeMethodProcessor的字类

  11. ModelAttributeMethodProcessor#resolveArgument解析参数

  12. 使用WebDataBinder来绑定参数到指定pojo

HandlerExecutionChain

由Handler对象及Handler拦截器构成的Handler执行链,由HandlerMappinggetHandler方法返回获取

HandlerMapping

Interface to be implemented by objects that define a mapping between requests and handler objects.

一个定义请求与处理器对象映射的将被实现的接口

HandlerAdapter

MVC framework SPI, allowing parameterization of the core MVC workflow

支持核心MVC工作流参数化的MVC框架SPI

java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。这有点类似IOC的思想,将装配的控制权移到了程序之外。

ModelAttributeMethodProcessor

Resolve {@code @ModelAttribute} annotated method arguments and handle return values from {@code @ModelAttribute} annotated methods.

处理被@ModelAttribute注解标注的方法看书映射

ServletModelAttributeMethodProcessor

A Servlet-specific {@link ModelAttributeMethodProcessor} that applies data binding through a WebDataBinder of type {@link ServletRequestDataBinder}.

一个通过WebDataBinder来绑定参数的特定处理器与父类相比,并没有在参数上添加相关注解

GenericConversionService

Base {@link ConversionService} implementation suitable for use in most environments.

基础参数转换类

提交时input框的name通过级联属性来触发映射到内部的pojo中例如pet.name

静态资源位置暂定resource/resource优先于resource/static

自定义参数转换格式

WebMvcConfigurer

自定义mvc配置器

addFormatters

Add {@link Converter Converters} and {@link Formatter Formatters} in addition to the ones registered by default.

向容器中添加自定义WebMvcConfigurer 通过重写addFormatters方法来自定义参数转换规则

多参数模板lambda表达式写法:

registry.addConverter((Converter<String, Pet>)(s) ->{
                    if (!StringUtils.isEmpty(s)){
                        Pet pet = new Pet();
                        String[] split = s.split(",");
                        pet.setName(split[0]);
                        pet.setAge(Integer.parseInt(split[1]));
                        return pet;
                    }
                    return null;
                });

出错

java.lang.IllegalArgumentException: Unable to determine source type and target type for your Converter

lambda表达式实际会被转为一个由static标注的私有方法进而产生合适的类,该方法是声明类的一部分,spring无法检索/访问

所以可通过

Converter<String, Pet> myConverter = source -> {
                    if (!StringUtils.isEmpty(source)) {
                        Pet pet = new Pet();
                        String[] split = source.split(",");
                        pet.setName(split[0]);
                        pet.setAge(Integer.parseInt(split[1]));
                        return pet;
                    }
                    return null;
                };
                registry.addConverter(myConverter);

这种方法来解决,解决失败。

注入实现类还是直接实现而不是lambda表达式为好

解决

registry.addConverter(new Converter<String, Pet>() {
                    @Override
                    public Pet convert(String source) {
                        if (!StringUtils.isEmpty(source)) {
                            Pet pet = new Pet();
                            String[] split = source.split(",");
                            pet.setName(split[0]);
                            pet.setAge(Integer.parseInt(split[1]));
                            return pet;
                        }
                        return null;
                    }
                });

在解析时将自定义converter也注入了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值