SpringMVC

文章目录

SpringMVC的概述

MVC模型

  1. MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
  2. 模型(Model):负责封装业务数据和业务逻辑,通常是 JavaBean 或领域对象,可从数据库、文件等数据源获取数据。
  3. 视图(View):负责将模型中的数据呈现给用户,常见形式有 JSP、Thymeleaf、FreeMarker 模板等。
  4. 控制器(Controller):负责接收用户请求,调用模型处理业务逻辑,然后选择合适的视图将结果展示给用户。

SpringMVC组件解析

SpringMVC处理请求的执行流程

  1. DispatcherServlet 接收请求:请求进入 SpringMVC 应用,首先被 DispatcherServlet(前端控制器)拦截,它是整个请求处理的核心枢纽。
  2. HandlerMapping 映射处理器:DispatcherServlet 调用 HandlerMapping(处理器映射器),根据请求的 URL、请求方法等信息,在已配置的映射关系中查找对应的处理器(Controller)。比如根据 @RequestMapping 注解配置的映射规则,找到处理该请求的具体 Controller 类和方法,HandlerMapping 返回一个包含处理器和拦截器的 HandlerExecutionChain 对象。
  3. HandlerAdapter 调用处理器:DispatcherServlet 拿到 HandlerExecutionChain 后,通过 HandlerAdapter(处理器适配器)来调用处理器。由于处理器类型可能不同,HandlerAdapter 负责适配不同的处理器,确保 DispatcherServlet 能以统一方式调用。
  4. 拦截器预处理(可选):在处理器执行前,HandlerExecutionChain 中配置的拦截器会依次执行预处理方法(preHandle),可用于权限验证、日志记录等操作。若拦截器返回 false,请求处理流程将被中断,不会继续执行处理器。
  5. 处理器处理请求:处理器(Controller)被调用,接收请求参数,调用业务逻辑层(Service 层)的方法处理业务,如查询数据库、计算数据等。处理完成后,处理器返回一个 ModelAndView 对象,包含处理结果数据(Model)和逻辑视图名(View)。
  6. 拦截器后处理(可选):处理器执行完成后,拦截器会依次执行后处理方法(postHandle),可以对 ModelAndView 对象进行进一步处理,如添加额外数据等。
  7. ViewResolver 解析视图:DispatcherServlet 将 ModelAndView 对象传递给 ViewResolver(视图解析器),视图解析器根据逻辑视图名,找到对应的实际视图,如 JSP、Thymeleaf 模板等,并返回视图对象。
  8. 视图渲染:DispatcherServlet 将模型数据传递给视图对象,视图将数据渲染成最终的响应内容,如生成 HTML 页面、JSON 数据等。
  9. 返回响应:响应内容通过 ServletResponse 对象返回给 Tomcat 服务器,Tomcat 再将响应发送回浏览器,浏览器解析并展示响应内容。

