@InitBinder解析和@ModelAttribute参数注入分析

2023-11-15

当我们请求/hello时, 传参数u.username如何注入到user中的username?


样例

@Controller
public class HelloController {
   

   @RequestMapping("/hello")
   public String hello(@ModelAttribute("user")User user) {
   
      System.out.println(user);
      System.out.println(employee);
      return "hello";
   }

   @InitBinder("user")
   public void initUser(WebDataBinder binder) {
   
      binder.setFieldDefaultPrefix("u.");
   }
}

原理

目标调用方法为hello方法, User参数如何被注入进去的? 先从原理出发

  1. 通过反射的方式, 拿到hello方法的参数信息, 比如参数个数为1个, 参数类型为User等等
  2. 反射创建出User对象, 用内省的方式(反射)给对象填充属性
  3. 通过method.invoke(obj, args)调用到目标hello方法

流程

org.springframework.web.servlet.DispatcherServlet#doDispatch
关注ha.handle()方法, 处理器适配器的handle方法, 会对参数解析并注入, 后续再调用具体的方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   boolean multipartRequestParsed = false;

   WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

   try {
   
      ModelAndView mv = null;
      Exception dispatchException = null;

      try {
   
         processedRequest = checkMultipart(request);
         multipartRequestParsed = (processedRequest != request);

         // Determine handler for the current request.

         // HandlerMapping核心为getHandler方法, 获取该请求的调用执行链, 拦截器 + 具体处理的HandlerMethod
         mappedHandler = getHandler(processedRequest);
         if (mappedHandler == null) {
   
            noHandlerFound(processedRequest, response);
            return;
         }

         // Determine handler adapter for the current request.

         // mappedHandler.getHandler()获取的是HandlerMethod对象
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

         // Process last-modified header, if supported by the handler.
         String method = request.getMethod();
         boolean isGet = "GET".equals(method);
         if (isGet || "HEAD".equals(method)) {
   
            long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
            if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
   
               return;
            }
         }

         // 处理拦截器preHandle方法
         if (!mappedHandler.applyPreHandle(processedRequest, response)) {
   
            return;
         }

         // Actually invoke the handler.

         // 调用目标方法
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

         if (asyncManager.isConcurrentHandlingStarted()) {
   
            return;
         }

         applyDefaultViewName(processedRequest, mv);

         // 处理拦截器postHandle方法
         mappedHandler.applyPostHandle(processedRequest, response, mv);
      }
      catch (Exception ex) {
   
         dispatchException = ex;
      }
      catch (Throwable err) {
   
         // As of 4.3, we're processing Errors thrown from handler methods as well,
         // making them available for @ExceptionHandler methods and other scenarios.
         dispatchException = new NestedServletException("Handler dispatch failed", err);
      }
      processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
   }
   catch (Exception ex) {
   
      triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
   }
   catch (Throwable err) {
   
      triggerAfterCompletion(processedRequest, response, mappedHandler,
            new NestedServletException("Handler processing failed"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@InitBinder解析和@ModelAttribute参数注入分析 的相关文章

随机推荐

  • torch.max函数比较最大值

    新建两个tensor列表 利用torch max 进行两个列表的比较 import torch a torch tensor 1 2 3 4 5 print a a b torch tensor 10 1 7 9 3 print b b x
  • 认识HTTP请求

    要分析HTTP请求和响应必然少不了抓包工具 关于抓包工具的设置和下载推荐看抓包工具Fiddler的下载与设置 通过抓包得到的一个HTTP请求 HTTP请求的格式 结构分析 一 请求行 1 post是方法 可以表示一条HTTP请求要进行的操作
  • elementui的el-input校验正则表达式

    el input 只能输入正整数 包括0 在 Input 值改变时触发 handleEdit e let value e replace d g 只能输入数字 value value replace 0 d 1 第一位0开头 0后面为数字
  • 前后端分离之Springboot

    这里写目录标题 springboot后台搭建 1 创建父项目 1 1 创建netseal 2 创建子项目 2 1 创建webserver 2 2 创建common 3 正式编码 3 1 修改pom文件 3 1 1 netseal的pom x
  • 三色标记-垃圾收集器底层算法

    三色标记 文章目录 三色标记 前言 一 三色标记是什么 二 三色的介绍 1 黑色 2 灰色 3 白色 三 浮动垃圾 四 读写屏障 四 总结 前言 三色标记相信大家也有所耳闻 但是都没有过深入的了解 小编在之前和同事交流的过程中 了解到很多大
  • Struts2 入门案例——基于Struts2 任意两数据的代数和

    基于Struts2 任意两数据的代数和 问题 设计一个简单的 Web 程序 其功能是让用户输入两个整数 并提交给 Action 在 Action 中计算两个数的代数和 如果代数和为非负数 则跳转到 ch11 1 Positive jsp 页
  • vue项目中如何设置ico图标

    在vue项目开发中往往会设计到浏览器头部图标的设置 这里分享一下自己在项目中的使用的方法 如有不足的地方还望指正 直奔主题 1 首先如何制作ico图标 本人使用的是比特虫在线制作ico图标 使用方法很简单直接导入照片 输入生产码 点击生成i
  • springboot (2.0) 设置监听器,过滤器,拦截器

    springboot 2 0 设置监听器 过滤器 拦截器 github springboot2 0 项目名 springboot filter 1 项目结构和配置顺序 1 1配置顺序 listener WebListener声明为liste
  • 自己总结的数据库系统概论笔记,需要的拿去用

    1 绪论 1 1 概念 数据库系统包含 数据库 数据库管理系统 数据库管理员 应用系统 数据库 数据库是长期存储在计算机内 有组织的 可共享的大量数据的集合 数据库中的数据按照一定的数据模型 组织 描述和储存 具有较小的冗余度 较高的数据独
  • Angular --官方文档使用 Angular CLI创建项目

    1 在node环境下 标配 node v npm v 指令在命令窗口查看两个的版本号 node高于6 9 3 npm版本高于3 0 0 如果你是新安装的话 就不要考虑这个问题了 2 全局安装 Angular CLI npm install
  • Java线程池的使用(简单实现)

    一 线程池的概念 创建Java线程需要给线程分配堆栈内存以及初始化内存 还需要进行系统调用 频繁地创建和销毁线程会大大降低系统的运行效率 采用线程池来管理线程有以下好处 提升性能 线程池能独立负责线程的创建 维护和分配 线程管理 每个Jav
  • Navicat 连接Oracle时提示oracle library is not loaded的问题解决

    Navicat 连接Oracle时提示oracle library is not loaded的问题解决 笔者使用的Navicat Premium 12启动界面截屏 请注意是64位的 笔者win7 64位系统 连接Oracle时提示 ora
  • Eclipse报错-The selection cannot be launched,and there are no recent launches

    Eclipse报错 报错 The selection cannot be launched and there are no recent launches 怎么解决 解决办法 1 检查分号 2 检查main函数 3 检查main函数后面括
  • 【buildroot】buildroot使用总结

    文章目录 一 buildroot使用步骤 1 构建图形配置界面 2 配置Target options 3 配置Build options 4 配置Toolchain 5 配置 System configuration 6 配置 Filesy
  • 运用顺序表实现多项式相加

    本题要求输入两个一元多项式 然后输出它们的和 相加后得到的一元多项式 输入格式 输入一个整数n 表示输入组数 然后依次输入每一组数据 输入一个整数A 表示多项式的项数 小于100 然后输入A对整数 每一对整数表示对应项的指数和系数 输出格式
  • 通配符

    1 通配符 用来匹配文件名或目录 匹配文件内容用正则表达式 匹配任意一个字符 匹配0个或任意多个字符 也就是可以匹配任何内容 匹配括号中的任意一个字符 eg abc 匹配一个字符 或a 或b 或c 匹配括号中任意一个字符 代表一个范围 eg
  • 词向量的运算与Emoji生成器

    本文参考参考 没有对框架内容进行学习 旨在学习思路和方法 1 词向量运算 之前学习RNN和LSTM的时候 输入的语句都是一个向量 比如恐龙的名字那个例子就是将一个单词中的字母按顺序依次输入 这对于一个单词的预测是可行的 但是对于想让机器学习
  • Qt - MVC模型/视图编程

    MVC模型 视图编程 Qt中的模型 视图架构用来实现大量的数据存储 处理及显示 MVC Model View Controller 包括了3个组件 模型 Model 是应用对象 用来表示数据 视图 View 是模型的用户界面 用来显示数据
  • mac安装eclipse报错:Failed to create the Java Virtual Machine

    目录 1 报错场景 2 解决办法 1 查看本机安装的JAVA环境 2 修改info plsit文件 1 报错场景 macosx安装Eclipse的时候报错 Failed to create the Java Virtual Machine
  • @InitBinder解析和@ModelAttribute参数注入分析

    当我们请求 hello时 传参数u username如何注入到user中的username 样例 Controller public class HelloController RequestMapping hello public Str