Spring MVC全局异常处理和单元测试_动力节点Java学院整理

 更新时间:2017年08月31日 10:59:15   作者:赵磊  
本篇文章主要介绍了Spring MVC全局异常处理和单元测试,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

在spring MVC的配置文件中:

<!-- 总错误处理--> 
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
  <property name="defaultErrorView">  
    <value>/error/error</value> 
  </property> 
  <property name="defaultStatusCode">  
    <value>500</value> 
  </property>   
<property name="warnLogCategory">  
    <value>org.springframework.web.servlet.handler.SimpleMappingExceptionResolver</value> 
  </property>   
</bean>

这里主要的类是SimpleMappingExceptionResolver类,和他的父类AbstractHandlerExceptionResolver类。

具体可以配置哪些属性,我是通过查看源码知道的。

你也可以实现HandlerExceptionResolver接口,写一个自己的异常处理程序。spring的扩展性是很好的。

通过SimpleMappingExceptionResolver我们可以将不同的异常映射到不同的jsp页面(通过exceptionMappings属性的配置)。

同时我们也可以为所有的异常指定一个默认的异常提示页面(通过defaultErrorView属性的配置),如果所抛出的异常在exceptionMappings中没有对应的映射,则Spring将用此默认配置显示异常信息。

注意这里配置的异常显示界面均仅包括主文件名,至于文件路径和后缀已经在viewResolver中指定。如/error/error表示/error/error.jsp

显示错误的jsp页面:

<%@ page language="java" contentType="text/html; charset=GBK" 
  pageEncoding="GBK"%> 
<%@ page import="java.lang.Exception"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=GBK"> 
<title>错误页面</title> 
</head> 
<body> 
<h1>出错了</h1> 
<% 
Exception e = (Exception)request.getAttribute("exception"); 
out.print(e.getMessage()); 
%> 
</body> 
</html> 

其中一句:request.getAttribute("exception"),key是exception,也是在SimpleMappingExceptionResolver类默认指定的,是可能通过配置文件修改这个值的,大家可以去看源码。

如何把全局异常记录到日志中?

在前的配置中,其中有一个属性warnLogCategory,值是“SimpleMappingExceptionResolver类的全限定名”。我是在SimpleMappingExceptionResolver类父类AbstractHandlerExceptionResolver类中找到这个属性的。查看源码后得知:如果warnLogCategory不为空,spring就会使用apache的org.apache.commons.logging.Log日志工具,记录这个异常,级别是warn。值:“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”,是“SimpleMappingExceptionResolver类的全限定名”。这个值不是随便写的。  因为我在log4j的配置文件中还要加入log4j.logger.org.springframework.web.servlet.handler.SimpleMappingExceptionResolver=WARN,保证这个级别是warn的日志一定会被记录,即使log4j的根日志级别是ERROR。

 如何给spring3 MVC中的Action做JUnit单元测试?

 使用了spring3 MVC后,给action做单元测试变得很方便,我以前从来不给action写单元测试的,现在可以根据情况写一些了。 不用给每个Action都写单元测试吧,自己把握。

JUnitActionBase类是所有JUnit的测试类的父类

package test; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.junit.BeforeClass; 
import org.springframework.mock.web.MockServletContext; 
import org.springframework.web.context.WebApplicationContext; 
import org.springframework.web.context.support.XmlWebApplicationContext; 
import org.springframework.web.servlet.HandlerAdapter; 
import org.springframework.web.servlet.HandlerExecutionChain; 
import org.springframework.web.servlet.HandlerMapping; 
import org.springframework.web.servlet.ModelAndView; 
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; 
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping; 
/** 
* 说明: JUnit测试action时使用的基类 
* 
* 
*  
*/  
public class JUnitActionBase { 
  private static HandlerMapping handlerMapping; 
  private static HandlerAdapter handlerAdapter; 
  /** 
   * 读取spring3 MVC配置文件 
   */ 
  @BeforeClass 
 public static void setUp() { 
    if (handlerMapping == null) { 
      String[] configs = { "file:src/springConfig/springMVCxml" }; 
      XmlWebApplicationContext context = new XmlWebApplicationContext(); 
      context.setConfigLocations(configs); 
      MockServletContext msc = new MockServletContext(); 
      context.setServletContext(msc);     context.refresh(); 
      msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context); 
      handlerMapping = (HandlerMapping) context 
          .getBean(DefaultAnnotationHandlerMapping.class); 
      handlerAdapter = (HandlerAdapter) context.getBean(context.getBeanNamesForType(AnnotationMethodHandlerAdapter.class)[0]);   
    } 
  } 
 
  /** 
   * 执行request对象请求的action 
   * 
   * @param request 
   * @param response 
   * @return 
   * @throws Exception 
   */ 
  public ModelAndView excuteAction(HttpServletRequest request, HttpServletResponse response) 
 throws Exception { 
    HandlerExecutionChain chain = handlerMapping.getHandler(request); 
    final ModelAndView model = handlerAdapter.handle(request, response, 
        chain.getHandler()); 
    return model; 
  } 
} 

