博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于struts1.框架的异常处理方案
阅读量:6973 次
发布时间:2019-06-27

本文共 4301 字,大约阅读时间需要 14 分钟。

hot3.png

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

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配置

    若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文件时指定,如
controller
org.apache.struts.action.ActionServlet
config
/WEB-INF/struts/struts-config.xml
config/page/user
/WEB-INF/struts/config/struts-user.xml
config/page/user/department
/WEB-INF/struts/config/struts-department.xml
0
    struts1框架要求param-name必须以config开头,否则不处理。去掉config/,后面内容就是该配置文件的唯一标识,而这个就是prefix。struts-config.xml比较特别,它的prefix使用空串("")。

转载于:https://my.oschina.net/SEyanlei/blog/159552

你可能感兴趣的文章
mouseleave,mouseout 和mouseover ,mouseenter区别
查看>>
eclipse 快捷键设置
查看>>
c++11 多线程间共享数据 <c++ concurrency in action>
查看>>
py 的 第 24 天
查看>>
BZOJ 3456 城市规划
查看>>
多轨视频编辑技术支持
查看>>
who
查看>>
sql where 1=1
查看>>
HDU2425:Hiking Trip(BFS+优先队列)
查看>>
[Oracle]ORA-01461: can bind a LONG value only for insert into a LONG column
查看>>
xcode6新建工程
查看>>
单向路由算法
查看>>
RabbitMQ系列教程之二:工作队列(Work Queues)
查看>>
scrapy入门教程
查看>>
Linux学习之CentOS(三十三)--DNS基础及域名系统架构
查看>>
leetcode349
查看>>
批处理-自动同步数据库
查看>>
git常用命令[持续更新]
查看>>
HTML标签 — dl,dt,dd
查看>>
python-----基础大杂烩
查看>>