SpringMVC初体验

  • 新建Maven项目
  • pom.xml文件导包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.powernode</groupId>
    <artifactId>SpringMVC</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springMVC-001</module>
        <module>springmvc-hellomvc</module>
        <module>springmvc-002</module>
        <module>springMVC-003</module>
    </modules>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>6.1.7</version>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring6</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.1.0</version>
            <!--指定servlet-api有tomcat容器提供,打包时将不会将servlet-api包加入打包中-->
            <scope>provided</scope>
        </dependency>

     <!--过时了   <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>-->

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.3</version>
        </dependency>

    </dependencies>

</project>
  • 新建maven模块springmvc-002
    在springmvc-002模块中的pom.xml中新增打包方式为war
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringMVC</artifactId>
        <groupId>com.powernode</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springmvc-002</artifactId>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>
  • 在springmvc-002模块上右击,新增框架支持,如图所示:
  • 补充:从Java EE 8开始,Servlet API的维护权转交给了Eclipse Foundation的Jakarta EE社区。因此,在最新的Jakarta EE版本中,Servlet API的包名已经从javax.servlet更改为了jakarta.servlet。这意味着jakarta.servlet-api是Servlet API在Jakarta EE 9(以及后续版本)中的新命名形式。
  • 添加完web框架后会自动生成web目录,如图所示
  • 编辑web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <!--前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--Servlet初始化参数,指定springmvc配置文件和位置-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!--在web服务器启动时,就启动DispatcherServlet,优化-->
        <load-on-startup>0</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  • 新增并编辑spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--组件扫描-->
    <context:component-scan base-package="com.powernode.springmvc.controller"/>


    <!--配置视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
        <!--作用于视图渲染过程中,设置视图渲染后输出时采用的编码字符集-->
        <property name="characterEncoding" value="utf-8"/>
        <!--若存在多个视图解析器,配置优先级,值越小优先级越高-->
        <property name="order" value="1"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                        <!--设置模板文件的位置-->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!--设置模板文件后缀-->
                        <property name="suffix" value=".html"/>
                        <!--设置模板类型-->
                        <property name="templateMode" value="HTML"/>
                        <!--设置模板文件在读取和解析过程中采用的编码字符集-->
                        <property name="characterEncoding" value="utf-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

</beans>
  • 在com.powernode.springmvc.controller新增IndexController类
package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {
    @RequestMapping("/")
    public String index(){
        return "index";
    }

    @RequestMapping("/first")
    public String first(){
        System.out.println("业务逻辑");
        return "first";
    }
}
  • 在WEB-INF目录下新增templates目录,并在此目录下新增firstm.html文件和index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>First HTML PAGE</h1>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>首页</h1>
<a th:href="@{/first}">First Spring MVC Code!</a>
</body>
</html>
  • 启动tomcat10,访问http://localhost:8080/ 效果图

    单击First Spring MVC Code!后打开下图

获取请求数据的几种方法

  1. 使用原生的Servlet API进行获取
  • 补充: Servlet接口是Java Servlet API中的一个核心接口,它定义了Servlet的生命周期方法以及用于处理HTTP请求和响应的方法。一个Servlet是运行在Web服务器或Servlet容器(如Apache Tomcat、Jetty等)中的Java程序,用于扩展服务器的功能。
    Servlet接口中定义的主要方法有:
    init(ServletConfig config): 当Servlet被加载到容器中时调用,用于初始化Servlet。
    service(ServletRequest req, ServletResponse res): 这是Servlet处理请求的主要方法,但通常我们不直接实现它,而是重写doGet()、doPost()等特定HTTP方法的方法。
    destroy(): 当Servlet不再需要时(例如,服务器关闭或重新加载Servlet时)调用,用于释放资源。
    ServletRequest接口代表客户端发送的HTTP请求。它定义了一系列方法来获取请求信息,如请求头、请求参数、请求方法、请求路径等。
  • 在SpringMVC当中,一个Controller类中的方法参数上如果有HttpServletRequest,SpringMVC会自动将当前请求对象传递给这个参数,因此我们可以通过这个参数来获取请求提交的数据。测试一下。
  • 前端准备注册页面register.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<!--注册页面-->
