当前位置: 首页 > news >正文

【SpringBoot】16 核心功能 - Web开发原理 - 请求参数 - 源码分析

文章目录

    • 一、普通参数与基本注解
      • 1.1 常用注解
      • 1.2 Servlet API参数
      • 1.3 复杂参数
      • 1.4 自定义对象参数
    • 二、请求参数处理源码分析
      • 参数解析过程
    • 三、自定义参数绑定
    • 四、自定义参数绑定原理
      • 1、核心机制:Web数据绑定
      • 2、自定义转换:原理与实现
      • 3、核心关系图
      • 小结
    • 总结


一、普通参数与基本注解

在SpringBoot的Web开发中,处理请求参数是最基础且常见的操作。SpringMVC提供了丰富的注解和机制来帮助我们方便地获取请求中的各类参数。

1.1 常用注解

  • @PathVariable:用于获取URL路径中的变量值。
  • @RequestHeader:用于获取HTTP请求头信息。
  • @ModelAttribute:用于将请求参数绑定到模型对象。
  • @RequestParam:用于获取HTTP请求参数。
  • @MatrixVariable:用于获取URL中的矩阵变量。
  • @CookieValue:用于获取Cookie值。
  • @RequestBody:用于获取HTTP请求体内容,通常用于接收JSON或XML数据。

以下是一个使用多种注解的控制器方法示例:

@RestController
public class ParameterTestController {@GetMapping("/car/{id}/owner/{username}")public Map<String, Object> getCar(@PathVariable("id") Integer id,@PathVariable("username") String name,@PathVariable Map<String, String> pv,@RequestHeader("User-Agent") String userAgent,@RequestHeader Map<String, String> header,@RequestParam("age") Integer age,@RequestParam("interests") List<String> interests,@RequestParam Map<String, String> params,@CookieValue("_ga") String _ga,@CookieValue("_ga") Cookie cookie) {Map<String, Object> map = new HashMap<>();map.put("id", id);map.put("name", name);map.put("pv", pv);map.put("userAgent", userAgent);map.put("header", header);map.put("age", age);map.put("interests", interests);map.put("params", params);map.put("_ga", _ga);map.put("cookie", cookie);return map;}
}

1.2 Servlet API参数

SpringMVC支持在控制器方法中直接使用Servlet API中的对象作为参数,例如:

  • WebRequest
  • ServletRequest
  • MultipartRequest
  • HttpSession
  • javax.servlet.http.PushBuilder
  • Principal
  • InputStream
  • Reader
  • HttpMethod
  • Locale
  • TimeZone
  • ZoneId

1.3 复杂参数

除了基本参数类型,SpringMVC还支持一些复杂参数类型:

  • Map
  • Model(Map和Model中的数据会被放在request的请求域中,相当于调用request.setAttribute)
  • Errors/BindingResult
  • RedirectAttributes(用于重定向时携带数据)
  • ServletResponse(response对象)
  • SessionStatus
  • UriComponentsBuilder
  • ServletUriComponentsBuilder

1.4 自定义对象参数

SpringMVC支持将请求参数自动绑定到自定义对象,包括自动类型转换与格式化,以及级联封装(即对象中包含其他对象的情况)。

二、请求参数处理源码分析

SpringMVC通过HandlerAdapter组件来处理控制器方法的参数解析和调用。在SpringBoot中,默认配置了多个HandlerAdapter:

  • RequestMappingHandlerAdapter:支持方法上标注@RequestMapping注解的处理器
  • HandlerFunctionAdapter:支持函数式编程的处理器
  • HttpRequestHandlerAdapter:支持HttpRequestHandler接口的处理器
  • SimpleControllerHandlerAdapter:支持Controller接口的处理器

其中,RequestMappingHandlerAdapter是最常用的,它负责解析控制器方法中的各种参数注解。

参数解析过程

当请求到达DispatcherServlet时,它会找到匹配的处理器,然后通过合适的HandlerAdapter来调用处理器方法。参数解析的核心是HandlerMethodArgumentResolver接口,SpringMVC提供了多个实现类来处理不同类型的参数:

  • PathVariableMethodArgumentResolver:处理@PathVariable注解
  • RequestHeaderMethodArgumentResolver:处理@RequestHeader注解
  • RequestParamMethodArgumentResolver:处理@RequestParam注解
  • ServletCookieValueMethodArgumentResolver:处理@CookieValue注解
  • RequestResponseBodyMethodProcessor:处理@RequestBody注解和@ResponseBody注解

