springmvc 统一处理异常

1.自定义统一异常处理器

自定义Exception实现 HandlerExceptionResolver接口或继承AbstractHandlerExceptionResolver类

1.实现接口HandlerExceptionResolver

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.jay.platform.exception.handler;
 
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.Date;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
 
import com.jay.platform.exception.AjaxException;
import com.jay.platform.exception.BusinessException;
 
/**
  *
  * @ClassName: ExceptionHandler
  * @Description: 统一异常处理 , 注意这里可以处理Controller层抛出的异常,但不处理Controller捕获的异常(Controller捕获的异常,这里不再处理)
  * @author Jay He
  * @date 2014年11月4日 上午10:22:11
  *
  */
public class ExceptionHandler implements HandlerExceptionResolver {
     private static final Logger LOGGER = Logger
         .getLogger(ExceptionHandler. class );
 
     @Override
     public ModelAndView resolveException(HttpServletRequest request,
         HttpServletResponse response, Object handler, Exception ex) {
     LOGGER.error( new Date().toLocaleString() + "异常信息" , ex);
     if (ex instanceof NumberFormatException) {
         return new ModelAndView( "exception/number" );
     } else if (ex instanceof NullPointerException) {
         return new ModelAndView( "exception/null" );
     } else if (ex instanceof BusinessException) {
         return new ModelAndView( "exception/business" );
     } else if (ex instanceof SocketTimeoutException
         || ex instanceof ConnectException) {
         try {
         response.getWriter().write( "网络异常" );
         } catch (IOException e) {
         e.printStackTrace();
         }
         return new ModelAndView( "exception/net_error" );
     } else if (ex instanceof AjaxException){
        System.out.println( "-=-=" );
     }
     return new ModelAndView( "exception/exception" );
     }
 
}


2.继承AbstractHandlerExceptionResolver类


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.jay.platform.exception.handler;
 
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.Date;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
 
import com.jay.platform.exception.AjaxException;
import com.jay.platform.exception.BusinessException;
 
/**
  *
  * @ClassName: ExceptionHandler
  * @Description: 统一异常处理 , 注意这里可以处理Controller层抛出的异常,但不处理Controller捕获的异常(Controller捕获的异常,这里不再处理)
  * @author Jay He
  * @date 2014年11月4日 上午10:22:11
  *
  */
public class ExceptionHandler extends AbstractHandlerExceptionResolver{
     private static final Logger LOGGER = Logger
         .getLogger(ExceptionHandler. class );
 
     @Override
     protected ModelAndView doResolveException(HttpServletRequest request,
         HttpServletResponse response, Object handler, Exception ex) {
    
LOGGER.error(new Date().toLocaleString() + "异常信息", ex); if (ex instanceof NumberFormatException) { return new ModelAndView("exception/number"); } else if (ex instanceof NullPointerException) { return new ModelAndView("exception/null"); } else if (ex instanceof BusinessException) { return new ModelAndView("exception/business"); } else if (ex instanceof SocketTimeoutException || ex instanceof ConnectException) { try { response.getWriter().write("网络异常"); } catch (IOException e) { e.printStackTrace(); } return new ModelAndView("exception/net_error"); }else if(ex instanceof AjaxException){ System.out.println("-=-="); } return new ModelAndView("exception/exception");
}}
?
1
 

在配置文件中添加自定义异常处理模块
?
1
2
<!-- Spring MVC的统一异常处理 -->
    <bean class = "com.jay.platform.exception.handler.ExceptionHandler" id= "exceptionResolver" >  </bean>



错误页面展示:
error. jsp
?
1
2
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
     pageEncoding= "UTF-8" %>

Error页面


出错信息



错误描述
${errorTips }



错误异常信息栈

${ex }


eception.jsp
?
1
2
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
     pageEncoding= "UTF-8" %>

Exception页面


模块开发中,请稍后。。。。。。






2.基于@ControllerAdvice注解实现统一异常处理,可方便返回普通异常和Ajax异常信息

自定义Web层异常处理


WebExceptionHandler.java
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package com.jay.platform.exception.handler;
 
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.ModelAndView;
 
import com.jay.platform.exception.AjaxException;
import com.jay.platform.utils.DateUtil;
 
/**
  * @ClassName: WebExceptionHandler
  * @Description: Web层异常处理器,  -- 这里可以根据不同的异常,写多个方法去处理, 可以处理跳转页面请求,跳到异常指定的错误页,
  *                                                       也可以处理Ajax请求,根据不通过异常,在页面输出不同的提示信息
  *                operateExp          :   处理普通请求
  *                operateExpAjax      :       处理Ajax请求
  * @author Jay He
  * @date 2015年5月27日 下午5:16:37
  *
  */
@ControllerAdvice
public class WebExceptionHandler {
     
     Logger logger =  Logger.getLogger(WebExceptionHandler. class );
     /*
      * 如果抛出UnauthorizedException,将被该异常处理器截获来显示没有权限信息
      */
     @ExceptionHandler ({ UnauthorizedException. class })
     @ResponseStatus (HttpStatus.UNAUTHORIZED)
     public ModelAndView unauthenticatedException(NativeWebRequest request,
         UnauthorizedException e) {
     ModelAndView mv = new ModelAndView();
     mv.addObject( "exception" , e);
     mv.setViewName( "base/exception/unauthorized" );
     return mv;
     }
 
