123.【SpringBoot 源码刨析B】(六)

简介: 123.【SpringBoot 源码刨析B】

假如页面报404,主要原因是因为我们在使用矩阵注解的时候,没有使用@PathVablied注解获取路径所以报404的错误。分号的前面是路径。分号前面的路径一定要使用@PathVabiled()

java

package com.jsxs.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Author Jsxs
 * @Date 2023/7/3 16:14
 * @PackageName:com.jsxs.controller
 * @ClassName: ParamterTestController
 * @Description: TODO
 * @Version 1.0
 */
@Controller
@ResponseBody
public class ParameterTestController {
    //      6. @MatrixVariable
    // /car/{path;low=10,brand=byd}
    // 面试题: cookie被静用了,session里面存放的值怎么获取?
    // 正常流程: session->(生成)sessionID(会保存在cookie中)->cookie(需要携带SessionID)才能进行获取具体session
    // cookie被禁用怎么处理?: url重写,使用矩阵变量进行传递(把Session的值使用矩阵变量的方式进行传递)
    // /cars/sell;low=34;brand=byd,audi,yd
    // 我们访问的时候发现页面报400 请求异常的错误,主要原因是SpringBoot禁用了矩阵变量
    // 我们需要手动的进行开启 : 原理对路径的处理都是 WebMvcAutoConfiguration类下 -> configurePathMatch()方法体中 -> UrlPathHelper类中 -> removeSemicolonContent属性默认为(true)
    // 1.成功配置开启之后,我们访问的页面是404.因为我们矩阵变量有格式
    @GetMapping("/cars/{path}")
    public Map<String, Object> carsSell(@MatrixVariable("low") Integer low,
                                        @MatrixVariable("brand") List<String> brand,
                                        @MatrixVariable Map<String, String> mv,
                                        @PathVariable("path") String path
    ) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("low", low);
        map.put("brand", brand);
        map.put("path", path);
        map.put("mv", mv);
        return map;
    }
  // 非紧密性矩阵, ;之前的路径一定要使用Rest 风格
    @GetMapping("/cars/{path}/{a}")
    public Map<String, Object> carsSell2(@MatrixVariable("low") Integer low,
                                        @MatrixVariable("brand") List<String> brand,
                                        @MatrixVariable Map<String, String> mv,
                                        @PathVariable("path") String path,
                                        @PathVariable("a") String a
    ) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("low", low);
        map.put("brand", brand);
        map.put("path_1", path);
        map.put("path_2", a);
        map.put("mv", mv);
        return map;
    }
    //      7. 紧密型矩阵 : 查询是1号的且年龄等于20的老板手下员工2号且员工年龄是10岁的
    // /boss/1;age=20/2;age=10
    @GetMapping("/boss/{bossID}/{empID}")
    public Map<String, Object> Boss(
            @MatrixVariable(value = "age", pathVar = "bossID") Integer BossAge,
            @MatrixVariable(value = "age", pathVar = "empID") Integer empAge,
            @PathVariable("bossID") String path_bossID,
            @PathVariable("empID") String path_empID,
            @MatrixVariable Map<String, String> mv
    ) {
        Map<String, Object> map = new HashMap<>();
        map.put("path_boss_id",path_bossID);
        map.put("path_emp_id",path_empID);
        map.put("boss_age",BossAge);
        map.put("empAge",empAge);
        map.put("mv",mv);
        return map;
    }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <a href="http://localhost:8080/cars/sell;low=34;brand=byd,bmw,mi">@MatrixVariable注解 (数组不分开)</a>
</ul>
<ul>
    <a href="http://localhost:8080/cars/sell;low=34;brand=byd;bmw;mi">@MatrixVariable注解 (数组分开)</a>
</ul>
<ul>
    <a href="http://localhost:8080/cars/sell/a;low=34;brand=byd;bmw;mi">@MatrixVariable注解 (非紧密双矩阵)</a>
</ul>
<ul>
    <a href="http://localhost:8080/boss/1;age=20/2;age=10">@MatrixVariable注解 (紧密双矩阵)</a>
</ul>
</body>
</html>

(1.2)、Servlet API

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

ServletRequestMethodArgumentResolver 以上的部分参数