以下是一个展示请求域参数传递的示例:

@Controller
public class RequestController {// 取出请求域中的参数值的方法,并将请求参数传入到下一个请求@GetMapping("goto")public String goToPage(HttpServletRequest request) {request.setAttribute("msg", "这是从controller传入的参数");request.setAttribute("code", 200);return "forward:/success"; // 转发到/success请求}@GetMapping("/params")public String testParam(Map<String, Object> map,Model model,HttpServletRequest request,HttpServletResponse response) {map.put("hello", "world666");model.addAttribute("world", "hello666");request.setAttribute("message", "HelloWorld");Cookie cookie = new Cookie("c1", "v1");cookie.setDomain("localhost");response.addCookie(cookie);return "forward:/success";}@ResponseBody@GetMapping("/success")public Map success(@RequestAttribute(value = "msg", required = false) String msg,@RequestAttribute(value = "code", required = false) Integer code,HttpServletRequest request) {Object msg1 = request.getAttribute("msg");Object code1 = request.getAttribute("code");Object hello = request.getAttribute("hello");Object world = request.getAttribute("world");Object message = request.getAttribute("message");Map<String, Object> map = new HashMap<>();map.put("reqMethod_msg", msg1); // 使用请求域中的参数map.put("annotation_msg", msg); // 使用参数注解传入的参数map.put("hello", hello);map.put("world", world);map.put("message", message);return map;}
}

在这个示例中,我们展示了如何通过HttpServletRequest设置请求域属性,以及如何通过@RequestAttribute注解或HttpServletRequest对象获取这些属性。当使用"forward"转发时,请求域中的属性会被保留到下一个请求中。

运行结果

在这里插入图片描述

我们来看一下cookie的值
在这里插入图片描述

三、自定义参数绑定

在这里插入图片描述
Person类

package com.web.bean;import lombok.Data;import java.util.Date;/*** @author cc* @date 2020/11/23-16:09*/
@Data
public class Person {private String userName;private Integer age;private Date birth;private Pet pet;
}

宠物类

package com.web.bean;import lombok.Data;@Data
public class Pet {private String name;private Integer age;
}

控制器接口方法

@RestController
public class ParameterTestController {@PostMapping("/saveuser")public Person saveUser(Person person){return person;}

在这里插入图片描述
点击提交按钮

在这里插入图片描述

四、自定义参数绑定原理

1、核心机制:Web数据绑定

1. 核心组件:WebDataBinder

  • 功能:作为数据绑定的核心处理器,负责将HTTP请求参数(通常是字符串形式)的值绑定到目标JavaBean的对应属性上。
  • 工作流程
    1. 接收请求参数(String类型)。
    2. 利用内置的转换服务(ConversionService) 和其管理的转换器(Converters),将字符串数据转换为目标属性所需的复杂数据类型(如IntegerDateFile或自定义对象)。
    3. 将转换后的数据填充(封装)到JavaBean中。

2. 基础架构:通用转换服务(GenericConversionService)

  • 角色:是类型转换系统的容器和调度中心。它是一个配置一次即可全局使用的服务。
  • 管理:内部维护了一个转换器(Converter)集合。这个集合包含了Spring默认提供的众多转换器(用于处理基本类型、集合等)以及开发者注册的自定义转换器。
  • 职责:当需要进行类型转换时,GenericConversionService会负责查找并调用合适的Converter来执行实际的转换工作。

2、自定义转换:原理与实现

1. 目的
解决框架默认转换能力不足的问题。当Spring无法自动将请求参数(String)转换为特定的、复杂的或自定义的目标类型时,就需要开发者介入,提供明确的转换规则。

2. 核心技术:Converter<S, T> 接口

  • 定义:一个函数式接口,是类型转换策略的抽象。
  • 泛型参数
    • S (Source):源类型,即需要被转换的数据类型(在Web场景中通常是String)。
    • T (Target):目标类型,即希望转换成的数据类型。
  • 核心方法T convert(S source)
    • 开发者需要实现此方法,编写具体的转换逻辑,例如解析字符串、构造对象、设置属性等。

3. 实现步骤