<form th:action="@{/user/reg}" method="post">
    用户名: <input type="text" name="username"><br>
    密码: <input type="password" name="password"><br>
    性别:
        男<input type="radio" name="sex" value="1">
        女<input type="radio" name="sex" value="0">
        <br>
    兴趣:
        抽烟<input type="checkbox" name="interest" value="smoke">
        喝酒<input type="checkbox" name="interest" value="drink">
        烫头:<input type="checkbox" name="interest" value="perm">
        <br>
    简介:
        <textarea cols="60" rows="10" name="intro"></textarea>
        <br>
    <input type="submit" value="注册"/>
</form>
</body>
</html>

  • 准备测试成功页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ok</title>
</head>
<body>
<h1>Test OK!</h1>
</body>
</html>
  • 准备Controller类,UserController
package com.powernode.springmvc.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Arrays;

@Controller
public class UserController {
    @RequestMapping("/")
    public String toRegister(){
        return "register";
    }

    /*第一种方法原生的Servlet API*/
    /*@RequestMapping(value = "/user/reg",method = {RequestMethod.POST})
    public String register(HttpServletRequest request, HttpServletResponse response, HttpSession session){

        //获取请求提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String sex = request.getParameter("sex");
        String[] interest = request.getParameterValues("interest");
        String intro = request.getParameter("intro");

        System.out.println(username);
        System.out.println(password);
        System.out.println(sex);
        System.out.println(Arrays.toString(interest));
        System.out.println(intro);
        return "ok";
    }*/

    /*第二种方法:通过注解@RequestParam*/
    /*@RequestMapping(value = "/user/reg",method = {RequestMethod.POST})
    public String register(
            @RequestParam("username")
            String username, //变量名可以自定义
            @RequestParam("password")
            String password,
            @RequestParam(value = "sex",defaultValue = "1")
            Integer sex,
            @RequestParam("interest")
            String[] interest,
            @RequestParam("intro")
            String intro){
        System.out.println(username);
        System.out.println(password);
        System.out.println(sex);
        System.out.println(Arrays.toString(interest));
        System.out.println(intro);
        return "ok";
    }*/


    /*第三种方法(不常用):如果方法形参的名字和提交数据时的name相同,则 @RequestParam 可以省略。*/
    /*@RequestMapping(value = "/user/reg",method = {RequestMethod.POST})
    public String register(
                    String username, //此处变量名如果写错,那么前端提交后值为null
                    String password,
                    Integer sex,
                    String[] interest,
                    String intro){
        System.out.println(username);
        System.out.println(password);
        System.out.println(sex);
        System.out.println(Arrays.toString(interest));
        System.out.println(intro);
        return "ok";
    }*/

/*第四种方法:POJO类/JavaBean接收请求参数,当提交的数据非常多时,方法的形参个数会非常多,这不是很好的设计。在SpringMVC中也可以使用POJO类来接收请求参数。要求POJO类的属性名必须和请求参数的参数名保持一致*/
@RequestMapping(value = "/user/reg",method = {RequestMethod.POST})
    public String register(User user,
                           @RequestHeader(value = "Referer", required = false,defaultValue ="" )
                           String referer){
        System.out.println(user);
        System.out.println(referer);
        return "ok";
    }
}

其中@RequestHeader是将请求头信息中的Referer映射到形参referer上,前端提交后后台能看到Referer对应的值.
POJO类如下:

package com.powernode.springmvc.pojo;

import java.util.Arrays;

public class User {
    private Long id;
    private String username;
    private String password;
    private Integer sex;
    private String[] interest;
    private String intro;
    private String age;

/*    public User() {
    }*/

    public User(Long id, String username, String password, Integer sex, String[] interest, String intro, String age) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.sex = sex;
        this.interest = interest;
        this.intro = intro;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String[] getInterest() {
        return interest;
    }

    public void setInterest(String[] interest) {
        this.interest = interest;
    }

    public String getIntro() {
        return intro;
    }