@Override
  public boolean supportsParameter(MethodParameter parameter) {
    Class<?> paramType = parameter.getParameterType();
    return (WebRequest.class.isAssignableFrom(paramType) ||
        ServletRequest.class.isAssignableFrom(paramType) ||
        MultipartRequest.class.isAssignableFrom(paramType) ||
        HttpSession.class.isAssignableFrom(paramType) ||
        (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
        Principal.class.isAssignableFrom(paramType) ||
        InputStream.class.isAssignableFrom(paramType) ||
        Reader.class.isAssignableFrom(paramType) ||
        HttpMethod.class == paramType ||
        Locale.class == paramType ||
        TimeZone.class == paramType ||
        ZoneId.class == paramType);
  }
(1.5)、自定义对象参数

可以自动类型转换与格式化,可以级联封装。

(3).POJO封装过程

我们自定义的类在SpringMVC中是由下面的类进行封装的

  • ServletModelAttributeMethodProcessor 类进行封装的

这里我们使用级联数据绑定 pet.name 这个就叫级联

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/saveuser" method="post">
    姓名: <input name="userName" value="jsxs">
    年龄: <input name="age" value="18">
    生日: <input name="birth" value="2019/12/17">
    宠物姓名: <input name="pet.name" value="阿猫">
    宠物年龄: <input name="pet.age" value="5">
    <input type="submit" value="保存">
</form>
</body>
</html>
package com.jsxs.bean;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Data;
import java.util.Date;
/**
 * @Author Jsxs
 * @Date 2023/7/5 11:39
 * @PackageName:com.jsxs.bean
 * @ClassName: Person
 * @Description: TODO
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String userName;
    private Integer age;
    private Date birth;
    private Pet pet;
}
package com.jsxs.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @Author Jsxs
 * @Date 2023/7/5 11:40
 * @PackageName:com.jsxs.bean
 * @ClassName: Pet
 * @Description: TODO
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Pet {
    private String name;
    private String age;
}
//  数据绑定: 页面提交的请求数据(GET、POST)都可以和对象属性进行绑定
    @PostMapping("/saveuser")
    // 我们的想法是: 因为传递过来的都是实体类的数据
    public Person saveUser(Person person,@RequestBody String content){
        return person;
    }

结果我们发现我们提交的数据不仅进行了自动类型转换,而且还赋值了数据。

(1.4)、复杂参数

Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

  1. Map和Model (会转储到HttpRequest中)

假如说我们在方法种放的参数是: Map类型和Model类型。那么Map和Model中添加的值相当于(HttpRequest)request.setAttribute()中放置数据。

我们在传地方设置两个参数Map和Model类型,转发到

// 接受方
    @ResponseBody
    @GetMapping("/success")
    public Map<String, Object> SuccessPage(HttpServletRequest httpServletRequest,
                                           @RequestAttribute(name = "msg",required = false) String name,
                                           HttpServletRequest request
    ) {
        Object hello = request.getAttribute("hello");
        Object world = request.getAttribute("world");
        Object message = request.getAttribute("message");
        String info = (String) httpServletRequest.getAttribute("info");
        System.out.println(info + " " + name);
        HashMap<String, Object> map = new HashMap<>();
        map.put("info_代码方式", info);  // 假如说是: 通过/params转发过来的就会为空 -》 (因为这个属于二次请求过来的)
        map.put("msg_注解方式", name);   // 假如说是: 通过/params转发过来的就会为空
        map.put("hello",hello);
        map.put("world",world);
        map.put("message",message);
        return map;
    }
// 传地方
    @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", "hello world");
        Cookie cookie = new Cookie("cookie_self", "88888888888");
        cookie.setDomain("localhost");  // 作用域设置为 本机
        response.addCookie(cookie);
        return "forward:/success";
    }

MapMethodProcessor 类下

Map、Model类型的参数,会返回 mavContainer.getModel();—> BindingAwareModelMap 是Model 也是Map

下面是Model和Map的对象,我们发现对象是一样的。所以Model是等于Map的。

相关文章
|
18天前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
45 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
18天前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
71 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
18天前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
78 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
4天前
|
JavaScript Java 关系型数据库
自主版权的Java诊所管理系统源码,采用Vue 2、Spring Boot等技术栈,支持二次开发
这是一个自主版权的Java诊所管理系统源码,支持二次开发。采用Vue 2、Spring Boot等技术栈,涵盖患者管理、医生管理、门诊管理、药店管理、药品管理、收费管理、医保管理、报表统计及病历电子化等功能模块。
|
1月前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
1月前
|
Java 关系型数据库 MySQL
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术的房屋租赁系统,旨在通过自动化和信息化手段提升房屋管理效率,优化租户体验。系统采用JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Layui和Spring Boot 2.0等技术栈,实现了高效的房源管理和便捷的租户服务。通过该系统,房东可以轻松管理房源,租户可以快速找到合适的住所,双方都能享受数字化带来的便利。未来,系统将持续优化升级,提供更多完善的服务。
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
|
18天前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
24 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
18天前
|
存储 JSON 算法
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
文章介绍了JWT令牌的基础教程,包括其应用场景、组成部分、生成和校验方法,并在Springboot中使用JWT技术体系完成拦截器的实现。
32 0
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
|
18天前
|
Java 数据库连接 mybatis
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
该文档详细介绍了如何在Springboot Web项目中整合Mybatis,包括添加依赖、使用`@MapperScan`注解配置包扫描路径等步骤。若未使用`@MapperScan`,系统会自动扫描加了`@Mapper`注解的接口;若使用了`@MapperScan`,则按指定路径扫描。文档还深入分析了相关源码,解释了不同情况下的扫描逻辑与优先级,帮助理解Mybatis在Springboot项目中的自动配置机制。
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
|
11天前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。