组件解析

  1. 前端控制器(DispatcherServlet)

  2. 处理器映射器(HandlerMapping)

  3. 处理器(Handler)

  4. 处理器适配器(HandlAdapter)

  5. 视图解析器(View Resolver)

  6. 视图(View)

  7. 前端控制器(DispatcherServlet)

    • 功能:作为 Spring MVC 的核心入口点,它接收所有客户端的 HTTP 请求,并负责协调其他组件来处理请求,最后将处理结果返回给客户端。可以将其看作是整个 Web 应用请求处理的调度中心。
    • 工作原理:在 Web 应用启动时,DispatcherServlet 会被初始化,并读取配置文件(如 Spring 的配置文件)来了解如何处理请求。当有请求到达时,它会依次调用处理器映射器、处理器适配器等组件,按照预定的流程处理请求。
  8. 处理器映射器(HandlerMapping)

    • 功能:根据客户端请求的 URL、HTTP 方法等信息,查找匹配的处理器(Handler)。它维护了请求和处理器之间的映射关系,将请求准确地路由到相应的处理器上。
    • 工作原理:常见的处理器映射器实现如 RequestMappingHandlerMapping,它会扫描应用中带有 @RequestMapping 等注解的控制器方法,建立请求 URL 和处理器方法之间的映射。当 DispatcherServlet 调用它时,它会根据请求信息找到对应的处理器,并返回一个包含处理器和拦截器的 HandlerExecutionChain 对象。
  9. 处理器(Handler)

    • 功能:也称为控制器(Controller),是处理具体业务逻辑的组件。它接收请求参数,调用业务逻辑层(如 Service 层)的方法进行处理,然后返回一个 ModelAndView 对象,其中包含了处理结果数据(Model)和逻辑视图名(View)。
    • 工作原理:开发人员通过编写控制器类和方法来实现具体的业务逻辑。例如,一个处理用户登录的控制器方法会接收用户名和密码参数,调用用户服务进行验证,然后根据验证结果返回相应的视图和数据。
  10. 处理器适配器(HandlerAdapter)

    • 功能:由于处理器(Handler)的类型可能多种多样(不同的框架或自定义的处理器类型),HandlerAdapter 的作用是为 DispatcherServlet 提供一种统一的方式来调用不同类型的处理器。它负责适配处理器的调用方式,确保 DispatcherServlet 能够顺利调用处理器并获取处理结果。
    • 工作原理:HandlerAdapter 会检查处理器的类型,然后调用相应的方法来执行处理器。例如,对于基于注解的控制器,它会调用控制器方法并传递请求参数,最后将处理器返回的 ModelAndView 对象传递给 DispatcherServlet。
  11. 视图解析器(View Resolver)

    • 功能:根据处理器返回的逻辑视图名,解析出实际的视图对象(如 JSP 视图、Thymeleaf 视图等),并将模型数据填充到视图中,最终生成可供客户端显示的响应内容。
    • 工作原理:常见的视图解析器如 InternalResourceViewResolver,它会根据配置的前缀和后缀,将逻辑视图名转换为实际的视图资源路径。例如,逻辑视图名 "userList",在配置了前缀 "/WEB-INF/views/" 和后缀 ".jsp" 的情况下,会被解析为 "/WEB-INF/views/userList.jsp",然后创建相应的视图对象并返回。
  12. 视图(View)

    • 功能:负责将模型数据渲染成最终的响应结果,如生成 HTML 页面、JSON 数据、XML 数据等,然后将其返回给客户端进行显示。
    • 工作原理:不同类型的视图(如 JSP 视图会使用 Java 代码和 HTML 标签结合的方式,Thymeleaf 视图使用模板引擎语法)根据模型数据和自身的渲染规则生成响应内容。例如,JSP 视图会将模型中的数据插入到 HTML 页面的相应位置,生成完整的 HTML 页面返回给客户端。

SpringMVC返回值

返回 String 类型

  • 作为视图名称 :当返回值为 String 类型时,Spring MVC 通常会将其视为视图名称,结合视图解析器(如 InternalResourceViewResolver)来定位实际的视图资源。
  • 重定向和转发 :可以在返回的 String 中使用特殊前缀来实现重定向或转发。

重定向和转发

@GetMapping("/forward2")
public String forward2() {
    System.out.println("-------forward2-------");
    return "forward:/test/responseEntityTest";
}

@GetMapping("/redirect2")
public String redirect2() {
    System.out.println("-------redirect2-------");
    return "redirect:/test/responseEntityTest";
}

返回 ModelAndView 类型

ModelAndView 可以同时包含视图名称和要传递给视图的数据,使用它能更灵活地设置视图和数据。

java 复制代码
@Controller
public class ModelAndViewController {

    @RequestMapping("/modelAndViewTest")
    public ModelAndView modelAndViewTest() {
        ModelAndView modelAndView = new ModelAndView();
        // 设置视图名称
        modelAndView.setViewName("result"); 
        // 添加数据到模型
        modelAndView.addObject("message", "这是通过 ModelAndView 传递的消息"); 
        return modelAndView;
    }
}

返回 void 类型

java 复制代码
@Controller
public class VoidReturnController {

    @RequestMapping("/voidTest")
    public void voidTest() {
        // 处理逻辑
    }
}

当控制器方法返回 void 时,Spring MVC 会根据请求的 URL 自动推断视图名称。若请求的 URL 为 /voidTest,Spring MVC 会尝试将视图名称解析为 voidTest,再结合视图解析器定位实际的视图资源。

返回 @ResponseBody 修饰的对象

当控制器方法使用 @ResponseBody 注解时,返回的对象会被转换为特定格式的数据(通常是 JSON 或 XML)作为 HTTP 响应体返回给客户端。

形式如下,@RestController = @Controller + @ResponseBody

