Spring统一异常处理

Posted 寻找风口的猪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring统一异常处理相关的知识,希望对你有一定的参考价值。

1、为什么要用Spring的统一异常处理?

  项目中无论是controller层、service层还是dao层都会有异常发生。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。所以将异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护

2、Spring统一异常处理的方式有哪些?

  2.1 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver。

  2.2 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器。

  2.3 使用@ExceptionHandler注解实现异常处理

3、做实验

  3.1使用SimpleMappingExceptionResolver

    3.1.1 在spring的配置文件applicationContext.xml文件中配置SimpleMappingExceptionResolver

<!-- springmvc提供的简单异常处理器 -->
    <bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面,这里的error表示的是error.jsp页面-->
        <property name="defaultErrorView" value="error" />
        <!-- 定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception-->
        <property name="exceptionAttribute" value="ex" /> 
        <!-- 定义需要特殊处理的异常,这是重要点 -->
        <property name="exceptionMappings">
            <props>
                <!-- 这里的exception表示的是exception.jsp页面 -->
                <prop key="org.hope.lee.exception.UserException">exception</prop>
                <prop key="org.hope.lee.exception.CustomerException">customerException</prop>
            </props> 
            <!-- 还可以定义其他的自定义异常 -->
        </property>
    </bean>

    3.1.2定义自己的异常

package org.hope.lee.exception;

public class UserException extends Exception{
    
    private static final long serialVersionUID = 1L;
    
    private String errorMsg;

    public UserException(String errorMsg) {
        super();
        this.errorMsg = errorMsg;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
    
}
package org.hope.lee.exception;

public class CustomerException extends RuntimeException{
    private String errorException;

    public CustomerException(String errorException) {
        super();
        this.errorException = errorException;
    }

    public String getErrorException() {
        return errorException;
    }

    public void setErrorException(String errorException) {
        this.errorException = errorException;
    }
    
}

    3.1.3 写几个简单的页面error.jsp exception.jsp customerException.jsp

error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    sorry, your request has some errors
</body>
</html>

exception.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    sorry, your request has ${ex.errorMsg}
</body>
</htm

customerException.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    sorry, your request has customerException:${ex.errorException}
</body>
</html>

    3.1.4 Controller层

package org.hope.lee.controller;

import org.hope.lee.exception.CustomerException;
import org.hope.lee.exception.UserException;
import org.hope.lee.model.User;
import org.hope.lee.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    
    @RequestMapping("/index")
    public String index() {
        return "userDetail";
    }
    
    @RequestMapping("/detail")
    public ModelAndView detail(String id) throws UserException {
        
        if("0".equals(id)) {
            throw new UserException("id不能为0");
        }
        
        if("10".equals(id)) {
            throw new CustomerException("id不能为10");
        }
        
        User user = userService.findUserById(Integer.parseInt(id));
        ModelAndView mv = new ModelAndView();
        mv.addObject("user", user);
        mv.setViewName("success");
        return mv;
    }
}

    3.1.4 进行测试

    ①启动项目

    ②浏览器输入:http://localhost:8088/springmvc-exception/user/detail?id=1(这个是正常时候)

          

    ③浏览器输入:http://localhost:8088/springmvc-exception/user/detail?id=0

          

    ④浏览器输入:http://localhost:8088/springmvc-exception/user/detail?id=10

        

  3.2自定义全局异常处理。

    3.2.1 定义自己的异常处理类实现HandlerExceptionResolver

package org.hope.lee.exception;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * 定义全局异常处理器
 */
public class ExceptionResolver implements HandlerExceptionResolver{

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) {
        ModelAndView mav = new ModelAndView();
        if(ex instanceof UserException) {
            UserException ue = (UserException)ex;
            mav.addObject("ex", ue);
            mav.setViewName("exception");
        } else if(ex instanceof CustomerException) {
            CustomerException ce = (CustomerException)ex;
            mav.addObject("ex", ce);
            mav.setViewName("customerException");
        } else {
            mav.addObject("ex", "未知错误");
            mav.setViewName("error");
        }
        
        
        return mav;
    }

}

     3.2.2 在applicationContext.xml中配置异常处理器

<bean class="org.hope.lee.exception.ExceptionResolver"/>

  3.3 使用@ExceptionHandler

    3.3.1 定义一个BaseController,所有的Controller层都要继承它

package org.hope.lee.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hope.lee.exception.CustomerException;
import org.hope.lee.exception.UserException;
import org.springframework.web.bind.annotation.ExceptionHandler;

public class BaseController {
    
    @ExceptionHandler
    public String exp(HttpServletRequest req, HttpServletResponse resp, Exception ex) {
        req.setAttribute("ex", ex);
        
        if(ex instanceof UserException) {
            return "exception";
        } else if(ex instanceof CustomerException) {
            return "customerException";
        } else {
            return "error";
        }
    }
}

    3.3.2 定义一个Controller,继承BaseController

package org.hope.lee.controller;

import org.hope.lee.service.SellerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SellerController extends BaseController{
    @Autowired
    private SellerService sellerService;
    
    @RequestMapping("/good/update")
    public void updateGood(String id) {
        sellerService.updateGoodsById(Integer.parseInt(id));
    }
}

    3.3.3 测试一下,启动项目在浏览器访问:http://localhost:8088/springmvc-exception/good/update?id=0

    

 https://gitee.com/huayicompany/spring-learn/tree/master/springmvc-exception

参考:

[1] 博客,http://blog.csdn.net/eson_15/article/details/51731567

[2] 博客,http://luanxiyuan.iteye.com/blog/2354081

以上是关于Spring统一异常处理的主要内容,如果未能解决你的问题,请参考以下文章

使用Spring MVC统一异常处理实战

Spring MVC学习—项目统一异常处理机制详解与使用案例

Spring Boot? 统一异常处理

Spring Boot的统一异常处理

Spring中的统一异常处理方式

Spring的@ExceptionHandler和@ControllerAdvice统一处理异常