SpringMVC -- 全局异常处理

SpringMVC – 全局异常处理

前言

开发工程中,分很多环境,对于异常处理,不可暴露同时,如果每个模块都有单独的异常处理,可能会把异常暴露出来,增加耦合性,不好统一管理维护比例比较大。所以需要进行全局的异常处理;


处理办法

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

  • SimpleMappingExceptionResolver。

实现 Spring 的异常处理接口

  • HandlerExceptionResolver 自定义自己的异常处理器。

使用

  • @ExceptionHandler 注解实现异常处理

实践代码


创建一个自定义异常
在这里插入图片描述


public class MyException extends Exception {
    private static final long serialVersionUID = 1L;
    public MyException() {
        super();
    }
    public MyException(String message) {
        super(message);
    }
}

创建 Dao 层开始向上面抛出异常

import java.sql.SQLException;
import org.springframework.stereotype.Repository;
@Repository("TestExceptionDao")
public class TestExceptionDao {


    public void daodb() throws Exception {
        throw new SQLException("Dao中数据库异常");
    }
    public void daomy() throws Exception {
        throw new SQLException("Dao中自定义异常");
    }
    public void daono() throws Exception {
        throw new SQLException("Dao中未知异常");
    }
}

分别向上面抛出了三个异常

Service 层向上抛出异常,三个向上抛出,三个调用dao出现异常向上抛出

接口

public interface TestExceptionService {
    public void servicemy() throws Exception;
    public void servicedb() throws Exception;
    public void daomy() throws Exception;
    public void daodb() throws Exception;
    public void serviceno() throws Exception;
    public void daono() throws Exception;
}

实现

import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import dao.TestExceptionDao;
import exception.MyException;
@Service("testExceptionService")
public class TestExceptionServiceImpl implements TestExceptionService {
    @Autowired
    private TestExceptionDao testExceptionDao;
    @Override
    public void servicemy() throws Exception {
        throw new MyException("Service中自定义异常");
    }
    @Override
    public void servicedb() throws Exception {
        throw new SQLException("Service中数据库异常");
    }
    @Override
    public void daomy() throws Exception {
        testExceptionDao.daomy();
    }
    @Override
    public void daodb() throws Exception {
        testExceptionDao.daodb();
    }
    @Override
    public void serviceno() throws Exception {
        throw new SQLException("Service中未知异常");
    }
    @Override
    public void daono() throws Exception {
        testExceptionDao.daono();
    }

创建控制器

import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import service.TestExceptionService;
import exception.MyException;
@Controller
public class TestExceptionController {
    @Autowired
    private TestExceptionService testExceptionService;
    @RequestMapping("/db")
    public void db() throws Exception {
        throw new SQLException("控制器中数据库异常");
    }
    @RequestMapping("/my")
    public void my() throws Exception {
        throw new MyException("控制器中自定义异常");
    }
    @RequestMapping("/no")
    public void no() throws Exception {
        throw new Exception("控制器中未知异常");
    }
    @RequestMapping("/servicedb")
    public void servicedb() throws Exception {
        testExceptionService.servicedb();
    }
    @RequestMapping("/servicemy")
    public void servicemy() throws Exception {
        testExceptionService.servicemy();
    }
    @RequestMapping("/serviceno")
    public void serviceno() throws Exception {
        testExceptionService.serviceno();
    }
    @RequestMapping("/daodb")
    public void daodb() throws Exception {
        testExceptionService.daodb();
    }
    @RequestMapping("/daomy")
    public void daomy() throws Exception {
        testExceptionService.daomy();
    }
    @RequestMapping("/daono")
    public void daono() throws Exception {
        testExceptionService.daono();
    }
}

控制器异常,service异常,和调用dao,调用service出现的异常


视图显示调用 index首页jsp更改

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!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>
    <h1>所有的演示例子</h1>
    <h3><a href="${pageContext.request.contextPath }/daodb"> 处理dao中数据库异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/daomy"> 处理dao中自定义异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/daono"> 处理dao未知错误 </a></h3>
    <hr>
    <h3><a href="${pageContext.request.contextPath }/servicedb">处理 service中数据库异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/servicemy">处理 service中自定义异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/serviceno">处理 service未知错误</a></h3>
    <hr>
    <h3><a href="${pageContext.request.contextPath }/db">处理 controller中数据库异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/my">处理 controller中自定义异常</a></h3>
    <h3><a href="${pageContext.request.contextPath }/no">处理 controller未知错误</a></h3>
    <hr>
    <!-- 在 web.xml中配置404 -->
    <h3>
        <a href="${pageContext.request.contextPath }/404">404 错误</a>
    </h3>
</body>
</html>

调用404 是为了防止出现无页面异常。所以这个要注意一下

定义 404 页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!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>
    资源已不在。
</body>
</html>

定义异常error.jsp,

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isErrorPage="true"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!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>
    <H1>错误:</H1><%=exception %>
    <H2>错误内容:</H2>
    <%
        exception.printStackTrace(response.getWriter());
    %>
</body>
</html>
  • excepton获取异常message信息。
  • exception.printStackTrace(response.getWriter());打印错误信息

定义my-error.jsp自定义异常页面


