博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springMVC对异常处理的支持
阅读量:6322 次
发布时间:2019-06-22

本文共 5368 字,大约阅读时间需要 17 分钟。

hot3.png

无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了。跟其他MVC框架一样,springMVC也有自己的异常处理机制。

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

1、实现自己的HandlerExceptionResolver,HandlerExceptionResolver是一个接口,springMVC本身已经对其有了一个自身的实现——DefaultHandlerExceptionResolver,该解析器只是对其中的一些比较典型的异常进行了拦截,然后返回对应的错误码,当然你也可以继承DefaultHandlerExceptionResolver类,然后重写其中的一些异常处理方法来实现自己的异常处理。

import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.ModelAndView;public class ExceptionHandler implements HandlerExceptionResolver {	@Override	public ModelAndView resolveException(HttpServletRequest request,			HttpServletResponse response, Object handler, Exception ex) {		// TODO Auto-generated method stub		return new ModelAndView("exception");	}}

 上述的resolveException的第4个参数表示对哪种类型的异常进行处理。因为Exception类是所有异常类的基类,所以如果想根据异常类型的不同来进行不同的处理的话,可以在resolveException方法里面根据不同的异常类型进行不同的处理,返回不同的异常视图。如:

public class ExceptionHandler implements HandlerExceptionResolver {	@Override	public ModelAndView resolveException(HttpServletRequest request,			HttpServletResponse response, Object handler, Exception ex) {		// TODO Auto-generated method stub		if (ex instanceof NumberFormatException) {			//doSomething...			return new ModelAndView("number");		} else if (ex instanceof NullPointerException) {			//doSomething...			return new ModelAndView("null");		}		return new ModelAndView("exception");	}}
 

 

定义了这样一个异常处理器之后就要在applicationContext中定义这样一个bean对象,如:

Spring除了实现了一个DefaultHandlerExceptionResolver之外,还实现了一个SimpleMappingExceptionResolver,这两者都是继承自抽象类AbstractHandlerExceptionResolver,而AbstractHandlerExceptionResolver是实现了HandlerExceptionResolver接口的resolveException方法的,并由此抽取出两个抽象方法,一个是在进行异常处理之前执行的方法prepareResponse(exception, response),一个是进行异常解析的doResolveException(request, response, handler, exception)方法。SimpleMappingExceptionResolver,顾名思义就是通过简单的映射关系来决定由哪个视图来处理当前的错误信息。SimpleMappingExceptionResolver提供了通过异常类型exceptionMappings来进行异常与视图之间的映射关系,提供了在发生异常时通过statusCodes来映射异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时就返回defaultErrorView定义的视图,defaultErrorCode表示在发生异常时当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时默认返回的返回码。在使用SimpleMappingExceptionResolver时,当发生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默认值exception。

以下是一个简单的例子:

(1)SpringMVC的servlet配置文件中申明一个SimpleMappingExceptionResolver bean,并通过配置属性exceptionMappings和defaultExceptionView来指定异常和视图的对应关系。

number
null
500
503

(2)如下访问:

@Controller@RequestMapping("/test")public class TestController {	@RequestMapping("/null")	public void testNullPointerException() {		Blog blog = null;		//这里就会发生空指针异常,然后就会返回定义在SpringMVC配置文件中的null视图		System.out.println(blog.getId());	}		@RequestMapping("/number")	public void testNumberFormatException() {		//这里就会发生NumberFormatException,然后就会返回定义在SpringMVC配置文件中的number视图		Integer.parseInt("abc");	}		@RequestMapping("/default")	public void testDefaultException() {		if (1==1)			//由于该异常类型在SpringMVC的配置文件中没有指定,所以就会返回默认的exception视图			throw new RuntimeException("Error!");	}	}

 

(3)Jsp页面中可以访问到的异常对象,这里以NumberFormatException的返回视图number.jsp作为示例:

<%@ page language="java" import="java.util.*" pageEncoding="GB18030" isErrorPage="true"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>              My JSP 'number.jsp' starting page    	
NumberFormatException.
<%=exception.getMessage() %>
<%=exception %>
<%=request.getAttribute("ex") %>
<%=request.getAttribute("javax.servlet.error.status_code") %>
   

(4)当请求/test/number.do的时候会返回定义好的number视图,返回结果如下:

 

2、使用@ExceptionHandler进行处理

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

如:

import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RequestMapping;import com.tiantian.blog.web.servlet.MyException;@Controllerpublic 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又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用

优先级

既然在SpringMVC中有两种处理异常的方式,那么就存在一个优先级的问题:

当发生异常的时候,SpringMVC会如下处理:

(1)SpringMVC会先从配置文件找异常解析器HandlerExceptionResolver

(2)如果找到了异常异常解析器,那么接下来就会判断该异常解析器能否处理当前发生的异常

(3)如果可以处理的话,那么就进行处理,然后给前台返回对应的异常视图

(4)如果没有找到对应的异常解析器或者是找到的异常解析器不能处理当前的异常的时候,就看当前的Controller中有没有提供对应的异常处理器,如果提供了就由Controller自己进行处理并返回对应的视图

(5)如果配置文件里面没有定义对应的异常解析器,而当前Controller中也没有定义的话,那么该异常就会被抛出来。

 

 

 

转载于:https://my.oschina.net/NEMOCoder/blog/607505

你可能感兴趣的文章
vsftpd本地用户访问
查看>>
python文件操作学习笔记
查看>>
朗科实习期间心得笔记(六)
查看>>
iphone编程指南学习笔记2
查看>>
NFS服务配置
查看>>
中级篇第九期:相册与拍照初使用
查看>>
我的友情链接
查看>>
lvs 一个网卡单个管理ip,多个跨网段VIP解决办法
查看>>
自定义圆角button
查看>>
超长正整数相加
查看>>
Centos 6 编译内核支持LVS-SNAT模式
查看>>
JAVA数据类型
查看>>
TCP segment of a reassembled PDU
查看>>
hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]...
查看>>
【Oracle】oracle中快速判断某一日期是闰年或平年
查看>>
datatable 转 json 格式
查看>>
vs2010生成Dll文件并引用dll(C#)
查看>>
藏在兰州拉面里精益管理秘诀
查看>>
How to blog on Github
查看>>
百思不得姐 one day
查看>>