返回 ResponseEntity 类型

ResponseEntity 可用于更精细地控制 HTTP 响应,包括设置响应状态码、响应头和响应体。

@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping("/responseEntityTest")
    public ResponseEntity<Map<String, String>> responseEntityTest() {
        Map<String, String> data = new HashMap<>();
        data.put("message", "这是通过 ResponseEntity 返回的消息");
        // 创建 ResponseEntity 对象,设置响应状态码为 200 OK
        return new ResponseEntity<>(data, HttpStatus.OK);
    }
}

SpringMVC注解解析

@RequestMapping

RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

RequestMapping注解可以作用在方法和类上

  1. 作用在类上:第一级的访问目录
  2. 作用在方法上:第二级的访问目录
  3. 细节:路径可以不编写 / 表示应用的根目录开始

RequestMapping的属性

  1. path 指定请求路径的url
  2. value value属性和path属性是一样的
  3. mthod 指定该方法的请求方式
  4. params 指定限制请求参数的条件

示例:

@Controller
@RequestMapping(path = "/role")        // 一级请求路径
public class RoleController {

    /**
     * /role/save.do
     * method="当前方法允许请求方式能访问"
     * params="请求路径上传参数"
     * @return
     */
    @RequestMapping(path = "/save.do",method = {RequestMethod.GET},params = "username")
    public String save(){
        System.out.println("保存角色...");
        return "suc";
    }

    @RequestMapping(value = "/delete.do")
    public String delete(){
        System.out.println("删除角色...");
        return "suc";
    }

}

@ResponseBody

@ResponseBody 是 Spring MVC 框架中的一个重要注解,主要用于将控制器方法返回的对象直接写入 HTTP 响应体中,而不是将其解析为视图名称来渲染视图。

  • 将对象转换为 JSON 或 XML

    java 复制代码
    @RestController // 相当于 @Controller + @ResponseBody
    @RequestMapping("/api")
    public class DataController {
    
        @GetMapping("/data")
        public Map<String, String> getData() {
            Map<String, String> data = new HashMap<>();
            data.put("name", "John");
            data.put("age", "30");
            return data;
        }
    }

    在上述代码中,getData 方法返回一个 Map 对象,由于使用了 @RestController(包含 @ResponseBody),Spring MVC 会将 Map 对象转换为 JSON 格式的字符串作为 HTTP 响应体返回给客户端

    {

    "name": "John",

    "age": "30"

    }

  • 返回字符串 :如果返回的是字符串,@ResponseBody 会直接将该字符串作为响应体返回,而不会去查找视图。

@RequestBody

@RequestBody 注解用于指示 Spring MVC 框架将 HTTP 请求体中的内容直接绑定到方法的参数上。它会根据请求的 Content-Type 自动选择合适的消息转换器来将请求体中的数据反序列化为 Java 对象。常见的 Content-Type 包括 application/jsonapplication/xml 等。

总之,@RequestBody 注解在 Spring MVC 中用于处理 HTTP 请求体中的数据,通过合适的消息转换器将数据反序列化为 Java 对象,方便开发者进行业务处理。

  • 处理 JSON 数据 :当客户端以 JSON 格式发送数据到服务器时,使用 @RequestBody 可以方便地将 JSON 数据转换为 Java 对象。
  • 处理 XML 数据 :类似地,当请求体为 XML 格式时,也可以使用 @RequestBody 将 XML 数据转换为 Java 对象。
  1. 作用:用于获取请求体的内容(注意:get方法不可以)
  2. 属性:required:是否必须有请求体,默认值是true
json 复制代码
public class User {
    private String username;
    private String password;
// 构造函数、toString方法重写,Getter和Setter方法
}
//可以使用 Postman 或其他工具发送一个 POST 请求到 `/users` 接口,请求体为 JSON 格式:
{
    "username": "john_doe",
    "password": "123456"
}
-----------测试-----------
    @PostMapping("/users")
    public String createUser(@RequestBody User user) {
        System.out.println("Received user: " + user);
        return "success";
    }

@PathVariable

