struts1异常的处理分析

1 异常链

  当不需要用户来处理和关心原始的异常时,常见的做法是捕获原始的异常,把他们包装成一个新的不同类型的异常,然后再抛出异常。

   所谓异常链就是把原始异常包装成新的异常类时,在新的异常类中封装了原始异常类

2 多样化异常

   在实际应用中,有时需要一个方法同时抛出多个异常。

   如果应用不支持在一个方法中抛出多个异常,用户每次将只能看到针对一个字段域的验证错误,当改正了一个错误后,重新提交表单,又会收到针对另一个字段域的验证错误,这会使得用户体验非常多差劲。

   有效的做法是每次当用户提交表单后,都验证所有的字段,然后向用户显示所有的验证信息。不幸的是,在java中一次只能抛出一个异常。因此需要开发者自行设计支持多样化异常的异常类。

3 struts异常分析

   在struts的控制层中,将java的异常类包装成ActionMessage。在struts中定义异常有两种方式:

         扩展ModuleException和创建自定义的异常类体系。

   扩展ModuleException

   优点,可以很好的和sturts的Resouce Bundle绑定。

   ModuleException(String key)和ModuleException(String key,Object[] values)

   key为错误消息key,values为对象数组类型的values参数。

  自定义异常类:

   如:

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class BaseException extends Exception {
	protected Throwable rootCause = null;
	private List exception = new ArrayList<Throwable>();
	private String messageKey = null;
	private Object[] messageArgs = null;
	
	public Throwable getRootCause() {
		return rootCause;
	}
	public void setRootCause(Throwable rootCause) {
		this.rootCause = rootCause;
	}
	public List getException() {
		return exception;
	}
	public void addException(Throwable exception) {
		this.exception.add(exception);
	}
	public String getMessageKey() {
		return messageKey;
	}
	public void setMessageKey(String messageKey) {
		this.messageKey = messageKey;
	}
	public Object[] getMessageArgs() {
		return messageArgs;
	}
	public void setMessageArgs(Object[] messageArgs) {
		this.messageArgs = messageArgs;
	}
	@Override
	public void printStackTrace() {
		printStackTrace(System.err);
	}
	@Override
	public void printStackTrace(PrintStream s) {
		printStackTrace(new PrintWriter(s));
	}
	@Override
	public void printStackTrace(PrintWriter s) {
		super.printStackTrace(s);
		
		if(getRootCause() != null){
			getRootCause().printStackTrace(s);
		}
		
		s.flush();
	}
}

 因为有了rootCause exceptions messageKey 和messageArgs 这四个属性使得这个自定义异常类有了以下功能:

   支持异常的级联,rootCause属性制定原始异常(异常链)

   支持多样化异常,exceptions属性存放所有嵌套的异常

   支持和struts的Resouce Bundle的绑定,messageKey属性指定消息key

   支持复合式消息,messageArgs属性指定复合式消息中的参数。

 

处理异常的方法

NO。1

   自己手动编写。   

   个人抛出异常方法:

     if(满足一定条件){

                throw new RuntionException(“错误提示信息”);

     }

 

    由自己try {}catch(){}进行捕获然后,用mapping.forwoard(“”)跳转到处理页面中来。

   xxAction.java

public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String id = request.getParameter("id");
		try {
			getOrgnizationService().delete(id);
		} catch (RuntimeException e) {
			/**
			 * 返回一个错误信息。
			 */
			ActionMessages mesgs = new ActionMessages();
			ActionMessage mesg = new ActionMessage("error.detail",e.getMessage());//error.detail为资源文件,e.getMessage()为得到的错误信息。他所处的地方为error.detail的参数所在地。
			mesgs.add("error",mesg);
			this.saveErrors(request, mesgs); //错误信息存入到页面中去。

			
			return mapping.findForward("exception");
			
		}
		return mapping.findForward("OK");
	}

 

   struts-config.xml文件:

<action-mappings >
    <action
      attribute="orgnizationForm"
      name="orgnizationForm"
      parameter="method"
      path="/orgnization"
      scope="request"
      type="org.springframework.web.struts.DelegatingActionProxy"
      validate="false">
      <forward name="exception" path="/error.jsp"></forward>
      <forward name="OK" path="/main/orgnization.jsp" />
    </action>

  </action-mappings> 


   在页面调用这个时应该用<html:errors>即可把资源文件里面的错误信息显示出来。

