Spring MVC全局异常处理

本文介绍了Spring框架中的两种异常处理方式:基于HandlerExceptionResolver接口的全局异常处理和基于@Controller中的@ExceptionHandler注解的局部异常处理。并通过示例展示了如何配置及使用。
摘要由CSDN通过智能技术生成

    今天翻看项目发现异常类中有一个CommonExceptionHandler,却在配置文件中找不到任何有配置的地方,于是搜了一把资料,整理一下。

    Spring3.0中有两种异常处理机制,一种是实现HandlerExceptionResolver接口,一种是在Controller类中使用@ExceptionHandler注解,第一种方法可以实现全局异常控制,第二种方法更加灵活,个性化,但是不统一,我之前看的项目中就是用的第一种方法。


1. 基于HandlerExceptionResolver接口的异常处理:

   使用这种方法只需要复写 resolveException方法就可以了,该方法返回一个ModelAndView对象,该方法内部对异常的类型做判断,然后返回合适的ModelAndView对象,如果该方法返回了null,则spring会继续寻找其他实现了HandlerExceptionResolver接口的bean,就是说spring会搜索所有注册在其环境中的实现了HandlerExceptionResolver接口的Bean,逐个执行,直到返回了一个ModelAndView对象。(注意该自定义全局异常类一般用注解 @Component,表示模糊不好分层的注入,或者在配置文件xml中使用<bean/>结点声明。)

   举例:

@Component
public class CommonExceptionHandler implements HandlerExceptionResolver {
	private static final Logger logger = LoggerFactory.getLogger(CommonExceptionHandler.class);

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
			Object handler, Exception ex) {

		try {
			response.reset();
			response.setContentType("text/html;charset=UTF-8");
			PrintWriter writer = response.getWriter();
			if (ex instanceof UnAuthenticatedException || ex instanceof NoAuthorityException
					|| ex instanceof TimeoutException || ex instanceof ServiceException) {
				logger.warn("hander Exception:{}, Message is {}", ex.getClass(), ex.getMessage());

				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				writer.print(ex.getMessage());

			} else if (ex instanceof SystemShutDownException) {

				logger.warn("hander Exception:{}, Message is {}", ex.getClass(), ex.getMessage());
				response.setStatus(HttpServletResponse.SC_FORBIDDEN);
				writer.print(ex.getMessage());
			} else {
				// 其他异常,返回500状态码
				logger.error(ex.getMessage(), ex);
				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				writer.print("System error");
			}

		} catch (Exception e) {
			//logger.error(e.getMessage(), e);
			return null;
		}

		return new ModelAndView();
	}

}

这种写法,错误码直接返回到前台,前台jsp页面获取到之后,进行相应的判断,给出相对应的提示,如果前台页面没有相应的判断,则会直接输入相应的错误信息在页面上。

也可以用一下写法,出现异常之后跳转到一个写好的提示页面:

public class CustomExceptionHandler implements HandlerExceptionResolver {  
  
    @Override  
    public ModelAndView resolveException(HttpServletRequest request,  
            HttpServletResponse response, Object object, Exception exception) {  
        if(exception instanceof IOException){  
            return new ModelAndView("errors/ioException");  
        }else if(exception instanceof SQLException){  
            return new ModelAndView("errors/sqlException");  
        }  
        return null;  
    }  
}  

其中 errors/ioException  和  errors/sqlException  都是jsp页面。


spring 默认也提供了一个全局异常处理类SimpleMappingExceptionResolver,它也是HandlerExceptionResolver的实现类,如果要使用,只需要在xml中配置即可。

以下转载自此处,点击跳转

例如:

<span style="color:#3333FF;"> <!-- 全局异常配置 start  控制器异常处理--> 
        <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
            <property name="exceptionMappings"> 
                <props> 
                    <prop key="java.lang.Exception">errors/webException</prop> 
                    <prop key="java.lang.Throwable">errors/rmsException</prop> 
                </props> 
            </property> 
            <property name="statusCodes"> 
                <props> 
                    <prop key="errors/webException">500</prop> 
                    <prop key="errors/rmsException">404</prop> 
                </props> 
            </property> 
            <!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 --> 
            <property name="warnLogCategory" value="WARN"></property> 
            <!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 --> 
            <property name="defaultErrorView" value="errors/error"></property> 
            <!-- 默认HTTP状态码 --> 
            <property name="defaultStatusCode" value="500"></property> 
        </bean> 
        <!-- 全局异常配置 end --> </span>

通过SimpleMappingExceptionResolver我们可以将不同的异常映射到不同的jsp页面(通exceptionMappings属性的配置),同时我们也可以为所有的异常指定一个默认的异常提示页面(通过defaultErrorView属性的配置),如果所抛出的异常在exceptionMappings中没有对应的映射,则Spring将用此默认配置显示异常信息(注意这里配置异常显示界面均仅包括主文件名,至于文件路径和后缀已经在viewResolver中指定)  <property name="defaultErrorView" value="errors/error"></property>
一个典型的异常显示页面如下:
<span style="color:#3333FF;"><html> 
<head><title>Exception!</title></head> 
<body> 
<% Exception ex = (Exception)request.getAttribute("exception"); %> 
<H2>Exception: <%= ex.getMessage();%></H2> 
<P/> 
<% ex.printStackTrace(new java.io.PrintWriter(out)); %> 
</body> 
</html> </span>

exception 实在SimpleMappingExceptionResolver 被存放到request中的,具体可以查看源代码。 
如果SimpleMappingExceptionResolver无法满足异常处理的需要,我们可以针对 
HandlerExceptionResolver接口实现自己异常处理类,这同样非常简单(只需要实现一个 
resolveException方法)。 

如果有ViewResolver,则制定的jsp页面必须在那个页面下,到时候如果找不到页面,可以根据错误提示再调整页面路径

2..基于@ExceptionHandler的异常处理

该方法需要定义在Controller内部,然后创建一个方法并用@ExceptionHandler注解来修饰用来处理异常,这个方法基本和 @RequestMapping修饰的方法差不多,只是可以多一个类型为Exception的参数,@ExceptionHandler中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。

示例:

<span style="color:#3333FF;">@Controller  
public class ExceptionHandlerController {  
      
    @ExceptionHandler(value={IOException.class,SQLException.class})  
    public String exp(Exception ex,HttpServletRequest request) {  
        request.setAttribute("exception", ex);  
        return "/error.jsp";  
    }  
  </span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值