@PathVariable ,这是 Spring MVC 中一个非常实用的注解,用于从 URL 的路径部分中提取变量值,并将其绑定到控制器方法的参数上。

  1. 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

  2. 属性:value:指定url中的占位符名称

  3. Restful风格的URL

    1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
    2. restful风格的URL优点
      1. 结构清晰
      2. 符合标准
      3. 易于理解
      4. 扩展方便

    @GetMapping("/articles/{year}/{month}/{articleId}")
    public String getArticle(@PathVariable("year") int year,
    @PathVariable("month") int month,
    @PathVariable("articleId") String articleId) {
    System.out.println(year+""+month+""+articleId);
    return "suceess";
    }
    //请求url:http://localhost:8080/s1/rp/articles/2024/03/abc

@RequestHeader

在 Spring MVC 中,@RequestHeader 注解用于将 HTTP 请求头中的值绑定到控制器方法的参数上。它允许你从请求头中提取特定的信息,如 User - AgentContent - Type、自定义请求头等,并将其作为方法参数传递,以便在方法内部进行处理。

注解属性

  • namevalue:指定要获取的请求头的名称。

  • required :表示该请求头是否为必需项,默认值为 true。如果设置为 true,而请求中没有该请求头,会抛出 HttpMessageNotReadableException 异常;若设置为 false,当请求中不存在该请求头时,参数会被赋值为 null

  • defaultValue:当请求中不存在指定的请求头时,使用该默认值。

    @GetMapping("/getUserAgent")
    public String getUserAgent(@RequestHeader("User-Agent") String userAgent) {
    System.out.println(userAgent);
    return "suceess";
    }

    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0

@CookieValue

在 Spring MVC 里,`` 注解的主要作用是把 HTTP 请求中的 Cookie 值绑定到控制器方法的参数上。借助这个注解,你能够方便地从请求的 Cookie 里提取特定 Cookie 的值,进而在控制器方法里使用这些值开展业务逻辑处理。

注解属性

  • namevalue:此属性用于指定要获取的 Cookie 的名称。

  • required :它是一个布尔类型的属性,默认值为 true。当设置为 true 时,意味着请求中必须包含指定名称的 Cookie,若不包含,就会抛出 HttpStatus 400 Bad Request 异常;当设置为 false 时,请求中可以不包含该 Cookie。

  • defaultValue :当 required 设置为 false 且请求中不存在指定名称的 Cookie 时,会使用该默认值来给方法参数赋值。

    @GetMapping("/getSessionId")
    public String getSessionId(@CookieValue(name = "sessionId",defaultValue = "hhhh") String sessionId) {
    System.out.println(sessionId);
    return "suceess";
    }

请求参数绑定

基于 URL 查询参数的绑定

当 HTTP 请求的 URL 中包含查询参数时,Spring MVC 可以自动将这些参数绑定到控制器方法的同名参数上。

可以通过设置 @RequestParamrequired 属性为 false 来指定参数为可选的,并使用 defaultValue 属性设置默认值。

@GetMapping("/user")
public String getUser(@RequestParam String name, @RequestParam int age) {
    System.out.println(name+""+age);
    return "suceess";
}
//请求url:http://localhost:8080/s1/rp/user?name=luxiya&age=19

基于表单参数的绑定

当客户端通过表单提交数据时,Spring MVC 可以将表单数据绑定到一个 Java 实体类上。

@RequestMapping("/save4.do")
public String save4(User user){
    System.out.println("user对象:"+user);
    return "suceess";
}
------前端----------
<form action="/s1/rp/save4.do" method="post">
    姓名:<input type="text" name="username" /><br/>
    年龄:<input type="text" name="age" /><br/>
    金额:<input type="text" name="address.money" /><br/>
    集合:<input type="text" name="list[0].money" /><br/>
    集合:<input type="text" name="list[1].money" /><br/>
    <input type="submit" value="提交" />
</form>

当客户端通过表单提交 nameage 字段时,Spring MVC 会自动将这些字段的值绑定到 User 对象的相应属性上。

基于请求体的绑定@RequestBody(和表单绑定的区别)

使用 @RequestBody 注解可以将 HTTP 请求体中的数据绑定到控制器方法的参数上,常用于处理 JSON 或 XML 格式的数据。

区别