  1. 创建转换器:定义一个类,实现Converter<S, T>接口,并在convert方法中完成从String到目标对象(如PersonOrder等)的转换逻辑。
  2. 注册转换器:将自定义的Converter实例添加到Spring的ConversionService中,使其生效。
    • 配置方式:可以通过Java配置类(使用@Bean注解)或XML配置文件进行注册。
  3. 自动应用:注册成功后,当Spring MVC在处理数据绑定遇到相应类型的转换时,会自动调用这个自定义的Converter,无需在控制器中编写额外的解析代码。

3、核心关系图

HTTP Request (带有String参数)|v
[WebDataBinder]  // 协调绑定过程|| 需要转换类型时调用v
[GenericConversionService]  // 转换服务管理中心|| 查找并委托给匹配的v
[Converter<S, T>]  // 执行实际转换工作的组件(内置的或自定义的)|v
目标类型的对象 (e.g., Integer, Date, CustomJavaBean)|v
填充到目标JavaBean中

小结

Spring通过 WebDataBinderGenericConversionService 构成了一套强大且可扩展的数据绑定与类型转换体系。其默认实现已经覆盖了大部分常见场景。对于特殊需求,开发者可以通过实现 Converter<S, T> 接口来定义精确的转换规则,并通过注册将其融入框架原有的转换流程中。这种设计既保证了开箱即用的便利性,又提供了高度的灵活性,是Spring MVC处理复杂Web参数绑定的关键机制。

总结

SpringBoot通过SpringMVC提供了完整且强大的Web请求参数处理机制,其核心在于灵活的参数绑定和类型转换体系。

在基础层面,框架提供了丰富的注解支持,包括@PathVariable、@RequestParam、@RequestHeader等,能够方便地提取URL路径、查询参数、请求头等各类信息。同时支持直接使用Servlet API对象和Map、Model等复杂参数类型,满足不同场景的需求。

参数处理的核心由HandlerAdapter组件实现,特别是RequestMappingHandlerAdapter负责解析方法参数。其内部通过HandlerMethodArgumentResolver策略接口,使用不同的解析器实现类来处理各类注解和参数类型。

对于自定义对象绑定,Spring提供了WebDataBinder和GenericConversionService组成的类型转换体系。WebDataBinder负责协调整个绑定过程,而GenericConversionService作为转换器容器,管理着包括默认转换器和自定义转换器在内的转换器集合。当默认转换能力不足时,开发者可以通过实现Converter<S, T>接口来定义特定类型的转换规则,并通过注册到转换服务中融入框架原有的转换流程。

这种分层设计使得SpringBoot既能提供开箱即用的便利性,又能通过扩展机制满足各种复杂的数据绑定需求,体现了框架的高度灵活性和可扩展性。

http://www.dtcms.com/a/342530.html

相关文章:

  • WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析七
  • 如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
  • CTFshow系列——命令执行web41-44
  • YOLOv8 原理与跨领域应用全景分析
  • CVPR | 2025 | MAP:通过掩码自回归预训练释放混合 Mamba - Transformer 视觉骨干网络的潜力
  • 【C++】仿函数和回调函数
  • Python数值取整完全指南:从基础到金融工程实践
  • uniapp实现分页,效果如图
  • 自然语言处理——04 注意力机制
  • npm全局安装后,cmd命令行可以访问,vscode访问报错
  • HTTP 403 错误:后端权限校验机制深度解析
  • 长尾关键词优化SEO核心策略
  • JeeSite 快速开发平台:全能企业级快速开发解决方案
  • 自己动手,在Mac开发机上利用ollama部署一款轻量级的大模型Phi-3:mini
  • ElasticSearch——常用命令
  • VSCode Import Cost:5 分钟学会依赖瘦身
  • java16学习笔记
  • uniapp 全局弹窗
  • 力扣1005:k次取反后最大化的数组和
  • pycharm编译器如何快速掌握一个新模块的使用方法
  • K-means 聚类算法学习
  • matplotlib 6 - Gallery Images
  • 在 Linux 中全局搜索 Word 文档内容的完整指南
  • 从零搭建Kubernetes集群:常见踩坑与解决方案
  • Django中的MVC和MVT模式
  • Unity接入DeepSeek实现AI对话功能
  • 解析火语言 RPA 核心功能:让流程自动化更高效​
  • leetcode 76 最小覆盖子串
  • 有关spring-ai的defaultSystem与systemMessage优先级
  • AI 发展的伦理困局:在创新与规范间寻找平衡