    public void setIntro(String intro) {
        this.intro = intro;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", sex=" + sex +
                ", interest=" + Arrays.toString(interest) +
                ", intro='" + intro + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

第三种方法有一个前提:如果你采用的是Spring6+版本,需要在该模块的pom.xml文件中指定编译参数'-parameter',配置如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

分别测试以上方法,启动tomcat,在浏览器打开效果图:

输入选项后能够跳转到ok页面,可以通过浏览器F12查看提交的表单数据,也可以在idea控制台看到所填的值

如果前端有cookie,后端可以通过@CookieValue获取前端提交的cookie,比如id(此处的id是测试在前端提前生成好的),通过Get方式获得.

    @GetMapping(value = {"/user/reg"})
    public String register(User user,
                           @RequestHeader(value = "Referer", required = false,defaultValue ="" )
                           String referer,
                           @CookieValue(value = "id",required = false,defaultValue = "")
                           String id){
        System.out.println(user);
        System.out.println(referer);
        System.out.println("客户端提交过来的CookieID值"+id);
        return "ok";
    }

---

2024年7月5日

request域对象

接口名:HttpServletRequest
简称:request
request对象代表了一次请求。一次请求一个request。
使用请求域的业务场景:在A资源中通过转发的方式跳转到B资源,因为是转发,因此从A到B是一次请求,如果想让A资源和B资源共享同一个数据,可以将数据存储到request域中。

  1. 在上面的父项目中创建模块springmvc-005,刷新新模块中的pom.xml,引用父项目中依赖.
  2. 添加web支持.spring6中添加web依赖

  3. 编写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
    <!--字符编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--配置前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  1. 创建IndexController
package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {
    @RequestMapping("/")
    public String index(){
        return "index";
    }
}
  1. 创建spring配置文件并编辑
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--组件扫描-->
    <context:component-scan base-package="com.powernode.springmvc.controller"/>

    <!--视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
        <!--作用于视图渲染过程中,设置视图渲染后输出时采用的编码字符集-->
        <property name="characterEncoding" value="utf-8"/>
        <!--若存在多个视图解析器,配置优先级,值越小优先级越高-->
        <property name="order" value="1"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                        <!--设置模板文件的位置-->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!--设置模板文件后缀-->
                        <property name="suffix" value=".html"/>
                        <!--设置模板类型-->
                        <property name="templateMode" value="HTML"/>
                        <!--设置模板文件在读取和解析过程中采用的编码字符集-->
                        <property name="characterEncoding" value="utf-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

</beans>
  1. 编写index.html,都测试完成后写的文档,所以index.html页面后后面测试的内容.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>测试三个域对象</h1>
<h2>测试request域对象</h2>
<a th:href="@{/testServletAPI}">测试在SpringMVC当中使用原生Servlet API,完成request域共享</a><br>
<h2>测试Model接口</h2>
<a th:href="@{/testModel}">测试在SpringMVC当中使用Model接口,完成request域共享</a><br>
<h2>测试Map接口</h2>
<a th:href="@{/testMap}">测试在SpringMVC当中使用Map接口,完成request域共享</a><br>
<h2>测试ModelMap接口</h2>
<a th:href="@{/testModelMap}">测试在SpringMVC当中使用ModelMap接口,完成request域共享</a><br>
<h2>测试ModelAndView</h2>
<a th:href="@{/testModelAndView}">测试在SpringMVC当中使用ModelAndView类,完成request域共享</a><br>
</body>
</html>
  1. 创建转发成功访问的ok.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ok</title>
</head>
<body>
<div th:text="${testRequestScope}"></div>
</body>
</html>

  • 在SpringMVC中,在request域中共享数据有以下几种方式:
  1. 使用原生HttpServletRequestAPI方式。
  2. 使用Model接口。
  3. 使用Map接口。
  4. 使用ModelMap类。
  5. 使用ModelAndView类。
package com.powernode.springmvc.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
public class RequestScopeTestController {
    @RequestMapping("/testServletAPI")
    public String testServletAPI(HttpServletRequest request){
        //将共享的数据存储到request域当中
        request.setAttribute("testRequestScope","在SpringMVC中使用原生ServletAPI完成request域数据共享");
        return "ok";
    }


    @RequestMapping("/testModel")
    public String testModel(Model model){
        //向request域当中绑定数据
        model.addAttribute("testRequestScope","在SpringMVC中使用Model接口完成request域数据共享");
        System.out.println(model);
        System.out.println(model.getClass().getName());
        return "ok";
    }

    @RequestMapping("/testMap")
    public String testMap(Map<String,Object> map){
        //向request域当中存数据
        map.put("testRequestScope","在SpringMVC中使用Map接口完成request域数据共享");
        System.out.println(map);
        System.out.println(map.getClass().getName());
        //转发
        return "ok";
    }

    @GetMapping("/testModelMap")
    public String testMap(ModelMap modelMap){
        //向request域当中存数据
        modelMap.addAttribute("testRequestScope","在SpringMVC中使用ModelMap接口完成request域数据共享");
        System.out.println(modelMap);
        System.out.println(modelMap.getClass().getName());
        //转发
        return "ok";
    }

    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        //创建模型视图
        ModelAndView modelAndView = new ModelAndView();
        //给模型视图绑定数据
        modelAndView.addObject("testRequestScope","在SpringMVC中使用ModelAndView接口完成request域数据共享");
        //给模型视图绑定视图
        modelAndView.setViewName("ok");
        System.out.println("获取ModelAndView类名称"+modelAndView.getClass().getName());
        return modelAndView;
    }
}
  • 通过测试无论是Model、Map还是ModelMap,底层实例化的对象都是:BindingAwareModelMap


