文档章节

基于struts1.框架的异常处理方案

磐谷
 磐谷
发布于 2013/09/06 10:52
字数 1361
阅读 882
收藏 1

首先感谢“郡主”对我的支持,她帮忙完善了跳转地址重定向问题。

1. 目标——什么异常需要我们处理

    通常来说,在业务流程中已经将大部分异常进行处理,因为大部分异常是继承java.lang.Exception,所以开发人员在IDE环境中可以轻松识别并使用try catch语句块进行处理。但是别忘了java.lang.RuntimeException。
    有很多常见的异常,如java.lang.NullPointerException、java.lang.IndexOutOfBoundsException,都是RuntimeException的子类,这类异常在IDE开发环境中不易判断,而且经常会导致意外的结果,这些异常正式是本文要处理的东西。
    PS:不要小看java.lang.NullPointerException,在做单元测试的过程中,一半以上的失败结果都是它造成的,相信在每一个项目中它都是一个可怕的存在。

2. struts1框架对异常的处理支持

    struts框架有两种异常处理方式:action的exception配置和global-exceptions配置

<action-mappings>
        <action path="/Test" scope="request"  type="com.sg.LoginAction" parameter="method" >
            <forward name="index" path="/index.jsp"/>
            <exception key="error.action.message" type="java.lang.RuntimeException"></exception>
        </action>
    </action-mappings>
<global-exceptions>
      <exception key="error.message" type="java.lang.RuntimeException" path="/common/errorPage.jsp" />
  </global-exceptions>
    若LoginAction的方法抛出的RuntimeException(事实上RuntimeException的子类也可以),struts会尝试在action配置中查找对应的exception配置并进行处理,若没有找到,则查找global-exceptions配置并处理,两者都没有找到,struts框架会抛出ServletException让web容器处理。

3. 通常的处理思路以及struts框架的弊端
    3.1 action的exception和global-exception的选择
        由于项目中,按模块、按功能划分后的action配置会很多,显然在使用action的exception配置进行同一的RuntimeException处理配置的工作量非常大,global-exceptions是我们的选择。
        
    3.2 global-exceptions的配置
        RuntimeException的子类非常多,我们不能把每一个RuntimeException的子类都进行配置。还好struts框架对于异常的处理可以对Exception进行向上转型并处理,比如Action抛出的NullPointerException,struts会按照NullPointerException->RuntimeException->Exception->Throwable的顺序一次查找是否有对应的处理。
        
    3.3 邪恶的struts1框架
        1) struts1的global-exeptions是针对配置文件的,假设项目按照功能划分的struts-user.xml和struts-department.xml,这两个配置的中的global-exeptions配置是不能共用的。
        2) 为了便于项目组对模块进行划分,struts的配置文件通常会设置不同的前缀(prefix,最后会有关于prefix的简单介绍),ActionForward根据前缀的路径进行跳转,因此不同的struts的配置文件可能需要配置不同的跳转地址。


4. ExceptionHandler带来的转机
    框架的目的之一是为了让开发人员忽略技术使用细节,转而将更多的精力放在业务逻辑实现上。为了绕开struts的复杂的异常处理,我们使用struts的ExceptionHandler。
    ExceptionHandler是struts默认异常处理类,在Action方法执行发生异常时,ExceptionHander将捕获异常,并进行更进一步的处理(如将异常根据配置的不同放入request或session、配置key国际化等),通过继承ExceptionHandler,我们可以尝试进行地址的统一跳转。
    
    struts的跳转是通过ActionForward的信息进行的,所以在ExceptionHandler子类中创新统一的ActionForward即可,代码如下:

public class CommonExceptionHandler extends ExceptionHandler {

	private static final Logger logger = 
	      Logger.getLogger(CommonExceptionHandler.class);
	
	/** 统一跳转地址路径 */
	private static final String EXCEPTION_PAGE_PATH = "/common/exceptionPage.jsp";
	
	public ActionForward execute(Exception ex, ExceptionConfig ae,
			ActionMapping mapping, ActionForm formInstance,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException {
		logger.info("统一异常处理 begin");
		logger.error("Action抛出了未捕获的异常", ex);
		
		/*
		 * 判断是否为ajax请求
		 *   若是ajax请求,由于页面处理方式不一致,不做页面提示
		 */
		String ajaxFlg = request.getHeader("X-Requested-With");
		if(ajaxFlg != null) {
			logger.info("请求类型为ajax请求!");
			logger.info("统一异常处理 end");
			return null;
		}
		
		/* 调用父类方法,方法中会将exception信息放入request */
		super.execute(ex, ae, mapping, formInstance, request, response);
		/* 设置同一跳转路径 */
		ActionForward forward = new ActionForward("excepationPage", EXCEPTION_PAGE_PATH , false, "");
		
		logger.info("统一异常处理 end");
		return forward;
	}
}
    代码中有两处需要注意:
    1) ajax请求可以处理(代码中之所以没有处理是因为我们项目的ajax请求处理不统一,因此不能统一设置,有待Ajax处理方案统一),但不能使用统一的跳转,因为跳转后response中设置的跳转页面的代码,ajax请求结果处理方法不需要这些信息;
    2) ActionForward的构造方法有4个参数:
