文件上传、拦截器及全局异常处理

发布于:2024-11-29 ⋅ 阅读:(23) ⋅ 点赞:(0)

目录

1.文件上传

1.异步文件上传

【任务1】:实现上传头像的功能。用户选择本地图片,单击上传按钮调用后端接口可以实现将图片保存到文件服务器中,同时在页面中显示上传的图片。

1.1.异步文件上传-简易文件服务器搭建

验证文件服务器的搭建

运行tomcat控制台输出乱码

1.1.异步文件上传-视图设计

 ​编辑

1.3.异步文件上传-解析配置

1.4.异步文件上传-远程调用依赖导入

 1.5. 异步文件上传-后端接口定义

 2.Spring MVC拦截器

综述

拦截器应用场景

拦截器创建

拦截器preHandle方法

拦截器postHandle方法

拦截器afterCompletion方法

运行原理

单个拦截器执行流程

多个拦截器执行流程

拦截器配置

【任务2】:定义拦截器实现登陆验证功能。

视图设计

登录页面

系统首页

控制器设计

UserController

登录拦截器设计

LoginInterceptor

配置拦截器

3.全局异常处理

【任务3】:在SpringMVC项目中定义全局异常处理器实现全局异常处理功能。具体要求如下:当前端调用后端接口出现异常时,

SpringMVC全局异常处理机制

全局异常处理器实现

SpringMVC全局异常处理机制

全局异常处理器实现


1.文件上传

1.异步文件上传

任务1】:实现上传头像的功能。用户选择本地图片,单击上传按钮调用后端接口可以实现将图片保存到文件服务器中,同时在页面中显示上传的图片

实现步骤

1. 使用Tomcat搭建简易文件服务器

2. 当单击上传按钮时,通过fetch发送异步请求调用后端API接口,同时将图片传送到后端。

3. 定义后端接口,接收图片文件内容并将图片存储到文件服务器。

4. 后端接口将服务器图片地址返回给前端进行展示。

1.1.异步文件上传-简易文件服务器搭建

1.在本机另外部署一个tomcat作为文件服务器

2.webapps下新建文件夹uploadfiles,用于存储上传的文件

3.修改conf/server.xml文件,配置文件服务器的端口与上传文件夹的访问

4.修改conf/web.xml,配置文件可读写

验证文件服务器的搭建

启动 tomcat
浏览器访问

运行tomcat控制台输出乱码

1.1.异步文件上传-视图设计

<%--
  Created by IntelliJ IDEA.
  User: flowerfog
  Date: 2024/11/28
  Time: 13:49
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/jquery-3.6.1.js"></script>
</head>
<body>
<form id="fileForm">
    选择文件:<input type="file" id="myFile" />
    <br/><br/>
    文件描述:<input type="text" id="description"/>
    <br/><br/>
    显示上传图片:<img alt="" id="img" src="">
    <br/><br/>
    <input type="button" onclick="ajaxUpload()" value="上传文件"/>
</form>
</body>
<script>
    function ajaxUpload() {
        // 获取表单数据,并添加到FormData中
        let myFile = $("#myFile")[0].files[0];
        let description = $("#description").val();
        let formData = new FormData();
        formData.append("myFile", myFile);
        formData.append("description", description);
        $.ajax({
            url: "${pageContext.request.contextPath}/doRemoteUpload",// 定义请求地址
            type: "post", // 定义请求类型
            data: formData,// 定义请求参数(使用js对象)
            // 告诉jQuery不要去处理发送数据,因已被我们通过FormData处理
            processData: false,
            contentType: false,
            dataType: "json",// 定义服务器响应的数据rData格式为json
            success: function (rData) {
                if (rData.code === 200) {
                    $("#img").attr("src", rData.data);
                }else{
                    alert(rData.message)
                }
            }
        });
    }
</script>
</html>

 

1.3.异步文件上传-解析配置

SpringMVC框架中,如果要使用上传文件解析器,需要在web.xml中配置

<multipart-config>标签。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee">

  <display-name>Archetype Created Web Application</display-name>
  <!-- 配置DispatcherServlet -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 自动加载spring-mvc.xml -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!--当值≥0时,启动时就加载;当值<0或不指定时,则表示第一次请求时加载-->
    <load-on-startup>1</load-on-startup>

    <!--配置上传文件解析-->
    <multipart-config>
      <!--上传文件大小限制,示例:5M-->
      <max-file-size>5242880</max-file-size>
      <!--一次表单提交中文件的大小限制,示例:10M-->
      <max-request-size>10485760</max-request-size>
      <!-- 多大文件会被自动保存到硬盘上。0 代表所有 -->
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
  </servlet>
  <!-- 配置DispatcherServlet接受所有URL请求 -->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 编码过滤器,解决中文乱码问题 -->
  <filter>
    <filter-name>encodingFilter</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>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>