@RequestBody基于请求体的绑定

  • 适用于处理复杂的数据结构,特别是需要传递大量数据或嵌套数据的场景。JSON 和 XML 等格式可以很好地表示复杂的对象层次结构,因此使用 @RequestBody 可以方便地处理这些数据。
  • 常用于前后端分离的项目中,前端使用 JavaScript 发送 AJAX 请求,将数据以 JSON 格式封装在请求体中发送给后端。
  • 此方法使用了 @RequestBody 注解,这表明它期望从 HTTP 请求体中获取数据。通常,请求体的数据格式可以是 JSON、XML 等。
  • 将请求体中的数据反序列化为 JAVA 对象。
  • 由于依赖请求体中的数据,需要正确设置请求头的 Content - Type。如果请求体是 JSON 格式,Content - Type 应该设置为 application/json;如果是 XML 格式,Content - Type 应该设置为 application/xml。如果 Content - Type 设置不正确,Spring MVC 可能无法找到合适的消息转换器来处理请求体数据,从而抛出异常。

无@RequestBody表单绑定

  • 适用于简单的表单提交场景,例如传统的 HTML 表单提交。用户在表单中填写数据,点击提交按钮后,表单数据会以表单编码的形式发送到服务器。
  • 对于一些简单的业务逻辑,使用表单数据或查询参数进行数据传递更加方便和直观。
  • 没有使用 @RequestBody 注解,Spring MVC 默认会从请求的表单数据或 URL 查询参数中获取数据。

基于路径变量/请求头/Cookie的绑定

就是上文@PathVariable,@RequestHeader,@CookieValue的使用。

使用 @PathVariable 注解可以将 URL 路径中的变量绑定到控制器方法的参数上,常用于 RESTful API 设计。

使用 @RequestHeader 注解可以将 HTTP 请求头中的值绑定到控制器方法的参数上。

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

SpringMVC异常处理

异常处理思路

Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。

核心接口为HandlerExceptionResolver。其核心价值在于:

  1. 统一管理 :避免分散的try-catch代码,集中处理控制器层异常。
  2. 解耦业务逻辑:将错误处理从业务代码中剥离,提升代码可读性。
  3. 灵活响应:支持动态返回JSON、HTML页面或自定义协议数据。

HandlerExceptionResolver

HandlerExceptionResolver 是 SpringMVC 提供的一个接口,用于自定义异常处理逻辑。可以实现该接口,并将其注册到 SpringMVC 中,以处理异常。

执行流程:

  1. DispatcherServlet 捕获到异常后,会依次调用已注册的 HandlerExceptionResolver 实现类的 resolveException 方法,尝试处理异常。

  2. 如果某个 HandlerExceptionResolver 成功处理了异常,返回一个非 nullModelAndView 对象,DispatcherServlet 会使用该 ModelAndView 进行视图渲染;如果所有的 HandlerExceptionResolver 都无法处理异常,DispatcherServlet 会将异常继续抛出。

    -----------------自定义异常类--------------
    public class SysException extends Exception{
    // 提示消息
    private String message;
    @Override
    public String getMessage() {
    return message;
    }
    public void setMessage(String message) {
    this.message = message;
    }
    public SysException(String message) {
    this.message = message;
    }
    }
    -------------注册异常处理器-----------
    @Component
    public class SysExceptionResolver implements HandlerExceptionResolver {
    /**
    * 程序出现了异常,调用异常处理器中的方法
    * @param o
    * @param e
    * @return
    */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
    // 在控制台打印异常的信息
    e.printStackTrace();
    // 做强转
    SysException exception = null;
    // 判断
    if(e instanceof SysException){
    exception = (SysException)e;
    }else{
    exception = new SysException("系统正在维护,请联系管理员");
    }
    // 存入异常提示信息
    ModelAndView mv = new ModelAndView();
    mv.addObject("errorMsg",e.getMessage());
    // 设置跳转的页面
    mv.setViewName("error");
    return mv;
    }
    }
    --------------测试方法-----------
    @Controller
    @RequestMapping("/error")
    public class ErrorController {
    @RequestMapping("/test")
    public String test() {
    int i = 1 / 0;
    return "success";
    }
    }
    ---------error.jsp页面----------
    <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

    <html> <head> <title>错误提示页面</title> </head> <body>

    错误的友好提示页面

    ${errorMsg} </body> </html>

SimpleMappingExceptionResolver

SimpleMappingExceptionResolver 的核心原理是通过配置异常类与视图名称之间的映射关系,当控制器方法抛出异常时,它会根据异常类型查找对应的视图名称,并将请求转发到该视图页面进行错误信息的展示。