  • BindingAwareModelMap 补充:
  1. 内部实现类:BindingAwareModelMap 是 Spring MVC 内部用于实现 Model、ModelMap 接口和 Map<String, Object> 的具体类。

  2. 数据传递:在 Spring MVC 中,控制器方法可以通过参数接收 Model、ModelMap 或 Map 类型的对象,并向其中添加数据。这些数据最终会通过 BindingAwareModelMap 实例进行管理和传递,最终到达视图层。

  3. 请求域绑定:BindingAwareModelMap 中的数据默认会绑定到 HTTP 请求的作用域(request scope)中,使得视图层可以方便地访问这些数据。

  4. 不要直接使用:尽管 BindingAwareModelMap 提供了许多功能,但开发者通常不需要(也不应该)直接在代码中创建或操作 BindingAwareModelMap 的实例。相反,应该通过 Model、ModelMap 或 Map 接口来与模型数据进行交互。

  5. 作用域:默认情况下,BindingAwareModelMap 中的数据会绑定到 HTTP 请求的作用域中。这意味着这些数据只在当前请求的生命周期内有效。如果需要跨多个请求共享数据,可以考虑使用其他作用域(如 session scope)或数据存储机制(如数据库)。


  • 但是在SpringMVC框架中为了更好的体现MVC架构模式,提供了一个类:ModelAndView。这个类的实例封装了Model和View。也就是说这个类既封装业务处理之后的数据,也体现了跳转到哪个视图。使用它也可以完成request域数据共享。需要注意:
  1. 方法的返回值类型不是String,而是ModelAndView对象。
  2. ModelAndView不是出现在方法的参数位置,而是在方法体中new的。
  3. 需要调用addObject向域中存储数据。
  4. 需要调用setViewName设置视图的名字。
  • 在Spring MVC中,ModelAndView 是用于将模型数据和视图名称封装在一起的一个类。ModelAndView 本身并不直接使用 BindingAwareModelMap,但确实使用了一个模型映射(Model Map)来存储模型数据。
    BindingAwareModelMap 是Spring MVC内部使用的一个类,它扩展了 ModelMap(后者又扩展了 LinkedHashMap),并添加了一些额外的功能,主要是与数据绑定相关的
    在 ModelAndView 的上下文中,你通常不会直接看到 BindingAwareModelMap 的使用,因为 ModelAndView 提供了 addObject、addAllObjects 等方法来向模型中添加数据,这些方法会委托给其内部的模型映射(通常是 ModelMap 的一个实例,但不一定是 BindingAwareModelMap)。
    但是,在某些情况下,Spring MVC内部可能会使用 BindingAwareModelMap 来处理与数据绑定相关的场景。例如,在处理带有表单提交的请求时,如果使用了 @ModelAttribute 注解,并且表单验证失败,Spring MVC可能会使用 BindingAwareModelMap 来存储表单数据以及验证错误。
    总的来说,虽然 ModelAndView 不直接使用 BindingAwareModelMap,但Spring MVC在处理与数据绑定相关的场景时可能会使用它。在大多数情况下,你不需要直接关注这一点,只需要使用 ModelAndView 来封装你的模型数据和视图名称即可。

session域对象

在SpringMVC中使用session域共享数据,实现方式有多种,其中比较常见的两种方式:

  1. 使用原生HttpSession API
  2. 使用SessionAttributes注解
  • 在上面基础上创建SessionScopeController类,分别包括原生的和SessionAttributes注解
package com.powernode.springmvc.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@SessionAttributes(value = {"X","Y"})
public class SessionScopeController {
    @RequestMapping("/testSessionServletAPI")
    public String testServletAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session){
        //处理核心业务...
        //将数据存储到session中
        session.setAttribute("testSessionScope","测试在SpringMVC当中使用原生HttpSessionAPI,完成request域共享");
        //返回逻辑视图名称
        return "ok";
    }

    @RequestMapping("/testSessionAttribute")
    public String testSessionAttribute(ModelMap modelMap){
        //处理业务
        //将数据存储到session中
        modelMap.addAttribute("X","我是X");
        modelMap.addAttribute("Y","我是Y");
        return "ok";
    }
}
注意:@SessionAttributes注解使用在Controller类上。标注了当key是 x 或者 y 时,数据将被存储到会话session中。如果没有 SessionAttributes注解,默认存储到request域中。
  • 在index.html添加如下
<h2>测试session域对象</h2>
<a th:href="@{/testSessionServletAPI}">测试在SpringMVC当中使用HttpSession接口,完成session域共享</a><br>
<a th:href="@{/testSessionAttribute}">测试在SpringMVC当中使用@SessionAttributes注解,完成session域共享</a><br>
  • 在ok页面添加如下:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ok</title>
</head>
<body>
<div th:text="${testRequestScope}"></div>
<div th:text="${session.testSessionScope}">
</div>
<p th:text="${session.X}"></p>
<p th:text="${session.Y}"></p>
</body>
</html>

RESTFul编程风格

RESTFul是WEB服务接口的一种设计风格。
RESTFul定义了一组约束条件和规范,可以让WEB服务接口更加简洁、易于理解、易于扩展、安全可靠。
REST对请求方式的约束是这样的:
● 查询必须发送GET请求
● 新增必须发送POST请求
● 修改必须发送PUT请求
● 删除必须发送DELETE请求

REST对URL的约束是这样的:
● 传统的URL:get请求,/springmvc/getUserById?id=1
● REST风格的URL:get请求,/springmvc/user/1

● 传统的URL:get请求,/springmvc/deleteUserById?id=1
● REST风格的URL:delete请求, /springmvc/user/1
传统的 URL 与 RESTful URL 的区别是传统的 URL 是基于方法名进行资源访问和操作,而 RESTful URL 是基于资源的结构和状态进行操作的。下面是一张表格,展示两者之间的具体区别:

  1. 模拟get请求
  • 在父模块下创建springmvc-006模块,新增web框架支持
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

        <!--字符编码过滤器在最上面,优先执行-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--post转换put/delete请求的过滤器-->
    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--前端控制器-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcherServlet-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  • resources目录下dispatcher-servlet.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"


       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--组件扫描-->
    <context:component-scan base-package="com.powernode.springmvc.controller"/>

    <!--视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
        <!--作用于视图渲染过程中,设置视图渲染后输出时采用的编码字符集-->
        <property name="characterEncoding" value="utf-8"/>
        <!--若存在多个视图解析器,配置优先级,值越小优先级越高-->
        <property name="order" value="1"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                        <!--设置模板文件的位置-->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!--设置模板文件后缀-->
                        <property name="suffix" value=".html"/>
                        <!--设置模板类型-->
                        <property name="templateMode" value="HTML"/>
                        <!--设置模板文件在读取和解析过程中采用的编码字符集-->
                        <property name="characterEncoding" value="utf-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!--开启注解驱动-->
    <mvc:annotation-driven/>

    <!--视图控制器-->
    <mvc:view-controller path="/" view-name="index"/>

</beans>
  • UserController类