NO。2    

    在项目中通常需要统一的错误处理。将异常throws出去,交给sturts来处理。

    有两个缺点

            不能处理带参数的异常!去给资源文件的参数赋值;

            异常的类型在配置文件中是固定的,不能动态改变。

    struts可以有两种方法对异常进行处理。

    一种 是在struts配置文件里面的action下面(局部异常处理 ),用exception来处理

 

<action-mappings >
    <action
      attribute="orgnizationForm"
      name="orgnizationForm"
      parameter="method"
      path="/orgnization"
      scope="request"
      type="org.springframework.web.struts.DelegatingActionProxy">
      <exception key="error.detail" type="java.lang.RuntimeException
"  scope="request" path="/error.jsp"></exception>

      <forward name="OK" path="/main/orgnization.jsp" />
    </action>

  </action-mappings>

 

 

 

 

 

   另一种 方法是在struts的配置文件中的global-exception为全局的异常

<global-exceptions>
  	<exception key="error.detail" type="java.lang.RuntimeException" scope="request" path="/error.jsp"></exception>
  </global-exceptions>

 NO。3 (推荐)

    使用自定义的异常类来继承原始的异常。用自定义的异常类来处理整个工程的异常。在一个异常类中使用多种异常。用一个异常类来代表不同的异常消息。

    首先,定义自己的异常类:他要继承RuntimeException

    

package edu.hust.util;

import java.io.PrintStream;
import java.io.PrintWriter;

public class SystemException extends RuntimeException {
	private String key;

	private Object[] values;
	public String getKey(){
		return key;
	}
	public Object[] getValues(){
		return values;
	 }
	public SystemException() {
		super();
	}

	public SystemException(String message, Throwable cause) {
		super(message, cause);
	}

	public SystemException(String message) {
		super(message);
	}

	public SystemException(Throwable cause) {
		super(cause);
	}

 	  public SystemException(String message,String key){
    		super(message);
    		this.key = key;
 	   }
	  public SystemException(String message,String key,Object values){
    		 super(message);
   		  this.key = key;
   		  this.values = new Object[]{values};
   	 }
 
  	  public SystemException(String message,String key,Object[] values){
		     super(message);
		     this.key = key;
		     this.values = values;
	    }	
}

  在抛出异常的地方:

public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String id = request.getParameter("id");
		try {
			getOrgnizationService().delete(id);
		} catch (RuntimeException e) {
			throw new SystemException("有子机构,不能删除!","error.detail2");//去对应上面的构造函数,知道error.detail2为key。
		}
		return mapping.findForward("OK");
	}

  在配置文件中:

<global-exceptions>
  	<exception 
  		key="error.detail"         

  		type="edu.hust.SystemException" 
  		scope="request" 
  		path="/error.jsp"         
  		handler="edu.hust.util.SystemExceptionHandler">   
  		</exception>
  </global-exceptions>

 异常处理类:

 

package edu.hust.util;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.config.ExceptionConfig;
/**
 * 统一异常处理类,继承的是org.apache.struts.action下的ExceptionHandler。
 * 实现execute方法即可
。

 * @author sunqitang
 *
 */
public class SystemExceptionHandler extends ExceptionHandler {
	@Override
	public ActionForward execute(Exception ex, ExceptionConfig ae,
			ActionMapping mapping, ActionForm formInstance,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException {
		ActionForward forward = null;
		if( null != ae.getPath()){
			forward = new ActionForward(ae.getPath());//获得默认的path
		}else{
			forward = mapping.getInputForward();
		}
		if(ex instanceof SystemException){
			ActionMessage error = null;
			SystemException sysExce = (SystemException) ex;
			String key = sysExce.getKey();   //获得key
			if( null == key){  //如果可以为空
				error = new ActionMessage(ae.getKey(),sysExce.getMessage());
			}else{
				if(null != sysExce.getValues()){ // 可以不为空,且有参数
					error = new ActionMessage(key,sysExce.getValues());
				}else{
					error = new ActionMessage(key);
				}
			}
			this.storeException(request, key, error, forward, ae.getScope());
			return forward;
		}
		return super.execute(ex, ae, mapping, formInstance, request, response); //异常不属于自定义异常类
	}
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值