1.4.异步文件上传-远程调用依赖导入

Jersey是一个WebService框架,用于服务器之间的远程调用。是一种跨编程语言和跨操作系统平台的远程调用技术,可用于实现跨服务器的文件上传。使用Jersey框架,需要在项目中引入Jersy依赖。

 

<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
         https://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.flowerfog</groupId>
        <artifactId>SpringMvcDemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>MvcDataInteraction</artifactId>
    <packaging>war</packaging>
    <name>MvcDataInteraction Maven Webapp</name>
    <url>https://maven.apache.org</url>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <org.springframework.version>5.3.29</org.springframework.version>
        <jersey-client.version>1.19.4</jersey-client.version>
    </properties>

    <dependencies>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!-- Spring Web MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!-- Java EE Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- Java EE JSP API -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- Jackson Databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.1</version>
        </dependency>
        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <!--Jersey-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>${jersey-client.version}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>MvcDataInteraction</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 1.5. 异步文件上传-后端接口定义

 

package org.flowerfog.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.UUID;

@Controller
public class UploadController {
    // 打开文件上传页面
    @GetMapping("/upload/index")
    public String index(){
        return "upload/index";
    }
    // 处理文件上传请求
    @PostMapping("/doRemoteUpload")
    @ResponseBody
    public Object doRemoteUpload(MultipartFile myFile,
                                 String description) {
        HashMap<String, Object> ret = new HashMap<>();
        try {
            String path = "http://localhost:8088/uploadfiles/";

            // 为上传到服务器的文件取名,使用UUID防止文件名重复
            String fileName = UUID.randomUUID().toString() + "-" + myFile.getOriginalFilename();
            // 创建Jersey客户端
            Client client = Client.create();
            // 使用客户端完成文件上传
            String filePath = path + "/" + URLEncoder.encode(fileName, StandardCharsets.UTF_8);
            WebResource webResource = client.resource(filePath);
            webResource.put(myFile.getBytes());
            // 返回值
            System.out.println(description);
            ret.put("code", 200);
            ret.put("data", path + fileName);
            ret.put("msg", "success");
        } catch (Exception e) {
            ret.put("code", -1);
            ret.put("data", null);
            ret.put("msg", e.getMessage());
        }
        return ret;
    }
}

 

 2.Spring MVC拦截器

综述

 l拦截器SpringMVC框架中的一种组件,主要用来拦截客户端的请求,在请求的控制器方法前后根据业务执行预先设定的代码,也是AOP(面向切面编程)思想的一种实现方式。

 

拦截器应用场景

登录验证:在用户访问需要登录的页面之前,拦截器可以检查用户是否已经登录,如果没有登录则重定向到登录页面
权限检查:在用户访问需要特定权限的资源之前,拦截器可以检查用户是否具有相应的权限,如果没有则返回无权限的错误信息
日志记录:在前端访问后端每个接口时,拦截器可以记录日志,包括请求的 IP 地址、请求时间、请求的 URL 等信息
数据校验:在请求处理之前,拦截器可以校验请求参数的有效性,如果参数不合法则返回错误信息
统一异常处理:在请求处理出现异常时,拦截器可以统一处理异常信息,避免程序抛出异常页面

 

拦截器创建

在SpringMVC项目中,可以通过实现HandlerInterceptor接口并重写接口中的方法来创建拦截器类。
在HandlerInterceptor接口中有三个方法,分别是preHandle、postHandle和afterCompletion方法。

拦截器preHandle方法

preHandle方法是在控制器目标方法执行之前执行的方法

拦截器postHandle方法

postHandle方法是在控制器目标方法执行之后执行的方法,目标方法内部异常时不执行

 

拦截器afterCompletion方法

afterCompletion方法是在给与客户端最终响应之后执行的方法,无论目标方法内部是否异常

运行原理

单个拦截器执行流程

多个拦截器执行流程

多个拦截器同时工作,它们的 preHandle 方法将按照拦截器 顺序执行 ,而它们的 postHandle 方法和 afterCompletion 方法则是 反序执行

拦截器配置

拦截器类创建好之后,还需要通过在SpringMVC配置文件中配置<mvc:interceptors>标签完成拦截器的配置才能生效。
子元素<bean>定义的是全局拦截器,即拦截所有请求
也可以通过<mvc:interceptor>标签定义指定拦截路径的拦截器
子元素<mvc:mapping>标签用于配置拦截器需要拦截的路径
<mvc:exclude-mapping>标签用于配置拦截器不需要拦截,也就是放行的路径。
<mvc:interceptors>标签下可以配置多个<mvc:interceptor>子标签

