SpringMVC——自定义异常处理并反馈错误信息

先导Spring的各种基本依赖,这里就不再说明

一、使用@ControllerAdvice和@ExceptionHandler注解的方式

1、自定义的异常类

package com.json.exception;

public class BookException extends RuntimeException {
    public BookException() {
    }

    public BookException(String message) {
        super(message);
    }

    public BookException(String message, Throwable cause) {
        super(message, cause);
    }

    public BookException(Throwable cause) {
        super(cause);
    }

    public BookException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

2、通过@ControllerAdvice和@ExceptionHandler来配置异常处理

注意@ControllerAdvice注解一定要在<context:component-scan>中扫描到

package com.json.exception;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.Map;

/*@ControllerAdvice会被<context:component-scan>扫描;该类使用@ExceptionHandler注解修饰的方法将
会应用到所有请求处理方法上*/
@ControllerAdvice
public class GlobalExceptionHandler {
    //处理Exception类型异常
    @ExceptionHandler(value = Exception.class)
    public ModelAndView globalErrorHandler(Exception e) throws Exception{
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex",e);
        mv.setViewName("error");
        return mv;
    }

    //处理OrderException类型异常
    @ResponseBody
    @ExceptionHandler(value = BookException.class)
    public Object bookErrorHandler(Exception e) throws Exception{
        //创建返回对象map并设置属性,其会被@ResponseBody注解转换为json返回
        Map<String,Object> map = new HashMap<>();
        map.put("code",100);
        map.put("message",e.getMessage());
        map.put("data","请求失败");
        return map;
    }
}

3、测试的controller

package com.json.controller;

import com.json.exception.BookException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 测试springmvc的自定义返回异常并返回页面
 */
@Controller
public class ExceptionController {
    @RequestMapping("find")
    public String find(String name){
        if (name == null){
            throw new NullPointerException("用户名不存在");
        }
        return "success";
    }

    @RequestMapping("delete")
    public String delete(){
        try {
            int x = 5/0;
            return "success";
        }catch (Exception e){
            e.printStackTrace();
            throw new BookException("删除图书失败");  //自定义异常处理
        }
    }
}

4、定制jsp进行访问测试

exceptionTest.jsp

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>springmvc异常处理测试</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#delete").click(function () {
                $.post("${pageContext.request.contextPath}/delete",null,
                    function (data) {
                        //处理异常
                        if (data.message){
                            alert("与服务器交互出现异常:"+data.message);
                        }
                        else {
                            //获取服务器响应,处理数据
                        }
                    }
                )
            })
        })
    </script>
</head>
<body>
    <a href="${pageContext.request.contextPath}/find">全局异常处理后放回错误页面</a>
    <button id="delete">点击此按钮,得到自定义异常处理(返回json)</button>
</body>
</html>

error.jsp

<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>异常页面</title>
</head>
<body>
    <h1>异常页面</h1>
    异常信息:${requestScope.ex.message}
</body>
</html>

5、访问exceptionTest.jsp

 得到全局异常后的页面:

 得到自定义异常后的页面:

 二、使用SimpleMappingExceptionResolver实现集成异常处理 

1、在SpringMVC的配置文件l中增加SimpleMappingExceptionResolver配置: 

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
  <!-- 定义默认的异常处理页面,当该异常类型的注册时使用 -->
  <property name="defaultErrorView" value="error"></property> 
  <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
  <property name="exceptionAttribute" value="ex"></property> 
  <!-- 定义需要特殊处理的异常,用全路径类名作为key,异常处理页面名作为值(跳转至页面时会把excepiton带上) -->
  <property name="exceptionMappings"> 
    <props> 
      <prop key="cn.basttg.core.exception.BookException">book-error</prop> 
      <prop key="cn.basttg.core.exception.UserException">user-error</prop> 
  
      <!-- 这里还可以继续扩展对不同异常类型的处理 -->
    </props> 
  </property> 
</bean> 

使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。

三、未捕获异常的处理 

对于Unchecked Exception而言,由于代码不强制捕获,往往被忽略,如果运行期产生了Unchecked Exception,而代码中又没有进行相应的捕获和处理,则我们可能不得不面对尴尬的404、500……等服务器内部错误提示页面。 

我们需要一个全面而有效的异常处理机制。目前大多数服务器也都支持在Web.xml中通过<error-page>(Websphere/Weblogic)或者<error-code>(Tomcat)节点配置特定异常情况的显示页面。修改web.xml文件,增加以下内容:

<!-- 出错页面定义 -->
<error-page> 
  <exception-type>java.lang.Throwable</exception-type> 
  <location>/500.jsp</location> 
</error-page> 
<error-page> 
  <error-code>500</error-code> 
  <location>/500.jsp</location> 
</error-page> 
<error-page> 
  <error-code>404</error-code> 
  <location>/404.jsp</location> 
</error-page> 
  
<!-- 这里可继续增加服务器错误号的处理及对应显示的页面 -->
原文地址:https://www.cnblogs.com/lyh233/p/13991561.html