spring之spring mvc对异常的处理

springMVC提供的异常处理主要有两种方式,一种是直接实现自己的 HandlerExceptionResolver,当然这也包括使用Spring已经为我们提供好的 SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,另一种是使用注解的 方式实现一个专门用于处理异常的Controller——ExceptionHandler.

 

 

1.spring mvc 自己实现了SimpleMappingExceptionResolver 和 DefaultHandlerExceptionResolver.



 DefaultHandlerExceptionResolver,该解析器只是对其中的一些比较典型的异常进行了拦截,然后返回对应的错误码.

 

public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
//......


	@Override
	protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
			Object handler, Exception ex) {

		try {
			if (ex instanceof NoSuchRequestHandlingMethodException) {
				return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response,
						handler);
			}
			else if (ex instanceof HttpRequestMethodNotSupportedException) {
				return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
						response, handler);
			}
			else if (ex instanceof HttpMediaTypeNotSupportedException) {
				return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response,
						handler);
			}
			//......
		}
		catch (Exception handlerException) {
			logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
		}
		return null;
	}

 

 

 SimpleMappingExceptionResolver提供了通过异常类型 exceptionMappings来进行异常与视图之间的映射关系,提供了在发生异常时通过statusCodes来映射异常返回的视图名称和对应的 HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认 值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时就返回defaultErrorView 定义的视图,defaultErrorCode表示在发生异常时当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时默认返回的返 回码。在使用SimpleMappingExceptionResolver时,当发生异常的时 候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指 定exceptionAttribute时,exceptionAttribute就是用默认值exception。

 

public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionResolver {

	/** The default name of the exception attribute: "exception". */
	public static final String DEFAULT_EXCEPTION_ATTRIBUTE = "exception";
       //当发生异常时,与视图的映射
	private Properties exceptionMappings;

	private Class<?>[] excludedExceptions;

        //默认的视图,表示当抛出异常但没有在exceptionMappings里面找到对应的异常时 返回//名叫exception的视图
	private String defaultErrorView;

       //定义在发生异常时视图跟返回码的对应关系
	private Integer defaultStatusCode;

	private Map<String, Integer> statusCodes = new HashMap<String, Integer>();

	private String exceptionAttribute = DEFAULT_EXCEPTION_ATTRIBUTE;

 

 

在需要使用到SimpleMappingExceptionResolver来处理异常时,一般需在xml配置bean.

如:

 

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
        <property name="exceptionMappings">  
            <props>  
                <prop key="NumberFormatException">number</prop><!-- 表示当抛出NumberFormatException的时候就返回名叫number的视图 -->  
                <prop key="NullPointerException">null</prop>  
            </props>  
        </property>  
        <property name="defaultErrorView" value="exception"/><!-- 表示当抛出异常但没有在exceptionMappings里面找到对应的异常时 返回名叫exception的视图-->  
        <property name="statusCodes"><!-- 定义在发生异常时视图跟返回码的对应关系 -->  
            <props>  
                <prop key="number">500</prop><!-- 表示在发生NumberFormatException时返回视图number,然后这里定义发生异常时视图number对应的HttpServletResponse的返回码是500 -->  
                <prop key="null">503</prop>  
            </props>  
        </property>  
        <property name="defaultStatusCode" value="404"/><!-- 表示在发生异常时默认的HttpServletResponse的返回码是多少,默认是200 -->  
    </bean>  

 

 

2.使用@ExceptionHandler进行处理

 

使用@ExceptionHandler进行处理有一个不好的地方是在同一个Controller里面需要同时有进行异常处理的方法与出错的方法.

如:

 

@Controller  
public class GlobalController {  
  
      
    /** 
     * 用于处理异常的 
     * @return 
     */  
    @ExceptionHandler({MyException.class})  
    public String exception(MyException e) {  
        System.out.println(e.getMessage());  
        e.printStackTrace();  
        return "exception";  
    }  
      
    @RequestMapping("test")  
    public void test() {  
        throw new MyException("出错了!");  
    }  
      
      
} 

 这里在页面上访问test方法的时候就会报错,而拥有该test方法的Controller又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用.

 

但是,一般在实际中,采用注解@ExceptionHandler来处理异常,都会建立一个父类BaseController.

 

public abstract class BaseController {  

    @ExceptionHandler
    public String exception(HttpServletRequest request, Exception e) {  
          
      //添加自己的异常处理逻辑,如日志记录   
        request.setAttribute("exceptionMessage", e.getMessage());  
          
        // 根据不同的异常类型进行不同处理
        if(e instanceof SQLException) 
            return "testerror";   
        else
            return "error";  
    }  
    
}

 

TestExceptionController:

 

@Controller
@RequestMapping("/ex")
public class TestExceptionController extends BaseController{

	@RequestMapping("/index")
	public ModelAndView index() throws SQLException{
		
		throw new SQLException("数据库异常");
	}
}

 最后,添加testerror.jsp视图来显示错误信息:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %> 
    
<!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>error!</title>
</head>
<body>
    ${exceptionMessage}
</body>
</html>

 

最后,测试访问,捕捉到异常.



 

这样只要把我们的其它的Controller全部继承于BaseController就能实现异常的集中捕捉和处理了

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值