     /**
      * @Title: operateExp
      * @Description: 全局异常控制,记录日志
      *              任何一个方法发生异常,一定会被这个方法拦截到。然后,输出日志。封装Map并返回给页面显示错误信息:
      *              特别注意:返回给页面错误信息只在开发时才使用,上线后,要把错误页面去掉,只打印log日志即可,防止信息外漏
      * @param: @param ex
      * @param: @param request
      * @return: String
      * @throws:
      */
     @ExceptionHandler (RuntimeException. class )
     public String operateExp(RuntimeException ex, HttpServletRequest request) {
     logger.error(ex.getMessage(), ex);
     logger.info( "************* ------ 异常信息已记录(" + DateUtil.getNow( "yyyy-MM-dd HH:mm:ss" )+ ") ------- ***********" );
     request.setAttribute( "errorTips" , ex.getMessage());
     request.setAttribute( "ex" , ex);
     return "exception/error" ;
     }
     
     /*
      * 记录Ajax异常日志,并将错误Ajax错误信息传递(回写)给前台展示,
      * 前台的jQuery的Ajax请求error中,可以打印错误提示信息   --  data.responseText   : 这里即是后台传递的错误提示
      * eg:
      * $.ajax({
                 type : 'get',
                 dataType : "json",
                 url : ctx + '/test/test',
                 accept:"application/json",
                 success : function(data) {
                     console.log(data);
                 },
                 error : function(data, errorThrown) {
                     console.log(data);
                     alert("error" + data.responseText);
                 }
             });
      */
     @ExceptionHandler (AjaxException. class )
     public void operateExpAjax(AjaxException ex, HttpServletResponse response) throws IOException {
     logger.error(ex.getMessage(), ex);
     logger.info( "************* ------ 异常信息已记录(" + DateUtil.getNow( "yyyy-MM-dd HH:mm:ss" )+ ") ------- ***********" );
     //将Ajax异常信息回写到前台,用于页面的提示
     response.getWriter().write( "sorry,Ajax请求出错!!!" );
     }
     
     
     @ExceptionHandler (ConnectException. class )
     public void operateExpNetException(ConnectException ex, HttpServletResponse response) throws IOException {
     logger.error(ex.getMessage(), ex);
     logger.info( "************* ------ 异常信息已记录(" + DateUtil.getNow( "yyyy-MM-dd HH:mm:ss" )+ ") ------- ***********" );
     //将Ajax异常信息回写到前台,用于页面的提示
         response.getWriter().write( "sorry,网络连接出错!!!" );
     }
}



异常测试


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.jay.platform.controller.test;
 
import java.net.ConnectException;
import java.util.HashMap;
import java.util.Map;
 
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.jay.platform.annotation.AjaxExceptionHandler;
import com.jay.platform.exception.AjaxException;
 
@Component
@Controller ()
@RequestMapping ( "exception" )
public class ExceptionHandlerTestController {
     
     @RequestMapping ( "test" )
     public String getIt(){
     return "exception/test/test" ;
     }
     
     @RequestMapping (value= "/common" ,method=RequestMethod.GET)
     public Map<string, object= "" > commonExcetion() throws RuntimeException{
     Map<string, object= "" > map = new HashMap<string, object= "" >();
     int i= 10 ;
     
     if (i== 10 ){
     throw new RuntimeException( "运行时异常" );
     }
     
     return map;
     }
     
     @AjaxExceptionHandler (tips= "试一把" , description= "哈啊" )
     @RequestMapping (value= "/ajax/net" ,method=RequestMethod.GET)
     @ResponseBody
     public Map<string, object= "" > AjaxConnectionExcetion() throws ConnectException{
     Map<string, object= "" > map = new HashMap<string, object= "" >();
     int i= 10 ;
     
     if (i== 10 ){
     throw new ConnectException( "测试    网络连接     异常" );
     }
     
     return map;
     }
     
     @RequestMapping (value= "/ajax/common" ,method=RequestMethod.GET)
     @ResponseBody
     public Map<string, object= "" > AjaxExcetion() throws AjaxException{
     Map<string, object= "" > map = new HashMap<string, object= "" >();
     int i= 10 ;
     
     if (i== 10 ){
     throw new AjaxException( "测试Ajax异常" );
     }
     
     return map;
     }
}
</string,></string,></string,></string,></string,></string,></string,></string,></string,>


前台页面


?
1
2
3
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
     pageEncoding= "UTF-8" %>
<%@ taglib prefix= "c" uri= "http://java.sun.com/jsp/jstl/core" %>
<%@ include file="../../common/meta.jsp"%> <script src="${jqueryCtxPath }/jquery-ui-1.11.2.custom/jquery-ui.min.js"></script>  <script type="text/javascript"> $(document).ready(function() { $("#test1").click(function(){ $.ajax({ type : 'get', dataType : "json", url : ctx + '/exception/ajax/net', accept:"application/json", success : function(data) { console.log(data); }, error : function(data, errorThrown) { console.log(data); alert("error" + data.responseText); } }); }); $("#test2").click(function(){ $.ajax({ type : 'get', dataType : "json", url : ctx + '/exception/ajax/common', accept:"application/json", success : function(data) { console.log(data); }, error : function(data, errorThrown) { console.log(data); alert("error" + data.responseText); } }); }); }); </script>

页面结果演示


\

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值