真实项目实践:快速定位 Spring MVC异常实战(附源码下载)
创始人
2025-01-09 08:31:24
0

一、使用@ExceptionHandler进行处理

 

1.创建异常基类,使用@ExceptionHandler声明异常处理

BusinessException和SystemException为自定义异常类,代码如下:

  1. package com.twosnail.exception;  
  2.    
  3. import javax.servlet.http.HttpServletRequest;  
  4. import org.springframework.stereotype.Controller;  
  5. import org.springframework.web.bind.annotation.ExceptionHandler;  
  6.    
  7. @Controller 
  8. public class BasicExController {  
  9.     /**  
  10.      * 基于@ExceptionHandler异常处理基类  
  11.      * @return  
  12.      */ 
  13.     @ExceptionHandler 
  14.     public String exception( HttpServletRequest request , Exception ex ) {  
  15.            
  16.     // 根据不同错误转向不同页面    
  17.         if( ex instanceof BusinessException ) {  
  18.             return "business-error";    
  19.         }else if( ex instanceof SystemException ) {   
  20.             return "system-error";  
  21.         } else {  
  22.             return "error";    
  23.         }  
  24.     }  

2、使所有需要异常处理的Controller都继承该类,如下所示:

  1. public class DemoController extends BasicExController {} 

 

然而,Dao层、Service层、Controller层抛出的异常(BusinessException、SystemException和其它异常)都能准确显示定义的异常处理页面,达到了统一异常处理的目标。

总结:使用@ExceptionHandler注解实现异常处理,具有集成简单、有扩展性好(只需要将要异常处理的Controller类继承于BasicExController即可)、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性(需要修改已有代码,使继承于BasicExController),在异常处理时不能获取除异常以外的数据。

 

二、SimpleMappingExceptionResolver简单异常处理器

SimpleMappingExceptionResolver有两种配置方式,可以按自己需求而定,配置代码如下:

 

1、第一种,在Spring的配置文件中,增加以下内容:

在这里,可以设置跳转相应页面。

  1.  
  2.       
  3.       
  4.       
  5.       
  6.       
  7.       
  8.           
  9.             business-error  
  10.             system-error  
  11.           
  12.       
  13.    
  14.       
  15.       
  16.           
  17.             500  
  18.             404  
  19.           
  20.       
  21.       
  22.       
  23.       
  24.       
  25.  

2、第二种,通过自定义java类,继承SimpleMappingExceptionResolver

然后在Spring的配置。代码如下:

  1.  
  2.       
  3.           
  4.             error/500  
  5.             error/errorpage  
  6.             error/500  
  7.           
  8.       
  9.  

java类代码如下,在这里可以处理相应逻辑,如下,分别处理了jsp页面和json数据:

  1. package com.twosnail.exception;  
  2.    
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7. import org.springframework.web.servlet.ModelAndView;  
  8. import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;  
  9.    
  10. public class MyselfSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {  
  11.    
  12.     @Override 
  13.     protected ModelAndView doResolveException(HttpServletRequest request,  
  14.             HttpServletResponse response, Object handler, Exception ex) {  
  15.         // Expose ModelAndView for chosen error view.  
  16.         String viewName = determineViewName(ex, request);  
  17.         if (viewName != null) {// JSP格式返回  
  18.             if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request  
  19.                     .getHeader("X-Requested-With") != null && request  
  20.                     .getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {  
  21.                 // 如果不是异步请求  
  22.                 // Apply HTTP status code for error views, if specified.  
  23.                 // Only apply it if we're processing a top-level request.  
  24.                 Integer statusCode = determineStatusCode(request, viewName);  
  25.                 if (statusCode != null) {  
  26.                     applyStatusCodeIfPossible(request, response, statusCode);  
  27.                 }  
  28.                 return getModelAndView(viewName, ex, request);  
  29.             } else {// JSON格式返回  
  30.                 try {  
  31.                     PrintWriter writer = response.getWriter();  
  32.                     writer.write(ex.getMessage());  
  33.                     writer.flush();  
  34.                 } catch (IOException e) {  
  35.                     e.printStackTrace();  
  36.                 }  
  37.                 return null;  
  38.    
  39.             }  
  40.         } else {  
  41.             return null;  
  42.         }  
  43.     }  

总结:使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但方法1仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。

 

三、HandlerExceptionResolver自定义异常

 

1.在Spring的配置文件中,增加以下内容:

  1.  

2.添加自定义的MyExceptionHandler类,代码如下:

在这里,单独打印出了异常路径,便于在日志中查看,在对SystemException异常进行了特殊处理:

  1. package com.twosnail.exception;  
  2.    
  3. import java.util.Map;  
  4.    
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7. import org.springframework.web.servlet.HandlerExceptionResolver;  
  8. import org.springframework.web.servlet.ModelAndView;  
  9. import org.springframework.web.servlet.View;  
  10. import org.springframework.web.servlet.view.RedirectView;  
  11.    
  12. public class MyExceptionHandler implements HandlerExceptionResolver {  
  13.    
  14.     public ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response,   
  15.             Object handler, Exception exception ) {  
  16.            
  17.         System.out.println( "【抛出异常】--异常路径为:" +   
  18.             request.getServletPath() + "\n【异常信息】--" +  exception.getMessage() ) ;  
  19.         //如果不是抛出的action业务异常则不处理  
  20.         if( !( exception instanceof SystemException ) ) {  
  21.             return null;  
  22.         }  
  23.            
  24.         final SystemException actionE = (SystemException) exception;         
  25.         ModelAndView model = null;  
  26.         if( actionE.getForwardType() == SystemException.FORWARD ) {  
  27.                 //进入页面渲染  
  28.                 model = new ModelAndView( actionE.getModelPath(), actionE.getAttributes());  
  29.         } else if( actionE.getForwardType() == SystemException.REDIRECT ) {  
  30.                 model = new ModelAndView( new RedirectView( actionE.getModelPath(), true));  
  31.         } else {  
  32.             //直接返回页面内容  
  33.             model = new ModelAndView( new View() {  
  34.                 @Override 
  35.                 public void render(Map arg0, HttpServletRequest arg1,  
  36.                         HttpServletResponse arg2) throws Exception {  
  37.                        
  38.                     arg2.setContentType( "text/html" );  
  39.                     arg2.setCharacterEncoding( actionE.getEncode() );  
  40.                     if( actionE.getResponseBody() != null ) {  
  41.                         arg2.getWriter().print( actionE.getResponseBody() );  
  42.                     }  
  43.                 }  
  44.                    
  45.                 @Override 
  46.                 public String getContentType() {  
  47.                     return "text/html; charset=utf-8";  
  48.                 }  
  49.             } );  
  50.         }  
  51.            
  52.         return model;  
  53.     }  

总结:从上面的集成过程可知,使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点。在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。而SimpleMappingExceptionResolver就是HandlerExceptionResolver的默认实现类。

四、项目截图

代码地址:twosnail源码地址

参考资料:使用Spring MVC统一异常处理实战

原创作者:两只蜗牛

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...