任务2】:定义拦截器实现登陆验证功能。

l 在用户访问系统资源之前, 拦截器 可以 检查用户是否已经登录
l 如果 未登录 重定向到登录页面
l 如果 已登录 可以访问系统资源

视图设计

登录页面
系统首页

登录页面

<%--
  Created by IntelliJ IDEA.
  User: flowerfog
  Date: 2024/11/28
  Time: 13:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=utf-8"
         pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>login</title>
</head>
<body>

<form action="${pageContext.request.contextPath}/user/login" method="POST">
    用户名: <input type="text" name="account" /><br />
    密 &nbsp;&nbsp;&nbsp;码 :
    <input type="password" name="password" /><br />
    <input type="submit" value="登录" />
    <div style="color: red">${msg}</div>
</form>
</body>
</html>



系统首页

<%--
  Created by IntelliJ IDEA.
  User: flowerfog
  Date: 2024/11/28
  Time: 14:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>main.jsp</title>
</head>
<body>
当前用户: ${loginUser.name}
<a href="${pageContext.request.contextPath}/user/logout">退出</a>
</body>
</html>

 

控制器设计

登录get请求,打开登录页面
登录post请求,验证登录
退出登录get请求,退出登录

 

UserController

package org.flowerfog.controller;


import org.flowerfog.pojo.User;
import org.flowerfog.service.UserService;
import org.flowerfog.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    //1.向页面传值
    //1.1.原生方式,使用方法的参数reques和response进行数据分享和页面跳转
    @GetMapping("/list1")
    public void list1(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        List<UserVo> users = userService.findAll();
        request.setAttribute("userList", users);
        request.getRequestDispatcher("/WEB-INF/views/user/list.jsp").forward(request, response);
    }
    @RequestMapping("/list12")
    public String list12(HttpSession session){
        List<UserVo> users = userService.findAll();
        session.setAttribute("userList", users);
        return "user/list";
    }
    @RequestMapping("/list13")
    public String list13(HttpServletRequest request){
        List<UserVo> users = userService.findAll();
        ServletContext ctx = request.getServletContext();
        ctx.setAttribute("userList", users);
        return "user/list";
    }
    //1.2.使用控制ModelAndView对象进行数据共享和页面的跳转
    @GetMapping("/list2")
    public ModelAndView list2() {
        ModelAndView mv = new ModelAndView();
        List<UserVo> users = userService.findAll();
        mv.addObject("userList", users);
        mv.setViewName("user/list");
        return mv;
    }
    //1.3.使用Model对象,使用返回的字符串控制页面的跳转,可使用试图解析器自动补充前后缀
    @GetMapping("/list3")
    public String list3(Model model){
        List<UserVo> users = userService.findAll();
        model.addAttribute("userList", users);
        return "user/list";
    }
    @GetMapping("/list32")
    public String list32(ModelMap model){
        List<UserVo> users = userService.findAll();
        model.addAttribute("userList", users);
        return "user/list";
    }
    @GetMapping("/list33")
    public String list33(Map<String,Object> map){
        List<UserVo> users = userService.findAll();
        map.put("userList", users);
        return "user/list";
    }
    //1.4.返回值为对象类型,一般返回JSON格式的对象字符串
    //新增Get
    @GetMapping("/add")
    public String add(Model model){
        User user = new User();
        user.setStatus(0);//设置默认值
        model.addAttribute("user", user);
        return "user/edit";
    }
    //修改Get
    @GetMapping("/edit")
    public String edit(Model model,Integer id){
        User user = userService.getById(id);//根据主键获取实体
        model.addAttribute("user", user);
        return "user/edit";
    }
    //新增与修改的Post
    @PostMapping(value="/save")
    @ResponseBody
    public Object save(@RequestBody User user) {
        HashMap<String,Object> ret = new HashMap<>();
        try {
            userService.save(user);
            ret.put("code", 200);
            ret.put("msg", "success");
        } catch (Exception e) {
            ret.put("code", -1);
            ret.put("msg", e.getMessage());
        }
        return ret;
    }
    //删除Get
    @GetMapping("/delete/{id}")
    @ResponseBody
    public Object delete(@PathVariable Integer id){
        HashMap<String,Object> ret = new HashMap<>();
        try {
            userService.deleteById(id);
            ret.put("code", 200);
            ret.put("msg", "success");
        } catch (Exception e) {
            ret.put("code", -1);
            ret.put("msg", e.getMessage());
        }
        return ret;
    }

    // 打开登录页面
    @GetMapping(value = "/login")
    public String toLogin() {
        return "user/login";
    }
    // 登录验证
    @PostMapping(value = "/login")
    public String Login(User user, Model model, HttpSession session) {
        String account = user.getAccount();
        String password = user.getPassword();
        if (account != null && account.equals("admin")
                && password != null && password.equals("123456")) {
            user.setName("管理员");
            session.setAttribute("loginUser", user);
            return "home/index";
        }
        model.addAttribute("msg", "账号密码有误,请重新登录!");
        return "user/login";
    }
    // 退出登录
    @GetMapping(value = "/logout")
    public String Logout(HttpSession session) {
        // 清除登录信息
        session.invalidate();
        return "user/login";
    }
}

 