在 Spring MVC 的 XML 配置文件中,可以通过以下方式配置 SimpleMappingExceptionResolver

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 定义异常类与视图名称的映射 -->
    <property name="exceptionMappings">
        <props>
            <!-- 当抛出 java.lang.Exception 异常时,跳转到 error 视图 -->
            <prop key="java.lang.Exception">error</prop> 
            <!-- 当抛出 java.lang.RuntimeException 异常时,跳转到 runtimeError 视图 -->
            <prop key="java.lang.RuntimeException">runtimeError</prop> 
        </props>
    </property>
    <!-- 默认的错误视图名称,当没有匹配的异常映射时使用 -->
    <property name="defaultErrorView" value="defaultError"/> 
    <!-- 异常属性名,将异常对象存储在请求域中,可在视图中通过该属性名获取异常信息 -->
    <property name="exceptionAttribute" value="ex"/> 
</bean>

@ExceptionHandler

@ExceptionHandler注解用于处理控制器方法中抛出的特定异常。可以在控制器类中定义一个方法,并使用该注解来捕获和处理指定类型的异常。

@Controller
@RequestMapping("/error")
public class ErrorController {
    @RequestMapping("/test")
    public String test() {
        int i = 1 / 0;
        return "success";
    }
    @ExceptionHandler(Exception.class)
    public ModelAndView error(Exception e) {
        e.printStackTrace();
        System.out.println("error----ExceptionHandler");

        // 创建 ModelAndView 对象
        ModelAndView modelAndView = new ModelAndView();
        // 设置要跳转的视图名称
        modelAndView.setViewName("error");
        // 添加异常信息到模型中,键名为 errorMsg
        modelAndView.addObject("errorMsg", e.getMessage());
        return modelAndView;
    }
}

@ControllerAdvice

@ControllerAdvice 注解用于定义全局异常处理器,它可以处理所有控制器中抛出的异常。结合 @ExceptionHandler 注解,可以实现统一的异常处理逻辑。

@ControllerAdvice
public class GlobalExceptionHandler {

    // 处理所有类型的异常
    @ExceptionHandler(Exception.class)
    public ModelAndView error(Exception e) {
        // 创建 ModelAndView 对象
        ModelAndView modelAndView = new ModelAndView();
        // 设置要跳转的视图名称
        modelAndView.setViewName("error");
        // 添加异常信息到模型中,键名为 errorMsg
        modelAndView.addObject("errorMsg", e.getMessage());
        return modelAndView;
    }
}

SpringMVC框架中的拦截器

拦截器的概述

  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。

  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。

  3. 拦截器和过滤器的功能比较类似,有区别

    1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
    2. 拦截器是SpringMVC框架独有的。
    3. 过滤器配置了/*,可以拦截任何资源。
    4. 拦截器只会对控制器中的方法进行拦截。
  4. 拦截器也是AOP思想的一种实现方式

  5. 想要自定义拦截器,需要实现HandlerInterceptor接口。

    /**

    • 测试拦截器
    • @return
      */
      @RequestMapping("/test2")
      public String test2() {
      System.out.println("controller 执行了");
      return "suceess";
      }
      ------springMVC的xml文件配置
      mvc:interceptors

      mvc:interceptor

      <mvc:mapping path="/error/**"/>
             <!--拦截器器对象-->
             <bean class="com.luxiya.study_01.controller.MyInterceptor"/>
         </mvc:interceptor>
     </mvc:interceptors>
    

配置多个拦截器

再定义一个拦截器MyInterceptor2。

当配置了多个拦截器时,它们的执行顺序遵循以下规则:

  • preHandle 方法:按照拦截器注册的顺序依次执行。

  • postHandle 方法:按照拦截器注册顺序的逆序执行。

  • afterCompletion 方法:按照拦截器注册顺序的逆序执行。

      <mvc:interceptors>
          <!--配置拦截器-->
          <mvc:interceptor>
              <!--哪些资源需要拦截-->
              <mvc:mapping path="/error/**"/>
              <!--哪些资源不想拦截-->
    
              <!--拦截器器对象-->
              <bean class="com.luxiya.study_01.controller.MyInterceptor"/>
          </mvc:interceptor>
          <mvc:interceptor>
              <mvc:mapping path="/error/**"/>
              <bean class="com.luxiya.study_01.controller.MyInterceptor2"/>
          </mvc:interceptor>
      </mvc:interceptors>
    

