统一异常处理

Posted mrchengs

tags:

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

 

在Spring MVC应用中,不管是怎样对底层数据库的操作还是业务层或者控制层的操作

都会遇到不可避免的各种异常需要处理,如果每个过程都单独对异常进行处理,那么

系统的代码耦合度高,工作量大且不好统一,维护工作也很麻烦。

 

如果将所有类型的异常从各个层中解耦出来,这样既保证了相关处理过程的功能单一

又实现了异常信息的统一处理和维护。

 

1、实例介绍

 模拟实例在请求的url中出现数学异常 i =10 /0;跳转到指定的页面。

同时可以指定其他的错误机制,此时仅仅作为列子:

 技术分享图片

搭建基本的测试环境:

MyFormatter.java 
public class MyFormatter implements Formatter<Date> {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    @Override
    public Date parse(String s, Locale locale) throws ParseException {
        return simpleDateFormat.parse(s);
    }
    @Override
    public String print(Date date, Locale locale) {
        return simpleDateFormat.format(date);
    }
}
MyException.java
public class MyException extends Exception {
    public MyException() {
        super();
    }
    public MyException(String msg) {
        super(msg);
    }
}

 error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"
         pageEncoding="UTF-8"    isErrorPage="true" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
error:<%=exception.getMessage()%>
</body>
</html>

 ErrorSql.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java"
isErrorPage="true" %> 
<html> <head> <title>Title</title> </head> <body>
error:<%=exception.getMessage()%>
</body> </html>

 test.java

@Controller
public class test {
    @RequestMapping("/test")
    public String test(){
        int i = 10 /0;
        System.out.println(i);
        return "addGoods";
    }
}

配置文件:

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/mvc
  http://www.springframework.org/schema/mvc/spring-mvc.xsd
   http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
"> <mvc:annotation-driven></mvc:annotation-driven> <context:component-scan base-package="controller"/> <!--视图解析--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="suffix" value=".jsp"/> <property name="prefix" value="/WEB-INF/jsp/"/> </bean> <!--注册Formatter --> <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="formatter.MyFormatter"></bean> </set> </property> </bean> <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven> </beans>

 

 2、SimpleMappingExceptionResolver

 org.springframework.web.servlet.handler.SimpleMappingExceptionResolver类统一处理异常时需要在配置文件中指定

配置异常类和View的对应关系。


dispatcher-servlet.xml
    <context:component-scan base-package="controller"/> 

    <!--视图解析-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
    </bean>

    <!--注册Formatter -->
    <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="formatter.MyFormatter"></bean>
            </set>
        </property>
    </bean>
    <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven>

    <!--异常-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="erroes/error" />
    </bean>

 启动测试:

技术分享图片

 其他使用方法:

<!--异常-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--定义默认异常处理的页面 -->
<property name="defaultErrorView" value="erroes/error" />
<!--定义异常吃力页面来获取异常信息的变量名,默认时exception -->
<property name="exceptionAttribute" value="ex"/>
<!--定义需要特殊处理的异常,用类名或者路径名作为key,异常页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="exception.MyException" >MyException</prop>
</props>
</property>
</bean>

 

 3、HandlerExceptionResolver

org.springframework.web.servlet.HandlerExceptionResolver接口用于解析请求处理过程中所产生的异常
开发者可以根据该接口的实现类进行Spring MVC应用的异常统一处理。

 

 MyExceptionHandler.java

package exception;

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 request,
      HttpServletResponse response, Object o, Exception e) {

        Map<String,Object> model = new HashMap<String, Object>();

        model.put("ex",e);

        //根据转向不同的页面统一处理
        if(e instanceof SQLException){
            return new ModelAndView("erroes/ErrorSql",model);
        }else {
            return new ModelAndView("erroes/error",model);
        }
    }
}

 此时可同时处理多个异常,因为只是测试所以就简单的写了两个!!!

需要将是实现类在配置文件中托管给spring MVC框架才能进行统一的异常处理。

配置文件:

    <mvc:annotation-driven></mvc:annotation-driven>

    <context:component-scan base-package="controller"/> 

    <!--视图解析-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
    </bean>

    <!--注册Formatter -->
    <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="formatter.MyFormatter"></bean>
            </set>
        </property>
    </bean>
    <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven>

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

 测试:

技术分享图片


 4、@ExceptionHandler

 创建BaseController类,并在该注解中使用@ExceptionHandler注解声明异常处理的方法

BaseController.java
package controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;
public abstract class BaseController {
    //异常的注解方式
    @ExceptionHandler
    public String exception(HttpServletRequest request,
        HttpServletResponse response, Object o, Exception e){

        request.setAttribute("ex",e);

        //根据转向不同的页面统一处理
        if(e instanceof SQLException){
            return "erroes/ErrorSql";
        }else {
            return "erroes/error";
        }
    }
}

将所有都需要异常处理的Controller都继承上述的类:

@Controller
public class testexController extends BaseController {

    @RequestMapping("/test1")
    public String test(){
        int i = 10 /0;
        System.out.println(i);
        return "addGoods";
    }
}

此时的配置文件:

    <mvc:annotation-driven></mvc:annotation-driven>

    <context:component-scan base-package="controller"/> 

    <!--视图解析-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="suffix" value=".jsp"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
    </bean>

    <!--注册Formatter -->
    <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatters">
            <set>
                <bean class="formatter.MyFormatter"></bean>
            </set>
        </property>
    </bean>
    <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven>

测试:

 技术分享图片

 

 

 基于异常的处理就是以上的三种方法,此时都是简单的测试,具体的根据自身的需要去实现。

















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

异常和TCP通讯

Spring统一异常处理

.NET Core统一参数校验异常处理结果返回功能实现

.NET Core统一参数校验异常处理结果返回功能实现

.NET Core统一参数校验异常处理结果返回功能实现

.NET Core统一参数校验异常处理结果返回功能实现