登录拦截器设计

登录页面放行

其他页面,检查是否已经登录

  已经登录,放行

  否则跳转登录页面

LoginInterceptor

package org.flowerfog.intercptor;


import org.flowerfog.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws ServletException, IOException {
        // 获取请求Url
        String url = request.getRequestURI();
        if (url.contains("/user/login")){
            // 登录页面,放行
            return true;
        }
        // 其他请求,检查用户是否已登录
        HttpSession session = request.getSession();
        User loginUser = (User) session.getAttribute("loginUser");
        if (loginUser == null){
            // 用户已经登录,放行
            return true;
        }
        // 用户未登录,跳转到登录页面
        // request.setAttribute("msg", "请先登录系统");
        request.getRequestDispatcher("/WEN-INF/views/user/login.jsp").forward(request,response);
        return false;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response
            , Object handler, Exception ex)
            throws Exception {
    }
}


配置拦截器

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

    <context:component-scan base-package="org.flowerfog.service"/>
    <context:component-scan base-package="org.flowerfog.controller"/>
    <!-- 开启SpringMVC框架的注解驱动 -->
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--静态资源访问映射路径-->
    <mvc:resources location="/static/" mapping="/static/**"/>
    <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置全局拦截器,拦截所有用户请求-->
        <bean class="org.flowerfog.intercptor.LoginInterceptor"/>
    </mvc:interceptors>
</beans>



3.全局异常处理

      异常可以分为两类:

业务异常 :业务异常是指由应用程序 自身业务逻辑 引发的异常,通常是 预期 的异常情况。这些异常可以 根据具体业务需求 进行分类,例如用户输入验证失败、资源未找到、权限不足等。
系统异常 :系统异常是指由 系统运行环境或外部因素 引发的异常,通常是 非预期 的异常情况。这些异常可能包括数据库连接失败、网络连接异常、服务器内部错误等。

 

异常处理是指对在请求处理过程中可能发生的异常情况进行捕获、处理和响应的机制。

Java中的异常处理主要通过try-catch语句块来实现,但是这样异常处理的代码就与处理业务的代码耦合在一起,不仅有大量的冗余代码,而且还影响代码的可读性。

全局异常处理将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能单一,也实现了异常信息的统一处理和维护

全局异常处理优点:

统一的异常处理逻辑
统一的异常返回格式
提高系统的容错性
异常日志记录和监控

任务3】:在SpringMVC项目中定义全局异常处理器实现全局异常处理功能。具体要求如下:当前端调用后端接口出现异常时,

1)如果是业务异常,则在页面中弹出对话框显示具体的业务异常信息

2)如果是系统异常,则在页面中弹出对话框显示“抱歉,服务器出现了异常,正在加紧修复中

SpringMVC全局异常处理机制

SpringMVC框架是通过HandlerExceptionResolver机制来实现全局异常处理功能的。

HandlerExceptionResolver是一个接口全局异常处理器就是通过实现该接口的resolveException方法实现全局异常处理。

全局异常处理器实现

ExceptionHandlerExceptionResolverSpringMVC中使用最简单、最常用异常处理器之一,可以进行全局异常统一处理

该异常处理器是通过对@ControllerAdvice@ExceptionHandler标注的异常处理方法进行缓存,构筑异常-处理方法的映射。在处理请求时,如果控制器方法中抛出异常到DispatcherServlet

ExceptionHandlerExceptionResolver会根据异常对象找到对应处理方法,进行统一异常处理

SpringMVC全局异常处理机制

全局异常处理器实现

SpringMVC项目中可以通过@ControllerAdvice@ExceptionHandler注解定义全局异常处理组件,实现捕获所有控制器抛出的异常并进行处理。

 

@RestControllerAdvice注解是@ControllerAdvice@ResponseBody的组合注解。

@ExceptionHandler注解中,我们可以使用该注解的value属性指定为不同类型的异常定义不同的异常处理方法

 

需要在SpringMVC配置文件中扫描全局异常处理组件所在的包,将全局异常处理组件注册到Spring容器中,该组件才能起作用。

springmvc.xml中加入如下配置:

至此,项目设计结束。