springMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,另一种是使用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler。
1、实现自己的HandlerExceptionResolver,HandlerExceptionResolver是一个接口,springMVC本身已经对其有了一个自身的实现——DefaultExceptionResolver,该解析器只是对其中的一些比较典型的异常进行了拦截处理。
-
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个参数表示对哪种类型的异常进行处理,如果想同时对多种异常进行处理,可以把它换成一个异常数组。
定义了这样一个异常处理器之后就要在applicationContext中定义这样一个bean对象,如:
- <bean id="exceptionResolver" class="com.tiantian.xxx.web.handler.ExceptionHandler"/>
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;
- @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又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用
当发生异常的时候,上述两种方式都使用了的时候,第一种方式会将第二种方式覆盖
http://gaojiewyh.iteye.com/blog/1297746
最近使用spring mvc开发一个web系统,发现在controller里发生未捕获异常时不出日志。
分析DispatcherServlet,初始化handlerExceptionResolvers
- /**
- * Initialize the strategy objects that this servlet uses.
- * <p>May be overridden in subclasses in order to initialize
- * further strategy objects.
- */
-
protected void initStrategies(ApplicationContext context) {
- initMultipartResolver(context);
- initLocaleResolver(context);
- initThemeResolver(context);
- initHandlerMappings(context);
- initHandlerAdapters(context);
- // 初始化异常处理支持器
- initHandlerExceptionResolvers(context);
- initRequestToViewNameTranslator(context);
- initViewResolvers(context);
- }
- // 进入初始化处理方法,具体内容就不贴了,主要是先到上下文中搜寻我们自己定义的ExceptionResolvers,如果没有自定义的resolvers,从默认配置中读取。
-
private void initHandlerExceptionResolvers(ApplicationContext context)
- // 从默认策略中取得默认配置,从DispatcherServlet.properties文件中取得相关的配置策略,但是在spring2.5的mvc jar包中properties文件中没有HandlerExceptionResolver的默认配置,返回一个EmptyList给handlerExceptionResolvers
- protected List getDefaultStrategies(ApplicationContext context, Class strategyInterface)
分析DispatcherServlet,分发处理请求
- // 从dispatch方法中看到,系统对请求进行具体的逻辑处理部分被catch住了一次exception,然后会使用servlet持有的ExceptionResolver进行处理
-
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
- HttpServletRequest processedRequest = request;
-
HandlerExecutionChain mappedHandler = null;
-
int interceptorIndex = -1;
- // Expose current LocaleResolver and request as LocaleContext.
- LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
-
LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);
- // Expose current RequestAttributes to current thread.
- RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();
-
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
-
RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);
-
if (logger.isTraceEnabled()) {
-
logger.trace("Bound request context to thread: " + request);
- }
-
try {
-
ModelAndView mv = null;
-
boolean errorView = false;
-
try {
- processedRequest = checkMultipart(request);
- // Determine handler for the current request.
-
mappedHandler = getHandler(processedRequest, false);
-
if (mappedHandler == null || mappedHandler.getHandler() == null) {
- noHandlerFound(processedRequest, response);