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参数。

  自定义异常类:

   如:

Java代码
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();  
    }  

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

Java代码
public ActionForward delete(ActionMapping mapping, ActionForm form,  
            HttpServletRequest request, HttpServletResponse response) {  
        String id = request.getParameter("id");  
        try {  
            getOrgnizationService().delete(id);  
        } catch (RuntimeException e) {  
             
            <SPAN style="COLOR: #000000">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); //错误信息存入到页面中去。</SPAN>  
 
              
            return mapping.findForward("exception");  
              
        }  
        return mapping.findForward("OK");  
    } 
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文件:

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><STRONG><SPAN style="FONT-SIZE: medium"><SPAN style="COLOR: #ff0000"> </SPAN> 
</SPAN> 
</STRONG> 
<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来处理

 

Xml代码
<action-mappings > 
    <action 
      attribute="orgnizationForm" 
      name="orgnizationForm" 
      parameter="method" 
      path="/orgnization" 
      scope="request" 
      type="org.springframework.web.struts.DelegatingActionProxy"> 
      <SPAN style="COLOR: #000000"><exception key="error.detail" type="<SPAN>java.lang.RuntimeException</SPAN> 
"  scope="request" path="/error.jsp"></exception></SPAN> 
 
      <forward name="OK" path="/main/orgnization.jsp" /> 
    </action> 
 
  </action-mappings> 
<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为全局的异常 :

Xml代码
<global-exceptions> 
    <exception key="error.detail" type="java.lang.RuntimeException" scope="request" path="/error.jsp"></exception> 
  </global-exceptions> 
<global-exceptions>
   <exception key="error.detail" type="java.lang.RuntimeException" scope="request" path="/error.jsp"></exception>
  </global-exceptions>
 NO。3 (推荐)

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

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

    

Java代码
package edu.hust.util;  
 
import java.io.PrintStream;  
import java.io.PrintWriter;  
 
public class SystemException extends RuntimeException {  
    <SPAN style="COLOR: #000000">private String key;</SPAN>  
 
    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;  
        }      

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;
     } 
}

  在抛出异常的地方:

Java代码
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");  
    } 
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");
 }
  在配置文件中:

Xml代码
<global-exceptions> 
    <exception   
        key="error.detail"        <SPAN style="COLOR: #000000"> </SPAN> 
 
        type="edu.hust.SystemException"   
        scope="request"   
        path="/error.jsp"           
        handler="edu.hust.util.SystemExceptionHandler">     
        </exception> 
  </global-exceptions> 
<global-exceptions>
   <exception
    key="error.detail"        

    type="edu.hust.SystemException"
    scope="request"
    path="/error.jsp"        
    handler="edu.hust.util.SystemExceptionHandler">  
    </exception>
  </global-exceptions>
 异常处理类:

 

Java代码
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;  
 
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); //异常不属于自定义异常类  
    }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xp9802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值