    <H1>自定义异常错误:</H1><%=exception %>

定义sql-error.jsp异常


    <H1>数据库异常错误:</H1><%=exception %>

web.xml配置404异常

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/jsp/404.jsp</location>
</error-page>

springMVC 配置 SimpleMappingExceptionResolver 类统一处理异常

 <bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 定义默认的异常处理页面,没有定义的异常全部到error.jsp页面 -->
        <property name="defaultErrorView" value="error"></property>
        <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception 一般都定义为ex比较常用-->
        <property name="exceptionAttribute" value="ex"></property>
        <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
        <property name="exceptionMappings">
            <props>
           <!--  定义自定义异常抛出显示的页面 -->
                <prop key="com.springTest.exception.MyException">my-error</prop>
                    <!--  定义sql异常抛出显示的页面 -->
                <prop key="java.sql.SQLException">sql-error</prop>
                <!-- 在这里还可以继续扩展对不同异常类型的处理 -->
            </props>
        </property>
    </bean>

配置完成启动服务器效果如下

在这里插入图片描述
在这里插入图片描述


实现HandlerExceptionResolver异常处理器接口

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse,
                                         Object o,
                                         Exception excption) {
//            封装错误信息
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("ex", excption);
        // 根据不同错误转向不同页面(统一处理),即异常与View的对应关系
        if (excption instanceof MyException) {
//            回传页面和信息
            return new ModelAndView("my-error", map);
        } else if (o instanceof SQLException) {
            return new ModelAndView("sql-error", map);
        } else {
            return new ModelAndView("error", map);
        }

    }
}

springMVC加载bean

 <!--托管MyExceptionHandler-->
    <bean class="exception.MyExceptionHandler"/>

使用注解@ExceptionHandler

配置基础类

import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import exception.MyException;
public class BaseController {
    /** 基于@ExceptionHandler异常处理 */
    @ExceptionHandler
    public String exception(HttpServletRequest request, Exception ex) {
        request.setAttribute("ex", ex);
        // 根据不同错误转向不同页面,即异常与view的对应关系
        if (ex instanceof SQLException) {
            return "sql-error";
        } else if (ex instanceof MyException) {
            return "my-error";
        } else {
            return "error";
        }
    }

将所有需要异常处理的 Controller 都继承 BaseController 基类

@Controller
public class TestExceptionController extends BaseController{
    ...
}

使用注解不需要配置SpringMVC配置

总结

使用此三种方法都可以让异常向上抛出,然后进行处理。分别使用simpleMapperResolver。和使用handlerExceptionResolver。以及简单的注解ExceptionHandler

在开发环境下,配置simpleMapperResolver比较常见。使用springBoot后使用注解开发比较常见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值