拦截器与过滤器的区别

  • 使用范围:过滤器是 Servlet 规范中的一部分,适用于所有的 Web 应用;而拦截器是 SpringMVC 框架中的一部分,仅适用于 SpringMVC 应用。
  • 拦截范围 :过滤器可以拦截所有的请求,包括静态资源请求;而拦截器只能拦截 SpringMVC 处理的请求,即通过 DispatcherServlet 处理的请求。
  • 实现机制:过滤器基于函数回调实现,而拦截器基于 Java 的反射机制实现。
  • 拦截器的功能更为强大,它可以访问 Spring 容器中的 Bean,而过滤器无法直接访问 Spring 容器。

配置文件

概述

  • <mvc:annotation-driven/> :开启 Spring MVC 的注解支持,使得可以使用 @Controller@RequestMapping 等注解。

  • <context:component-scan> :指定 Spring 扫描组件的基础包,Spring 会自动扫描该包及其子包下带有 @Controller@Service 等注解的类,并将其注册为 Spring Bean。

  • InternalResourceViewResolver :配置视图解析器,用于将控制器返回的视图名称解析为实际的视图资源。prefixsuffix 分别指定视图文件的前缀和后缀。

  • <mvc:resources>:配置静态资源处理,指定静态资源的映射路径和实际存储位置。

  • <mvc:interceptors> :配置拦截器,mvc:mapping 指定拦截的路径,mvc:exclude-mapping 指定排除的路径,bean 指定拦截器的实现类。

    <?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:mvc="http://www.springframework.org/schema/mvc" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.luxiya.study_01.controller"/>

    mvc:annotation-driven/

      <!--配置视图解析器-->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="prefix" value="/WEB-INF/pages/"/>
          <property name="suffix" value=".jsp"/>
      </bean>
    
      <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
          <property name="exceptionMappings">
              <props>
                  <prop key="java.lang.ArithmeticException">error</prop>
    
              </props>
          </property>
      </bean>
      <mvc:interceptors>
          <!--配置拦截器-->
          <mvc:interceptor>
              <!--哪些资源需要拦截-->
              <mvc:mapping path="/error/**"/>
              <!--哪些资源不想拦截-->
    
              <!--拦截器器对象-->
              <bean class="com.luxiya.study_01.controller.MyInterceptor"/>
          </mvc:interceptor>
          <mvc:interceptor>
              <mvc:mapping path="/error/**"/>
              <bean class="com.luxiya.study_01.controller.MyInterceptor2"/>
          </mvc:interceptor>
      </mvc:interceptors>
    
    </beans>

静态资源处理

DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

标签配置不过滤

  1. location元素表示webapp目录下的包下的所有文件

  2. mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b

     <!-- 设置静态资源不过滤 -->
     <mvc:resources location="/css/" mapping="/css/**"/>  <!-- 样式 -->
     <mvc:resources location="/images/" mapping="/images/**"/>  <!-- 图片 -->
     <mvc:resources location="/js/" mapping="/js/**"/>  <!-- javascript -->
    
相关推荐
Matrix706 分钟前
Flink-学习路线
大数据·学习·flink
大G哥9 分钟前
Spring Boot 与 Spring MVC 有何不同
java·spring boot·后端·spring·mvc
JavinLu10 分钟前
idea超级AI插件,让 AI 为 Java 工程师
java·前端·intellij-idea
考虑考虑20 分钟前
JDK14中的switch
java·后端·java ee
昊坤说不出的梦28 分钟前
【微服务】Nacos 配置动态刷新(简易版)(附配置)
java·spring boot·微服务
为几何欢33 分钟前
【学习笔记】《逆向工程核心原理》03.abex‘crackme-2、函数的调用约定、视频讲座-Tut.ReverseMe1
笔记·学习·逆向·crackme·逆向工程·vb逆向
啾啾Fun33 分钟前
[微服务设计]1_微服务
java·微服务·微服务设计
阳光九叶草LXGZXJ36 分钟前
达梦数据库-学习-10-SQL 注入 HINT 规则(固定执行计划)
linux·运维·数据库·sql·学习
云上艺旅40 分钟前
K8S学习之基础二十二:k8s的持久化存储之hostPath
学习·云原生·容器·kubernetes
为什么不问问神奇的海螺呢丶43 分钟前
Kubernetes 中 YAML 文件详解
java·容器·kubernetes