@Controller
public class UserController {
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public ModelAndView modelAndView(){
        ModelAndView modelAndView = new ModelAndView();
        System.out.println("正在查询用户所有信息");
        modelAndView.setViewName("ok");
        return modelAndView;
    }
    @RequestMapping(value = "/user/{id}",method =       RequestMethod.GET)
    public  String getById(@PathVariable(value = "id")String id){
        System.out.println("正在根据用户id查询用户信息...用户id是"+id);
        return "ok";
    }
  • index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>测试RESTFul编程风格</h1>
<hr>
<!--RESTFul风格的,查看用户列表-->
<a th:href="@{/user}">查看用户列表</a><br>
<!--RestFul风格,根据用户id查询用户信息-->
<a th:href="@{/user/110}">查询id是1的用户信息</a><br>

<!--RESTFul风格的,新增用户信息,用post请求-->
<form th:action="@{/user}" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" name="保存">
</form>

<!--RESTFul风格的,修改用户信息,用put请求,发送put请求先用post请求-->
<form th:action="@{/user}" method="post">
    <!--隐藏域-->
    <input type="hidden" name="_method" value="put">

    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" name="修改">
</form>
<!--RESTFul风格删除用户信息
发送delete请求的前提是发送post请求,通过隐藏域提交_method=delete-->
<a th:href="@{/user/120}" onclick="dele(event)">删除用户id为120的用户信息</a>
<form id="deleForm" method="post">
    <input type="hidden" name="_method" value="delete">
</form>

<script>
    function dele(event){
        //获取表单
        let deleForm = document.getElementById("deleForm");
        //给form的action赋值
        deleForm.action = event.target.href;
        //发送POST请求提交表单
        deleForm.onsubmit();
        //阻止超链接的默认行为
        event.preventDefault();
    }
</script>
</body>
</html>
  • ok.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ok</title>
</head>
<body>
<h1>OK!</h1>
</body>
</html>
  • 启动tomcat10测试


    测试:查询id是1的用户信息
  1. 模拟post请求
  • 在UserController类中新增
@RequestMapping(value = "/user",method = RequestMethod.POST)
    public String save(User user){
        System.out.println("正在保存用户信息");
        System.out.println(user);
        return "ok";
    }
  • 新增User实体类
package com.powernode.springmvc.bean;

public class User {
    private String username;
    private String password;
    private Integer age;

    public User(String username, String password, Integer age) {
        this.username = username;
        this.password = password;
        this.age = age;
    }

    public User() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 启动tomcat测试


    后台控制台输出信息:
    正在保存用户信息
    User
  1. 模拟PUT请求
    对于PUT请求,前提是一个POST请求。然后在发送POST请求的时候,提交这样的数据:_method=PUT,最后在web.xml文件配置SpringMVC提供的过滤器:HiddenHttpMethodFilter
  • 在UserController类中新增
    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String modify(User user){
        System.out.println("正在修改用户信息: "+ user);
        return "ok";
    }
  • 配置过滤器,前面已经在dispatcherServlet-servlet.xml中写了
  • index.html页面的配置
  • 启动tomat测试

  • idea控制台输出:
    正在修改用户信息: User
  1. 模拟delete请求
  • 在UserController类中新增
@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public String del(@PathVariable("id") String id){
        System.out.println("正在删除用户");
        return "ok";
    }
  • index.html页面
  • 启动tomcat测试

  • @ResponseBody注解
    @ResponseBody 是 Spring MVC 中的一个注解,可以直接将控制器(Controller)的方法返回的对象自动转换为字符串,并写入到 HTTP 响应(HttpServletResponse)的 body 中。这样,前端就可以直接接收到这些数据
@Controller
public class AjaxController {
/*    @GetMapping("/ajax")
    public String ajax(HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        writer.print("hello ajx,My name is SpringMVC");
        return null;
    }*/

    @GetMapping("/ajax")
    @ResponseBody
    public String ajax(){
        return "hello ajx,My name is SpringMVC";
    }
}

@ResponseBody注解等同于原生的

  • 实体类转换为json
package com.powernode.springmvc.bean;

public class User {
    private Long id;
    private String name;
    private String password;

