SpringMVC异常处理

1、重要的接口和类

1.1 HandlerExceptionResolver

            他是SpringMVC“九大组件”之一,SpringMVC异常处理核心接口。该接口定义了1个解析异常的方法:

1.2 ExceptionHandlerExceptionResolver

            继承自AbstractHandlerMethodExceptionResolver该类主要处理Controller中用@ExceptionHandler注解定义的方法。该类是<annotation-driven/>配置中定义的HandlerExceptionResolver实现类之一,大多数异常处理都是由该类操作。 

  • 在Controller中使用@ExceptionHandler处理异常
package com.xust.iot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;

@Controller
public class ExceptionHandlerTest {

@RequestMapping("/handler1")
public String handler1(Model model,@RequestParam(value = "value",required = false) int value){
	int i=10/value;
	model.addAttribute("msg","你好呀!");
	model.addAttribute("msg1","10/"+value+"=");
	model.addAttribute("res",i);

	return "success";
}

/**
 * 使用@ExceptionHandler注解可以告诉SpringMVC这是一个专门处理异常的方法
 * 一个方法可处理多个异常,可以有多个处理异常的类
 * @param e
 * @return
 */
@ExceptionHandler(ArithmeticException.class)
public ModelAndView exceptionHandler1(Exception e, HttpServletResponse response){
	System.out.println("在"+this.getClass().getName()+"中的异常处理方法");
	ModelAndView mv=new ModelAndView("error");
	mv.addObject("e",e);
	mv.addObject("statusCode",response.getStatus());
	return mv;
}
}

异常后的页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>出错啦</title>
</head>
<body>
<h3>出错啦!响应代码:${status},错误信息:${e}</h3>

</body>
</html>

测试结果:

            像这样在Controller中借助@ExceptionHandler这个注解定义的异常处理方法只能在定义的那个Controller中使用,当Controller类十分多的时候,那么写异常处理方法就是个体力活了,因此SpringMVC就提供了@ControllerAdvice这个注解,它只能用在类上,而这个类中的异常处理方法都是全局范围,如下定义一个类专门集中处理异常:

package com.xust.iot.handleException;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletResponse;

@ControllerAdvice
public class MyExceptionHandler {

@ExceptionHandler(ArithmeticException.class)
public ModelAndView handleArithmeticException(Exception e,HttpServletResponse response){
	ModelAndView mv=new ModelAndView("error");
	mv.addObject("status", response.getStatus());
	mv.addObject("e",e);
	return mv;
}


@ExceptionHandler(NullPointerException.class)
public ModelAndView handlerNulPointlException(Exception e,HttpServletResponse response){
	ModelAndView mv=new ModelAndView("error");
	mv.addObject("status", response.getStatus());
	mv.addObject("e",e);
	return mv;
}

@ExceptionHandler(Exception.class)
public ModelAndView handlerException(Exception e, HttpServletResponse response){
	ModelAndView mv=new ModelAndView("error");
	mv.addObject("status", response.getStatus());
	mv.addObject("e",e);
	return mv;
}
}
1.3 DefaultHandlerExceptionResovler

            HandlerExceptionResolver接口的默认实现之一 ,基本上是Spring MVC内部使用,用来处理Spring定义的各种标准异常,将其转化为相对应的HTTP Status Code。其处理的异常类型有:

handleNoSuchRequestHandlingMethod
handleHttpRequestMethodNotSupported
handleHttpMediaTypeNotSupported
handleMissingServletRequestParameter
handleServletRequestBindingException
handleTypeMismatch
handleHttpMessageNotReadable
handleHttpMessageNotWritable
handleMethodArgumentNotValidException
handleMissingServletRequestParameter
handleMissingServletRequestPartException
handleBindException
1.4 ResponseStatusExceptionResovler

             用来支持@ResponseStatus的使用,处理使用了ResponseStatus注解的异常,根据注解的内容,返回相应的HTTP Status Code和异常页面给客户端。如果Web应用程序中配置了ResponseStatusExceptionResolver,那么我们就可以使用ResponseStatus注解来注解我们自己编写的异常类,并在Controller中抛出该异常类,之后ResponseStatusExceptionResolver就会自动帮我们处理剩下的工作。<annotation-driven/>配置中定义的HandlerExceptionResolver实现类之一。 

自定义一个异常

package com.xust.iot.handleException;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(reason = "用户不存在",value = HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
    //......
}

另一个自定义异常

package com.xust.iot.handleException;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(reason = "输入的登录参数不合法",value = HttpStatus.BAD_REQUEST)
public class ParamterIllegalException extends RuntimeException {
}

在Controller中主动抛出这个异常看看效果:

package com.xust.iot.controller;

import com.xust.iot.beans.User;
import com.xust.iot.handleException.ParamterIllegalException;
import com.xust.iot.handleException.UserNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;


@Controller
public class UserController {

@RequestMapping("/toLogin")
public String checkLogIn(@RequestParam(value ="username",defaultValue = "")String username,Model model) throws Throwable {

	if("".equals(username)){
		System.out.println("用户登录失败");
		throw  new ParamaterIllegalException();
	}else if(!"admin".equals(username)){
		System.out.println("用户登录失败");
		throw  new UserNotFoundException();
	}

	model.addAttribute("msg","欢迎你"+username+",现在是北京时间:"+new SimpleDateFormat("hh:mm:ss").format(new Date()));
	System.out.println("用户登录成功");
	return "success";

}
}

测试结果:

ExceptionHandlerExceptionResolver、DefaultHandlerExceptionResolver和ResponseStatusExceptionResolver这三个类是<mvc:annotation-driver>配置后默认的3个实现类,他们的优先级是按书写的顺序由高到底。

1.5 SimpleMappingExceptionResovler

提供了将异常映射为视图的能力,高度可定制化。其提供的能力有:
1. 根据异常的类型,将异常映射到视图;
2. 可以为不符合处理条件没有被处理的异常,指定一个默认的错误返回;
3. 处理异常时,记录log信息;
4. 指定需要添加到Modle中的Exception属性,从而在视图中展示该属性。

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <!--在props标签中配置所有异常后对应的页面,其中:
                key表示异常,应该写异常的全类名
                <prop>标签体写该异常映射的视图名,只写视图名即可,SpringMVC的视图处理器会自动拼串
              -->
            <props>
                <prop key="java.lang.NullPointerException" >error</prop>
            </props>
        </property>
</bean>

留言区

还能输入500个字符