Springmvc 异常处理

Springmvc 异常处理

1. 异常分类

系统中异常包括两类:编译期异常和运行时异常

  • 编译期异常:继承java.lang.Exception,通过捕获异常(try-catch)从而获取异常信息
  • 运行时异常:继承java.lang.RuntimeException,通过规范代码开发、测试通过手段减少运行时异常的发生

2. SpringMVC的异常处理机制

系统中的三层架构(dao、service、controller)都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图

在这里插入图片描述

3. 异常模拟过程

3.1 maven依赖

<dependencies>
    <!-- spring核心包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springbean包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springcontext包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring表达式包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAOP包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAspects包 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring对web的支持 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springwebMVC -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.18.RELEASE</version>
    </dependency>

    <!-- 配置javaweb环境 -->
    <!-- servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- jackson -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.5</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.5</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.5</version>
    </dependency>
</dependencies>

3.2 SpringMVC配置

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.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>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 通过隐藏域传参解决form表单的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>

    <!-- 解决put请求传递参数的问题-->
    <filter>
        <filter-name>HttpPutFormContentFilter</filter-name>
        <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HttpPutFormContentFilter</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.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>/views/index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

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

    <!-- springmvc的注解式开发 -->
    <!-- 开启组件扫描 -->
    <context:component-scan base-package="com.newcapec"/>

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

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置视图地址的前缀和后缀:简化视图地址 -->
        <property name="prefix" value="/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--不拦截静态资源-->
    <mvc:default-servlet-handler/>
</beans>

3.3 自定义异常类

BusinessExeption.java

public class BusinessExeption extends Exception {
    public BusinessExeption(){
        super("商务异常");
    }
}

CustomException.java

public class CustomException extends Exception  {
    public CustomException(){
        super("客户异常");
    }
}

3.4 dao

接口

public interface DemoDao {
    void insert(String name) throws Exception;
}

实现类

@Repository("demoDao")
public class DemoDaoImpl implements DemoDao {
    @Override
    public void insert(String name) throws Exception {
        System.out.println("dao执行了..." + name);
        //模拟异常
        if("null".equals(name)){
            System.out.println("空指针异常出现...");
            String s = null;
            s.trim();
        }else if("business".equals(name)){
            System.out.println("商务异常出现...");
            throw new BusinessExeption();
        }else if("custom".equals(name)){
            System.out.println("客户异常出现...");
            throw new CustomException();
        }else{
            System.out.println("未出现异常,程序正常...");
        }
    }
}

3.5 service

接口

public interface DemoService {
    void add(String name) throws Exception;
}

实现类

@Service("demoService")
public class DemoServiceImpl implements DemoService {

    @Autowired
    private DemoDao demoDao;

    @Override
    public void add(String name) throws Exception {
        System.out.println("service执行了...");
        demoDao.insert(name);
    }
}

3.6 controller

@Controller
@RequestMapping("/demo")
public class DemoController {

    @Autowired
    private DemoService demoService;

    @RequestMapping("/add")
    public String add(String name) throws Exception {
        System.out.println("controller执行了...");
        //在controller中调用业务逻辑层
        demoService.add(name);
        return "success";
    }
}

3.7 页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <h1>异常处理</h1>
        <form action="demo/add" method="post">
            <p>数据:<input type="text" name="name"></p>
            <p><button>提交</button></p>
        </form>
    </div>
</body>
</html>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>跳转成功!!!</h1>
    </div>
</body>
</html>

4. SpringMVC的异常处理

4.1 自带异常处理器

使用springmvc提供的简单异常处理器SimpleMappingExceptionResolver,在springmvc.xml配置如下:

<!-- 配置全局异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 配置默认的异常处理页面,value属性配置为一个逻辑视图名 -->
    <property name="defaultErrorView" value="error"/>
    <!-- 配置在异常页面中获取异常对象 -->
    <property name="exceptionAttribute" value="ex"/>
    <!-- 单独处理某些特殊异常 -->
    <property name="exceptionMappings">
        <props>
            <!-- key为单独处理异常的全限定名,value为单独处理异常之后的跳转页面 -->
            <prop key="com.newcapec.myexception.BusinessExeption">error_bus</prop>
            <prop key="com.newcapec.myexception.CustomException">error_cust</prop>
        </props>
    </property>
</bean>

异常跳转页面如下:

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <h1 style="color: red;">系统故障,请联系管理员!</h1>
        <p>异常信息:${ex}</p>
        <p>自定义信息:${msg}</p>
    </div>
</body>
</html>

error_bus.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>商务异常出现后的跳转页面</h1>
        <p>异常信息:${ex}</p>
        <p>自定义信息:${msg}</p>
    </div>
</body>
</html>

error_cust.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>客户异常出现后的跳转页面</h1>
        <p>异常信息:${ex}</p>
        <p>自定义信息:${msg}</p>
    </div>
</body>
</html>

4.2 自定义异常处理器

实现SpringMVC的异常处理接口HandlerExceptionResolver定义自己的异常处理器,代码如下:

/**
 * 自定义全局异常处理器
 * 1.实现HandlerExceptionResolver接口并实现其中抽象方法
 * 2.将异常处理器对象放入ioc容器中
 */
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    /**
     * 处理异常的方法
     * @param request 请求对象
     * @param response 响应对象
     * @param handler 处理器对象
     * @param ex 抛出的异常对象
     * @return ModelAndView对象
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                         Object handler, Exception ex) {
        ModelAndView mav = new ModelAndView();
        // 根据不同异常向不同的页面跳转
        if(ex instanceof BusinessExeption){
            request.setAttribute("msg", "message for business exception");
            mav.setViewName("error_bus");
        }else if(ex instanceof CustomException){
            request.setAttribute("msg", "message for custom exception");
            mav.setViewName("error_cust");
        }else {
            request.setAttribute("msg", "message for other exception");
            mav.setViewName("error");
        }
        return mav;
    }
}

4.3 注解式异常处理器

4.3.1 局部异常处理

在Controller中使用@ExceptionHandler注解实现异常处理

@Controller
@RequestMapping("/other")
public class OtherController {

    @RequestMapping("/add")
    public String add() throws Exception {
        System.out.println("其他处理器中的异常...");
        //模拟异常
        Class.forName("abc");
        return "success";
    }

    /**
     * 在Controller中定义一个处理异常的方法
     * 方法的如果是String类型,表示异常跳转的路径视图名
     *
     * @ExceptionHandler
     * 位置:方法
     * 作用:使当前方法可处理异常
     * 属性:value = 当前方法将要处理异常的类型(异常的Class类型)
     *
     * 注意:如果@ExceptionHandler使用在某个Controller,那么它只能处理该Controller抛出的异常
     */
    @ExceptionHandler(Exception.class)
    public String handleException(Model model){
        model.addAttribute("msg", "注解式异常处理");
        return "error";
    }
}

注意:进行异常处理的方法必须与抛出异常的方法在同一个Controller里面,不能全局控制异常

4.3.2 全局异常处理

使用@ControllerAdvice + @ExceptionHandler注解实现全局异常处理

/**
 * @ControllerAdvice
 * 位置:类
 * 作用:注解式全局异常处理器
 */
@ControllerAdvice
public class MyControllerAdvice {
    @ExceptionHandler(BusinesException.class)
    public String handleBusinesException(Model model){
        model.addAttribute("msg", "注解式异常处理的商务异常");
        return "error_bus";
    }
    @ExceptionHandler(CustomException.class)
    public String handleCustomException(Model model){
        model.addAttribute("msg", "注解式异常处理的客户异常");
        return "error_cust";
    }

    @ExceptionHandler(Exception.class)
    public String handleException(Model model){
        model.addAttribute("msg", "注解式异常处理的其他异常");
        return "error";
    }
}
4.3.3 异步异常处理

在异常处理的方法中,使用@ResponseBody注解响应客户端即可

Controller中的方法:

@ResponseBody
@RequestMapping("/get")
public String get(String id) throws Exception {
    System.out.println("处理异步请求的方法执行了...");
    //模拟异常
    int i = Integer.parseInt(id);
    System.out.println("编号:" + i);
    return "success";
}

处理异常的方法:

/**
 * 处理异步请求中出现的异常
 */
@ResponseBody
@ExceptionHandler(value = NumberFormatException.class)
public String handleAsyncException(){
    return "error";
}

页面中的异步请求:

<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    function get() {
        $.ajax({
            url : "demo/get",
            type : "get",
            data : {id : "10"},
            success : function (data) {
                alert(data);
            }
        });
    }
</script>

<p><a href="javascript:get()">异步请求</a></p>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring MVC中,可以通过以下几种方式来处理异常: 1. 使用@ControllerAdvice注解和@ExceptionHandler注解: - 首先,创建一个全局的异常处理类,使用@ControllerAdvice注解标注,并在类中定义一个或多个带有@ExceptionHandler注解的方法,用于处理特定的异常类型。 - 在异常处理方法中,可以定义需要执行的逻辑,例如记录日志、返回自定义错误信息等。 - 这种方式可以捕获并处理控制器中抛出的异常,提供统一的异常处理机制。 2. 使用@ExceptionHandler注解: - 在控制器类中,可以使用@ExceptionHandler注解标注方法,用于处理特定的异常类型。 - 这种方式适合处理控制器中的异常,可以针对不同的异常类型定义不同的处理逻辑。 3. 使用HandlerExceptionResolver接口: - 可以实现HandlerExceptionResolver接口,并注册为Spring的bean。 - 通过实现该接口的resolveException方法,可以自定义异常处理逻辑。 - 这种方式可以自定义异常处理的策略,例如根据异常类型、请求路径等进行不同的处理。 4. 使用@ControllerAdvice注解和@ModelAttribute注解: - 在全局异常处理类中,可以使用@ModelAttribute注解定义一个方法,用于在异常处理方法执行前,向模型中添加一些通用的属性。 - 这种方式适合在异常处理前,向模型中添加一些额外的信息,以便在异常处理方法中使用。 以上是几种常见的Spring MVC异常处理方式,根据具体的需求和场景,选择适合的方式进行异常处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JTZ001

你的鼓励是我创作的最大动力?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值