/**
     * Construct a new instance with the specified values.
     *
     * @param name Name of this forward
     * @param path Path to which control should be forwarded or redirected
     * @param redirect Should we do a redirect?
     * @param module Module prefix, if any
     */
    public ActionForward(String name, String path, boolean redirect,
                         String module) {

        super();
        setName(name);
        setPath(path);
        setRedirect(redirect);
        setModule(module);

    }
    module指Module prefix,我们项目在根目录下的/common/exceptionPage.jsp,所以使用struts-config.xml的prefix,若使用其他配置文件的prefix需要自行修改。
    
关于prefix
    struts的每一个配置文件都有唯一标识,这个标识在web.xml中配置struts文件时指定,如
<servlet>
		<servlet-name>controller</servlet-name>
		<servlet-class>
			org.apache.struts.action.ActionServlet
		</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>
				/WEB-INF/struts/struts-config.xml
			</param-value>
		</init-param>
		<init-param>
			<param-name>config/page/user</param-name>
			<param-value>
				/WEB-INF/struts/config/struts-user.xml
			</param-value>
		</init-param>
		<init-param>
			<param-name>config/page/user/department</param-name>
			<param-value>
				/WEB-INF/struts/config/struts-department.xml
			</param-value>
		</init-param>
		<load-on-startup>0</load-on-startup>
	</servlet>
    struts1框架要求param-name必须以config开头,否则不处理。去掉config/,后面内容就是该配置文件的唯一标识,而这个就是prefix。struts-config.xml比较特别,它的prefix使用空串("")。

© 著作权归作者所有

磐谷
粉丝 5
博文 23
码字总数 24987
作品 0
朝阳
高级程序员
私信 提问
Struts1和Struts2的特点、工作流程及差异性

图解Struts1的工作流程: Struts1的优缺点: 优点:a.从技术的本质而言:是基于jsp+javabean模式2的基础的一个框架。 b.从设计的本质而言:仅仅只针对与MVC。 c.从模型本质而言:它就是一套框...

鲁雯雪
2014/02/16
158
0
一次post提交中文造成乱码问题的分析

前提条件 在解决问题之前,web模块中配置了自定义的HttpEncodingFilter和GetHttpServletRequestWrapper,期待能够解决所有服务器上的中文乱码问题,很遗憾,让大家失望了。最后给出web.xml中...

彭苏云
2015/09/18
3.9K
3
Java面试题之Struts2

1.简单的介绍一下Struts2 struts2框架框架是一个按照MVC设计模式设计的WEB层框架,是在Struts1和WebWork的技术基础上进行了合并的全新的框架 ,其全新的Struts2的体系结构,与Struts1的体系结...

年轻诠释我们的梦想_705b
2018/06/11
0
0
struts1-2,springMVC原理基本对比(单例,多例)-servlet与filter区别

最近做项目用到了struts2,之前一直是用struts1和springMVC。感觉到了struts2从很大程度上和这两个还是有很大区别的,所以今天搜集了些资料,给他们做一下对比。 Struts1官方已经停止更新,现...

tantexian
2016/06/21
394
0
Struts1 title:insert 异常处理问题

我现在正在做以个很老很破旧的项目,现在发现项目没有做全局的Exception处理, 也就是 JSP 出了异常的话,就会直接上到页面上去。 我现在的想法,就是加一个filter去过滤所有的请求,只要fli...

何聪聪GG
2014/12/05
46
0

没有更多内容

加载失败,请刷新页面

加载更多

Hibernate 5 的模块/包(modules/artifacts)

Hibernate 的功能被拆分成一系列的模块/包(modules/artifacts),其目的是为了对依赖进行独立(模块化)。 模块名称 说明 hibernate-core 这个是 Hibernate 的主要(main (core))模块。定义...

honeymoose
今天
4
0
CSS--属性

一、溢出 当内容多,元素区域小的时候,就会产生溢出效果,默认是纵向溢出 横向溢出:在内容和容器之间再套一层容器,并且内部容器要比外部容器宽 属性:overflow/overflow-x/overflow-y 取值...

wytao1995
今天
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
7
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0
jenkins 插件下载加速最终方案

推荐做法 1、告诉jenkins 我哪些插件需要更新 jenkins插件清华大学镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 1.进入jenkins系统管理 2.进入插件管...

vasks
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部