• SSM - Springboot - MyBatis-Plus 全栈体系(二十)


    第四章 SpringMVC

    二、SpringMVC 接收数据

    3. 接收 Cookie 数据

    • 可以使用 @CookieValue 注释将 HTTP Cookie 的值绑定到控制器中的方法参数。

    • 考虑使用以下 cookie 的请求:

    JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
    
    • 1
    • 下面的示例演示如何获取 cookie 值:
    @GetMapping("/demo")
    public void handle(@CookieValue("JSESSIONID") String cookie) {
      //...
    }
    
    • 1
    • 2
    • 3
    • 4

    4. 接收请求头数据

    • 可以使用 @RequestHeader 批注将请求标头绑定到控制器中的方法参数。
    • 请考虑以下带有标头的请求:
    Host                    localhost:8080
    Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
    Accept-Language         fr,en-gb;q=0.7,en;q=0.3
    Accept-Encoding         gzip,deflate
    Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive              300
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 下面的示例获取 Accept-EncodingKeep-Alive 标头的值:
    @GetMapping("/demo")
    public void handle(
        @RequestHeader("Accept-Encoding") String encoding,
        @RequestHeader("Keep-Alive") long keepAlive) {
      //...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5. 原生 Api 对象操作

    • 下表描述了支持的控制器方法参数
    Controller method argument 控制器方法参数Description
    jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse请求/响应对象
    jakarta.servlet.http.HttpSession强制存在会话。因此,这样的参数永远不会为 null
    java.io.InputStream, java.io.Reader用于访问由 Servlet API 公开的原始请求正文。
    java.io.OutputStream, java.io.Writer用于访问由 Servlet API 公开的原始响应正文。
    @PathVariable接收路径参数注解
    @RequestParam用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。
    @RequestHeader用于访问请求标头。标头值将转换为声明的方法参数类型。
    @CookieValue用于访问 Cookie。Cookie 值将转换为声明的方法参数类型。
    @RequestBody用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。
    java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap共享域对象,并在视图呈现过程中向模板公开。
    Errors, BindingResult验证和数据绑定中的错误信息获取对象!
    • 获取原生对象示例:
    /**
     * 如果想要获取请求或者响应对象,或者会话等,可以直接在形参列表传入,并且不分先后顺序!
     * 注意: 接收原生对象,并不影响参数接收!
     */
    @GetMapping("api")
    @ResponseBody
    public String api(HttpSession session , HttpServletRequest request,
                      HttpServletResponse response){
        String method = request.getMethod();
        System.out.println("method = " + method);
        return "api";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6. 共享域对象操作

    6.1 属性(共享)域作用回顾
    • 在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:ServletContextHttpSessionHttpServletRequestPageContext
    1. ServletContext 共享域:ServletContext 对象可以在整个 Web 应用程序中共享数据,是最大的共享域。一般可以用于保存整个 Web 应用程序的全局配置信息,以及所有用户都共享的数据。在 ServletContext 中保存的数据是线程安全的。
    2. HttpSession 共享域:HttpSession 对象可以在同一用户发出的多个请求之间共享数据,但只能在同一个会话中使用。比如,可以将用户登录状态保存在 HttpSession 中,让用户在多个页面间保持登录状态。
    3. HttpServletRequest 共享域:HttpServletRequest 对象可以在同一个请求的多个处理器方法之间共享数据。比如,可以将请求的参数和属性存储在 HttpServletRequest 中,让处理器方法之间可以访问这些数据。
    4. PageContext 共享域:PageContext 对象是在 JSP 页面 Servlet 创建时自动创建的。它可以在 JSP 的各个作用域中共享数据,包括pageScoperequestScopesessionScopeapplicationScope 等作用域。
    • 共享域的作用是提供了方便实用的方式在同一 Web 应用程序的多个组件之间传递数据,并且可以将数据保存在不同的共享域中,根据需要进行选择和使用。
      在这里插入图片描述
    6.2 Request 级别属性(共享)域
    6.2.1 使用 Model 类型的形参
    @RequestMapping("/attr/request/model")
    @ResponseBody
    public String testAttrRequestModel(
    
            // 在形参位置声明Model类型变量,用于存储模型数据
            Model model) {
    
        // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
        // 存入请求域这个动作也被称为暴露到请求域
        model.addAttribute("requestScopeMessageModel","i am very happy[model]");
    
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    6.2.2 使用 ModelMap 类型的形参
    @RequestMapping("/attr/request/model/map")
    @ResponseBody
    public String testAttrRequestModelMap(
    
            // 在形参位置声明ModelMap类型变量,用于存储模型数据
            ModelMap modelMap) {
    
        // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
        // 存入请求域这个动作也被称为暴露到请求域
        modelMap.addAttribute("requestScopeMessageModelMap","i am very happy[model map]");
    
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    6.2.3 使用 Map 类型的形参
    @RequestMapping("/attr/request/map")
    @ResponseBody
    public String testAttrRequestMap(
    
            // 在形参位置声明Map类型变量,用于存储模型数据
            Map<String, Object> map) {
    
        // 我们将数据存入模型,SpringMVC 会帮我们把模型数据存入请求域
        // 存入请求域这个动作也被称为暴露到请求域
        map.put("requestScopeMessageMap", "i am very happy[map]");
    
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    6.2.4 使用原生 request 对象
    @RequestMapping("/attr/request/original")
    @ResponseBody
    public String testAttrOriginalRequest(
    
            // 拿到原生对象,就可以调用原生方法执行各种操作
            HttpServletRequest request) {
    
        request.setAttribute("requestScopeMessageOriginal", "i am very happy[original]");
    
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    6.2.5 使用 ModelAndView 对象
    @RequestMapping("/attr/request/mav")
    public ModelAndView testAttrByModelAndView() {
    
        // 1.创建ModelAndView对象
        ModelAndView modelAndView = new ModelAndView();
        // 2.存入模型数据
        modelAndView.addObject("requestScopeMessageMAV", "i am very happy[mav]");
        // 3.设置视图名称
        modelAndView.setViewName("target");
    
        return modelAndView;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    6.3 Session 级别属性(共享)域
    @RequestMapping("/attr/session")
    @ResponseBody
    public String testAttrSession(HttpSession session) {
        //直接对session对象操作,即对会话范围操作!
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    6.4 Application 级别属性(共享)域
    • 解释:springmvc 会在初始化容器的时候,讲 servletContext 对象存储到 ioc 容器中!
    @Autowired
    private ServletContext servletContext;
    
    @RequestMapping("/attr/application")
    @ResponseBody
    public String attrApplication() {
    
        servletContext.setAttribute("appScopeMsg", "i am hungry...");
    
        return "target";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三、SpringMVC 响应数据

    1. handler 方法分析

    • 理解 handler 方法的作用和组成:
    /**
     * TODO: 一个controller的方法是控制层的一个处理器,我们称为handler
     * TODO: handler需要使用@RequestMapping/@GetMapping系列,声明路径,在HandlerMapping中注册,供DS查找!
     * TODO: handler作用总结:
     *       1.接收请求参数(param,json,pathVariable,共享域等)
     *       2.调用业务逻辑
     *       3.响应前端数据(页面(不讲解模版页面跳转),json,转发和重定向等)
     * TODO: handler如何处理呢
     *       1.接收参数: handler(形参列表: 主要的作用就是用来接收参数)
     *       2.调用业务: { 方法体  可以向后调用业务方法 service.xx() }
     *       3.响应数据: return 返回结果,可以快速响应前端数据
     */
    @GetMapping
    public Object handler(简化请求参数接收){
        调用业务方法
        返回的结果 (页面跳转,返回数据(json))
        return 简化响应前端数据;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 总结:
      • 请求数据接收,我们都是通过 handler 的形参列表
      • 前端数据响应,我们都是通过 handler 的 return 关键字快速处理!
      • springmvc 简化了参数接收和响应!

    2. 页面跳转控制

    2.1 快速返回模板视图
    2.1.1 开发模式回顾
    • 在 Web 开发中,有两种主要的开发模式:前后端分离和混合开发。
    • 前后端分离模式:[重点]
      • 指将前端的界面和后端的业务逻辑通过接口分离开发的一种方式。开发人员使用不同的技术栈和框架,前端开发人员主要负责页面的呈现和用户交互,后端开发人员主要负责业务逻辑和数据存储。前后端通信通过 API 接口完成,数据格式一般使用 JSON 或 XML。前后端分离模式可以提高开发效率,同时也有助于代码重用和维护。
    • 混合开发模式:
      • 指将前端和后端的代码集成在同一个项目中,共享相同的技术栈和框架。这种模式在小型项目中比较常见,可以减少学习成本和部署难度。但是,在大型项目中,这种模式会导致代码耦合性很高,维护和升级难度较大。
    • 对于混合开发,我们就需要使用动态页面技术,动态展示 Java 的共享域数据!!
    2.1.2 jsp 技术了解
    • JSP(JavaServer Pages)是一种动态网页开发技术,它是由 Sun 公司提出的一种基于 Java 技术的 Web 页面制作技术,可以在 HTML 文件中嵌入 Java 代码,使得生成动态内容的编写更加简单。
    • JSP 最主要的作用是生成动态页面。它允许将 Java 代码嵌入到 HTML 页面中,以便使用 Java 进行数据库查询、处理表单数据和生成 HTML 等动态内容。另外,JSP 还可以与 Servlet 结合使用,实现更加复杂的 Web 应用程序开发。
    • JSP 的主要特点包括:
    1. 简单:JSP 通过将 Java 代码嵌入到 HTML 页面中,使得生成动态内容的编写更加简单。
    2. 高效:JSP 首次运行时会被转换为 Servlet,然后编译为字节码,从而可以启用 Just-in-Time(JIT)编译器,实现更高效的运行。
    3. 多样化:JSP 支持多种标准标签库,包括 JSTL(JavaServer Pages 标准标签库)、EL(表达式语言)等,可以帮助开发人员更加方便的处理常见的 Web 开发需求。
    • 总之,JSP 是一种简单高效、多样化的动态网页开发技术,它可以方便地生成动态页面和与 Servlet 结合使用,是 Java Web 开发中常用的技术之一。
    2.1.3 准备 jsp 页面和依赖
    • pom.xml 依赖
    
    <dependency>
        <groupId>jakarta.servlet.jsp.jstlgroupId>
        <artifactId>jakarta.servlet.jsp.jstl-apiartifactId>
        <version>3.0.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • jsp 页面创建
    • 建议位置:/WEB-INF/下,避免外部直接访问!
    • 位置:/WEB-INF/views/home.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>Titletitle>
      head>
      <body>
            
            ${msg}
      body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2.1.4 快速响应模板页面
    2.1.4.1 配置 jsp 视图解析器
    @EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
    @Configuration
    @ComponentScan(basePackages = "com.alex.controller") //TODO: 进行controller扫描
    
    //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
    public class SpringMvcConfig implements WebMvcConfigurer {
    
        //配置jsp对应的视图解析器
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            //快速配置jsp模板语言对应的
            registry.jsp("/WEB-INF/views/",".jsp");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    2.1.4.2 handler 返回视图
    /**
     *  跳转到提交文件页面  /save/jump
     *
     *  如果要返回jsp页面!
     *     1.方法返回值改成字符串类型
     *     2.返回逻辑视图名即可
     *         
     *            + 逻辑视图名 +
     *         
     */
    @GetMapping("jump")
    public String jumpJsp(Model model){
        System.out.println("FileController.jumpJsp");
        model.addAttribute("msg","request data!!");
        return "home";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.2 转发和重定向
    • 在 Spring MVC 中,Handler 方法返回值来实现快速转发,可以使用 redirect 或者 forward 关键字来实现重定向。
    @RequestMapping("/redirect-demo")
    public String redirectDemo() {
        // 重定向到 /demo 路径
        return "redirect:/demo";
    }
    
    @RequestMapping("/forward-demo")
    public String forwardDemo() {
        // 转发到 /demo 路径
        return "forward:/demo";
    }
    
    //注意: 转发和重定向到项目下资源路径都是相同,都不需要添加项目根路径!填写项目下路径即可!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 总结:
      • 将方法的返回值,设置 String 类型
      • 转发使用 forward 关键字,重定向使用 redirect 关键字
      • 关键字: /路径
      • 注意:如果是项目下的资源,转发和重定向都一样都是项目下路径!都不需要添加项目根路径!

    3. 返回 JSON 数据

    3.1 前置准备
    3.1.1 导入 jackson 依赖
    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-databindartifactId>
        <version>2.15.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3.1.2 添加 json 数据转化器
    • @EnableWebMvc
    //TODO: SpringMVC对应组件的配置类 [声明SpringMVC需要的组件信息]
    
    //TODO: 导入handlerMapping和handlerAdapter的三种方式
     //1.自动导入handlerMapping和handlerAdapter [推荐]
     //2.可以不添加,springmvc会检查是否配置handlerMapping和handlerAdapter,没有配置默认加载
     //3.使用@Bean方式配置handlerMapper和handlerAdapter
    @EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
    @Configuration
    @ComponentScan(basePackages = "com.alex.controller") //TODO: 进行controller扫描
    
    //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
    public class SpringMvcConfig implements WebMvcConfigurer {
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    3.2 @ResponseBody
    3.2.1 方法上使用@ResponseBody
    • 可以在方法上使用 @ResponseBody 注解,用于将方法返回的对象序列化为 JSON 或 XML 格式的数据,并发送给客户端。在前后端分离的项目中使用!
    • 测试方法:
    @GetMapping("/accounts/{id}")
    @ResponseBody
    public Object handle() {
      // ...
      return obj;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 具体来说,@ResponseBody 注解可以用来标识方法或者方法返回值,表示方法的返回值是要直接返回给客户端的数据,而不是由视图解析器来解析并渲染生成响应体(viewResolver 没用)。
    • 测试方法:
    @RequestMapping(value = "/user/detail", method = RequestMethod.POST)
    @ResponseBody
    public User getUser(@RequestBody User userParam) {
        System.out.println("userParam = " + userParam);
        User user = new User();
        user.setAge(18);
        user.setName("John");
        //返回的对象,会使用jackson的序列化工具,转成json返回给前端!
        return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 返回结果:

    在这里插入图片描述

    3.2.2 类上使用@ResponseBody
    • 如果类中每个方法上都标记了 @ResponseBody 注解,那么这些注解就可以提取到类上。
    @ResponseBody  //responseBody可以添加到类上,代表默认类中的所有方法都生效!
    @Controller
    @RequestMapping("param")
    public class ParamController {
    
    • 1
    • 2
    • 3
    • 4
    3.3 @RestController
    • 类上的 @ResponseBody 注解可以和 @Controller 注解合并为 @RestController 注解。所以使用了 @RestController 注解就相当于给类中的每个方法都加了 @ResponseBody 注解。
    • RestController 源码:
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Controller
    @ResponseBody
    public @interface RestController {
    
      /**
       * The value may indicate a suggestion for a logical component name,
       * to be turned into a Spring bean in case of an autodetected component.
       * @return the suggested component name, if any (or empty String otherwise)
       * @since 4.0.1
       */
      @AliasFor(annotation = Controller.class)
      String value() default "";
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4. 返回静态资源处理

    4.1 静态资源概念
    • 资源本身已经是可以直接拿到浏览器上使用的程度了,不需要在服务器端做任何运算、处理。典型的静态资源包括:

      • 纯 HTML 文件
      • 图片
      • CSS 文件
      • JavaScript 文件
      • ……
    4.2 静态资源访问和问题解决
    4.2.1 web 应用加入静态资源

    在这里插入图片描述

    4.2.2 手动构建确保编译

    在这里插入图片描述
    在这里插入图片描述

    4.2.3 访问静态资源

    在这里插入图片描述

    4.2.4 问题分析
    • DispatcherServlet 的 url-pattern 配置的是“/”
    • url-pattern 配置“/”表示整个 Web 应用范围内所有请求都由 SpringMVC 来处理
    • 对 SpringMVC 来说,必须有对应的 @RequestMapping 才能找到处理请求的方法
    • 现在 images/mi.jpg 请求没有对应的 @RequestMapping 所以返回 404
    4.2.5 问题解决
    • 在 SpringMVC 配置配置类:
    @EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
    @Configuration
    @ComponentScan(basePackages = "com.alex.controller") //TODO: 进行controller扫描
    //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
    public class SpringMvcConfig implements WebMvcConfigurer {
    
        //配置jsp对应的视图解析器
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            //快速配置jsp模板语言对应的
            registry.jsp("/WEB-INF/views/",".jsp");
        }
    
        //开启静态资源处理 
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 再次测试访问图片:

    在这里插入图片描述

    4.2.6 新的问题:其他原本正常的 handler 请求访问不了了
    • handler 无法访问
    • 解决方案:
    @EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
    
    • 1
  • 相关阅读:
    素数判断[牛客]
    ARMv8常用寄存器记录
    论文开题报告的研究基础怎么写?
    登录验证的步骤
    leetcode:828. 统计子串中的唯一字符【贡献题 + 记录同一个c的下标 + 分别记录每个c的贡献】
    ArcGIS基础:使用线段分割面数据操作
    PO VO DTO 转换神器替代BeanUtils 了
    戏说领域驱动设计(十一)——纠偏
    【MATLAB源码-第54期】基于白鲸优化算法(WOA)和遗传算法(GA)的栅格地图路径规划最短路径和适应度曲线对比。
    聊聊设计模式——解释器模式
  • 原文地址:https://blog.csdn.net/sgsgkxkx/article/details/133581361