这是个JUnit测试类,我们可以new Request对象,来参与测试,太方便了。给request指定访问的URL,就可以请求目标Action了。

package test.com.app.user; 
import org.junit.Assert; 
import org.junit.Test; 
import org.springframework.mock.web.MockHttpServletRequest; 
import org.springframework.mock.web.MockHttpServletResponse; 
import org.springframework.web.servlet.ModelAndView; 
 
import testJUnitActionBase; 
 
/** 
* 说明: 测试OrderAction的例子 
* 
*  
*  
*/  
 
public class TestOrderAction extends JUnitActionBase { 
  @Test 
  public void testAdd() throws Exception { 
  MockHttpServletRequest request = new MockHttpServletRequest(); 
    MockHttpServletResponse response = new MockHttpServletResponse(); 
    request.setServletPath("/order/add"); 
    request.addParameter("id", "1002"); 
    request.addParameter("date", "2010-12-30"); 
    request.setMethod("POST"); 
    // 执行URI对应的action 
    final ModelAndView mav = this.excuteAction(request, response); 
    // Assert logic 
    Assert.assertEquals("order/add", mav.getViewName()); 
    String msg=(String)request.getAttribute("msg"); 
    System.out.println(msg); 
  } 
} 

需要说明一下 :由于当前最想版本的Spring(Test) 3.0.5还不支持@ContextConfiguration的注解式context file注入,所以还需要写个setUp处理下,否则类似于Tiles的加载过程会有错误,因为没有ServletContext。3.1的版本应该有更好的解决方案。

相关文章

  • java后端PayPal支付实现教程

    java后端PayPal支付实现教程

    本文主要介绍了java后端PayPal支付实现教程,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Java如何使用poi导入导出excel工具类

    Java如何使用poi导入导出excel工具类

    这篇文章主要介绍了Java如何使用poi导入导出excel工具类问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • Java中eq、ne、ge、gt、le、lt的含义详细解释

    Java中eq、ne、ge、gt、le、lt的含义详细解释

    Java中的比较运算符包括eq(等于)、ne(不等于)、ge(大于或等于)、gt(大于)、le(小于或等于)和lt(小于),这些运算符在控制流语句和条件语句中用于判断条件是否满足,从而决定程序的执行路径,需要的朋友可以参考下
    2024-11-11
  • java通过注解实现分表详解

    java通过注解实现分表详解

    这篇文章主要为大家详细介绍了java如何通过注解实现分表,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-11-11
  • 使用java实现云端资源共享小程序的代码

    使用java实现云端资源共享小程序的代码

    这篇文章主要介绍了用java写一个云端资源共享小程序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • spring boot整合CAS Client实现单点登陆验证的示例

    spring boot整合CAS Client实现单点登陆验证的示例

    本篇文章主要介绍了spring boot整合CAS Client实现单点登陆验证的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • springboot发布dubbo服务注册到nacos实现方式

    springboot发布dubbo服务注册到nacos实现方式

    这篇文章主要介绍了springboot发布dubbo服务注册到nacos实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java如何使用interrupt()终止线程

    Java如何使用interrupt()终止线程

    这篇文章主要介绍了Java如何使用interrupt()终止线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • MyBatis Plus整合Redis实现分布式二级缓存的问题

    MyBatis Plus整合Redis实现分布式二级缓存的问题

    Mybatis内置的二级缓存在分布式环境下存在分布式问题,无法使用,但是我们可以整合Redis来实现分布式的二级缓存,这篇文章给大家介绍MyBatis Plus整合Redis实现分布式二级缓存,感兴趣的朋友跟随小编一起看看吧
    2023-11-11
  • 一起学JAVA基础之运算符

    一起学JAVA基础之运算符

    计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量,下面这篇文章主要给大家介绍了关于JAVA基础之运算符的相关资料,需要的朋友可以参考下
    2022-01-01

最新评论