SpringBoot请求处理:前端请求参数与后端参数绑定原理源码以及自定义Converter

自定义pojo类与前端请求参数绑定源码解析

1、DispatcherServlet.class
找到能处理请求的Handler
在这里插入图片描述
为当前Handler 找一个适配器HandlerAdapter
在这里插入图片描述

找到适配器真正执行方法
在这里插入图片描述
2、AbstractHandlerMethodAdapter.class
找到执行方法
在这里插入图片描述
3、RequestMappingHandlerAdapter.class
真正来执行处理器的方法
在这里插入图片描述
SpringMVC目标方法能写多少种参数类型。取决于参数解析器。
在这里插入图片描述
参数解析器
在这里插入图片描述
返回值处理器
在这里插入图片描述

执行目标方法
在这里插入图片描述
4、ServletInvocableHandlerMethod.class
确定参数,真正执行目标方法的地方,有方法的返回值。
在这里插入图片描述
5、InvocableHandlerMethod.class
获取当前目标方法所有参数的属性值,然后在65行通过反射执行目标方法(也就是Controller方法)
在这里插入图片描述

挨个判断所有参数解析器哪个支持解析目标方法的参数
在这里插入图片描述

6、HandlerMethodArgumentResolverComposite.class
在这里插入图片描述
判断是否有满足条件的解析器
在这里插入图片描述
如果是自定义类型参数封装POJO会调用ServletModelAttributeMethodProcessor 这个参数处理器在这里插入图片描述

7、InvocableHandlerMethod.class
返回该处理器来到下面的处理环节
在这里插入图片描述
8、HandlerMethodArgumentResolverComposite.class
拿到能支持解析的参数解析器,然后调用resolveArgument方法进行解析
在这里插入图片描述

9、ModelAttributeMethodProcessor.class
创建实例,不同的解析器会进入到不同的class文件中
在这里插入图片描述
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
WebDataBinder :web数据绑定器,利用它里面的 Converters 将请求数据转成指定的数据类型。再次封装到JavaBean中
在这里插入图片描述
有124个转换器。从前端传来的数据经过http超文本协议想从文本类型转换为指定的数据类型需要使用到这些转换器
在这里插入图片描述
关键一步,把请求里的数据绑定 在这里插入图片描述
10、ServletModelAttributeMethodProcessor.class
把原生的数据调过来进行绑定
在这里插入图片描述
11、ServletRequestDataBinder.class
获取原生参数所有key-value对
在这里插入图片描述
准备进行绑定
在这里插入图片描述
12、WebDataBinder.class
在这里插入图片描述
13、DataBinder.class
应用属性
在这里插入图片描述
设置属性值
在这里插入图片描述
14、AbstractPropertyAccessor.class
遍历并且底层利用反射赋值
在这里插入图片描述
15、AbstractNestablePropertyAccessor.class
对反射属性和原生数据进行绑定
在这里插入图片描述
在这里插入图片描述
把原生数据的类型进行转换并绑定
在这里插入图片描述
去找转换器
在这里插入图片描述
16、TypeConverterDelegate.class
判断能不能进行转换
在这里插入图片描述
17、GenericConversionService.class
获取转换器
在这里插入图片描述
找它里面的所有converter那个可以将这个数据类型(request带来参数的字符串)转换到指定的类型
在这里插入图片描述
18、TypeConverterDelegate.class
判断为true时则进行转换
在这里插入图片描述
19、GenericConversionService.class
在这里插入图片描述
20、ConversionUtils.class
在这里插入图片描述
21、GenericConversionService.class
在这里插入图片描述

22、StringToNumberConverterFactory.class
未来我们可以给WebDataBinder里面放自己的Converter; private static final class StringToNumber<T extends Number> implements Converter<String, T>,
在这里插入图片描述

在这里插入图片描述
23、AbstractNestablePropertyAccessor.class
前端参数值转换完毕开始赋值
在这里插入图片描述

自定义Converter

原理:底层用了一个WebDataBinder数据绑定器,它会将请求参数的值绑定到指定JavaBean里面
1、自定义配置文件,把前端传来的值去掉“,”后一一对应绑定到JavaBean里面

@Component
public class MyConfig {

    @Bean
    public WebMvcConfigurer myWebMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addFormatters(FormatterRegistry registry) {
                registry.addConverter(new Converter<String, User>() {
                    @Override
                    public User convert(String source) {
                        if(!StringUtils.isNullOrEmpty(source)){
                            String[] split = source.split(",");
                            User user = new User();
                            user.setUserId(Integer.parseInt(split[0]));
                            user.setName(split[1]);
                            user.setBalance(Integer.parseInt(split[2]));
                            return user;
                        }
                        return null;
                    }
                });
            }
        };
    }
}

2、客服端发送post请求提交数据

<form action="/requestBook" method="post">
    <input name="bookId" value="1"/><br/>
    <input name="bookName" value="三体"/><br/>
    <input name="price" value="100"/><br/>
    <input name="stock" value="99"/><br/>
    <input name="user" value="2,张三,1000"/><br/>
    <input type="submit" value="save"/>
</form>

3、服务端接收数据自定义Converter处理并返回

@Controller
public class UserController {
    @Autowired
    private UserService userService;


    @ResponseBody
    @RequestMapping(value = "/requestBook", method = RequestMethod.POST)
    public Book requestBook(Book book){
        return book;
    }

    @ResponseBody
    @RequestMapping(value = "/responseData", method = RequestMethod.GET)
    public Book responseData(){
        Book book = new Book();
        book.setBookId(1);
        book.setBookName("三体");
        book.setPrice(100);
        book.setStock(10);
        return book;
    }
}

实现结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值