    public User(Long id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

修改AjaxController类

    @RequestMapping(value = "/ajax", method = RequestMethod.GET)
    @ResponseBody
    public User ajax(){
        User user = new User(1122L, "张三", "123");
        return user;
    }

前端Vue3+axios+Thymeleaf代码:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <!--引入vue-->
<!--    <script th:src="@{/static/js/main.js}"></script>-->
    <script src="https://cdn.jsdelivr.net/npm/vue@3.x/dist/vue.global.js"></script>
    <!--引入axios-->
<!--    <script th:src="@{/static/js/axios.js}"></script>-->
    <script th:src="@{https://cdn.staticfile.org/axios/0.27.2/axios.min.js}"></script>
</head>
<body>
<h1>发送Vue3+axios+Thymeleaf+springmvc发送Ajax请求</h1>
<hr>
<div id="app">
    <button @click="getMessage">获取消息</button>
    <h1>{{message}}</h1>
</div>

<script th:inline="javascript">
    Vue.createApp({
        data(){
            return{
                message: ''
            }
        },
        methods: {
            //异步方法
            async getMessage(){
                //发送ajax请求
                let response = await axios.get('/ajax')
                //将返回的数据交给message
                this.message = response.data
            }
        }
    }).mount("#app")
</script>
</body>
</html>

启动tomcat,前端通过访问/ajax,产生的效果:

补充:
MappingJackson2HttpMessageConverter是Spring框架中的一个HTTP消息转换器,主要用于在Java对象和JSON之间进行转换。
MappingJackson2HttpMessageConverter依赖于Jackson库来实现Java对象与JSON之间的序列化和反序列化。
jackson-databind是Jackson库的核心包之一,它提供了数据绑定的功能,即在Java对象和JSON之间进行转换。
所以pom.xml需要导入jackson-databind包

  <!--专门负责将java对象转换成json字符串的包,也可以互转-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>
@RestController

在类上添加@RestController 等于 类上添加@Controller + 在每个返回数据的方法上添加@ResponseBody,因为 在类上添加@RestController 默认所有方法都带有 @ResponseBody

@RequestBody

这个注解的作用是直接将请求体传递给Java程序,在Java程序中可以直接使用一个String类型的变量接收这个请求体的内容。

  1. 将前端页面中的form表单提交后后台转成java对象测试:
    编写User类
package com.powernode.springmvc.bean;

public class User {
    private Long id;
    private String name;
    private String password;

    public User(Long id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

编写RequestBodyController类

package com.powernode.springmvc.controller;

import com.powernode.springmvc.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

//@Controller
@RestController
public class RequestBodyController {
    @PostMapping("/save")
    public String save(@RequestBody String requestBodyStr){
        System.out.println(requestBodyStr);
        return "ok";
    }

/*    @PostMapping("/save")
    public String save(User user){
        System.out.println(user);
        return "ok";
    }*/

上面的两个方法都可以获取index.html页面中提交的表单信息

<form th:action="@{/save}" method="post">
    用户名:<input type="text" name="name"/>
    密码:<input type="password" name="password">
    <input type="submit" value="保存"/>
</form>

通过@RequestBody注解获取的格式是name=alice&password=222222222,Springmvc使用FormHttpMessageConverter消息转换器,将请求体转换成user对象。
通过pojo类的方法获取的格式时User{id=null, name='江疏影', password='222222222'}

  1. 在请求体中提交的是一个JSON格式的字符串,这个JSON字符串传递给Spring MVC之后,将JSON字符串转换成POJO对象。
    在index.html页面新增测试代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <!--引入vue-->
<!--    <script th:src="@{/static/js/main.js}"></script>-->
    <script src="https://cdn.jsdelivr.net/npm/vue@3.x/dist/vue.global.js"></script>
    <!--引入axios-->
<!--    <script th:src="@{/static/js/axios.js}"></script>-->
    <script th:src="@{https://cdn.staticfile.org/axios/0.27.2/axios.min.js}"></script>
</head>
<body>
<h1>发送Vue3+axios+Thymeleaf+springmvc发送Ajax请求</h1>
<hr>
<form th:action="@{/save}" method="post">
    用户名:<input type="text" name="name"/>
    密码:<input type="password" name="password">
    <input type="submit" value="保存"/>
</form>


<div id="app">
    <button @click="getMessage">获取消息</button>
    <h1>{{message}}</h1>
</div>

<script th:inline="javascript">
    Vue.createApp({
        data(){
            return{
                message: ''
            }
        },
        methods: {
            //异步方法
            async getMessage(){
                //发送ajax请求
                let response = await axios.get('/ajax')
                //将返回的数据交给message
                this.message = response.data
            }
        }
    }).mount("#app")
</script>

<div id="app1">
    <button @click="getMessage">提交post</button>
    <h1>{{message1}}</h1>
</div>

<!--发送ajax post请求,并提交json-->
<script th:inline="javascript">
    let jsonObj = {"name" : "zhangsan","password":"123456"}
    Vue.createApp({
        data1(){
            return{
                message: ''
            }
        },
        methods: {
            //异步方法
            async getMessage(){
                //发送ajax请求
                let response = await axios.post('/save2',JSON.stringify(jsonObj),{
                    headers : {
                        "Content-Type": "application/json"
                    }
                })
                //将返回的数据交给message
                this.message1 = response.data1
            }
        }
    }).mount("#app1")
</script>
</body>
</html>
ON.stringify(jsonObj),{
                    headers : {
                        "Content-Type": "application/json"
                    }
                })
                //将返回的数据交给message
                this.message1 = response.data1
            }
        }
    }).mount("#app1")
</script>

在RequestBodyController中新增

//    @RequestMapping(value = {"/save2"}, method= RequestMethod.POST)
    @PostMapping(value = "/save2")
    public String saveUser(@RequestBody User user){
        System.out.println(user);
        return "ok";
    }

重启tomcat,打开浏览器测试,点击"提交post"

idea后台控制台显示User{id=null, name='zhangsan', password='123456'},该用户信息是在index.html提交定义好的,如图所示:

RequestEntity类

RequestEntity 是 Spring Framework 的 org.springframework.http.RequestEntity 类,它用于表示一个带有请求头、请求体和 URL 的 HTTP 请求。RequestEntity 通常在发送 HTTP 请求时使用
获取index.html中的post请求信息

在RequestBodyController类中新增

 @PostMapping(value = "/save2")
    public String saveUser(RequestEntity<User> requestEntity) {
        //请求方法
        HttpMethod method = requestEntity.getMethod();
        System.out.println(method);
        //请求URL
        URI url = requestEntity.getUrl();
        System.out.println(url);
        //请求头
        HttpHeaders headers = requestEntity.getHeaders();
        System.out.println("请求头"+headers);
        //获取请求头中的内容信息
        MediaType contentType = headers.getContentType();
        System.out.println("请求头中的内容信息"+contentType);
        //请求体
        User body = requestEntity.getBody();
        System.out.println(body);
        return "ok";
    }

重启tomcat,启动浏览器,点击"提交post",在ideal后台控制中心获取请求的信息,如图所示:

ResponseEntity类

ResponseEntity不是注解,是一个类。用该类的实例可以封装响应协议,包括:状态行、响应头、响应体。也就是说:如果你想定制属于自己的响应协议,可以使用该类。
假如我要完成这样一个需求:前端提交一个id,后端根据id进行查询,如果返回null,请在前端显示404错误。如果返回不是null,则输出返回的user。

  • 编辑index.html
<a th:href="@{/user/2}">查找id=1的用户信息</a>
  • 编写UerController类
package com.powernode.springmvc.controller;

import com.powernode.springmvc.bean.User;
import com.powernode.springmvc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

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

    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    public ResponseEntity<User> getById(@PathVariable("id") Long id){
        User user = userService.getById(id);
        if (user == null){
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }else{
            return ResponseEntity.ok(user);
        }
    }
}
  • 编写UserServie类
package com.powernode.springmvc.service;

import com.powernode.springmvc.bean.User;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public User getById(Long id){
        if (id == 1){
            return new User(111L,"zhangsan","123");
        }
        return null;
    }
}

重启tomcat,浏览器点击"查找id=1的用户信息"

跳转结果

如果浏览器地址手动更改访问为http://localhost:8080/user/2

拦截器
  • 拦截器基本配置
    第一种方式:在spring配置文件中配置
    配置测试拦截器Interceptor1
package com.powernode.springmvc.interceptors;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class Interceptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor1's preHandlehaha");
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        System.out.println("Interceptor1's postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        System.out.println("Interceptor1's afterCompletion");
    }
}
  • 在dispatcherServlet-servlet.xml中添加
<mvc:interceptors>
    <bean class="com.powernode.springmvc.interceptors.Interceptor1"/>
</mvc:interceptors>

第二种方法,使用注解配置

<mvc:interceptors>
<!--通过注解方式,引用类名,首字母小写-->
    <ref bean="interceptor1"/>
</mvc:interceptors>

第二种方式的前提:
● 前提1:包扫描

● 前提2:使用 @Component 注解进行标注

2. 自定义拦截路径

        <mvc:interceptor>
            <!--拦截所有路径-->
            <mvc:mapping path="/**"/>
            <!--放行指定路径-->
            <mvc:exclude-mapping path="/ok"/>
            <!--设置拦截器-->
            <ref bean="interceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>
posted @ 2024-06-29 22:28  文采杰出  阅读(2)  评论(0编辑  收藏  举报