Struts 声明式异常处理和个性化异常处理(转)

首先我们的国际化资源文件中有

  1. user.not.found = 用户不能找到,用户名称=[{0}]   
  2. user.password.error = user.password.error  

第一种 声明式异常处理

为国际化配置文件中的每个key,设计一个异常。

用户登录验证,用户名错误抛出UserNotFoundException,密码错误抛出PasswordErrorException

 

代码
public void login(String username, String password) {   
        
if (!"admin".equals()) {   
            
throw new UserNotFoundException();   
        }   
        
if (!"admin".equals(password)) {   
            
throw new PasswordErrorException();   
        }   
    } 

struts-config.xml文件中,<exception/>的key对应国际化配置文件中key,type是对应的异常处理类

代码
<global-exceptions>  
    
<!-- 为所有Action使用的,全局异常 -->  
        
<exception key="user.not.found" type="demo.struts.UserNotFoundException"/>  
        
<exception key="user.password.error" type="demo.struts.PasswordErrorException"/>  
    
</global-exceptions>  
           
    
<action-mappings>  
        
<action path="/login"  
                type
="demo.struts.LoginAction"  
                name
="loginForm"  
                scope
="request"  
                validate
="false"  
                input
="/login.jsp"  
        
>       
        
<!-- path 错误时候 跳转的页面,优先级高于 action中的input -->  
        
<!-- 为每一个action配置    
            <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>  
            <exception key="user.password.error" type="demo.struts.PasswordErrorException" path="/login_error.jsp"/>  
        
-->  
            
<forward name="success" path="/login_success.jsp"/>  
            
<forward name="error" path="/login.jsp"/>  
        
</action>  
           
        
<action path="/changelang"  
                type
="demo.struts.ChangeLanguageAction"  
        
>  
            
<forward name="index" path="/index.jsp"/>  
        
</action>  
  
    
</action-mappings>  

Struts的RequestProcessor类

代码
protected ActionForward processException(HttpServletRequest request,   
                                            HttpServletResponse response,   
                                            Exception exception,   
                                            ActionForm form,   
                                            ActionMapping mapping)   
       
throws IOException, ServletException {   
  
       
// 是否在配置了Exception   
       ExceptionConfig config = mapping.findException(exception.getClass());   
       
// 找到的config就是下面这条信息   
       
// <exception key="user.not.found" type="demo.struts.UserNotFoundException" path="/login_error.jsp"/>   
       if (config == null) {   
       
// 没有配置,struts不管了,往web容器里抛,看在web.xml文件中是否配置,   
       
// 如果仍没有配置,则把异常显示到页面上   
           log.warn(getInternal().getMessage("unhandledException",   
                                             exception.getClass()));   
           
if (exception instanceof IOException) {   
               
throw (IOException) exception;   
           } 
else if (exception instanceof ServletException) {   
               
throw (ServletException) exception;   
           } 
else {   
               
throw new ServletException(exception);   
           }   
       }   
  
       
// struts异常默认处理类   
       try {   
           ExceptionHandler handler 
= (ExceptionHandler)   
           RequestUtils.applicationInstance(config.getHandler());   
           
return (handler.execute(exception, config, mapping, form,   
                                   request, response));   
       } 
catch (Exception e) {   
           
throw new ServletException(e);   
       }   
   }  

struts默认的exceptionHandler

代码
public ActionForward execute(   
    Exception ex,   
    ExceptionConfig ae,   
    ActionMapping mapping,   
    ActionForm formInstance,   
    HttpServletRequest request,   
    HttpServletResponse response)   
    
throws ServletException {   
  
    ActionForward forward 
= null;   
    ActionMessage error 
= null;   
    String property 
= null;   
  
    
// 在<exception>中配置了path,返回actionForward就是path中的配置   
    if (ae.getPath() != null) {   
        forward 
= new ActionForward(ae.getPath());   
    } 
else {   
    
// 没有配置的话,返回actionForward就是<action>中的input   
        forward = mapping.getInputForward();   
    }   
  
    
// Figure out the error   
    if (ex instanceof ModuleException) {   
        error 
= ((ModuleException) ex).getActionMessage();   
        property 
= ((ModuleException) ex).getProperty();   
    } 
else {   
    
// 我们写的程序抛出的异常都是这种情况   
    
// 从国际化文件中,根据key取   
    
// ae.getKey() -- 拿到<exception>中key值 user.not.found   
        error = new ActionMessage(ae.getKey(), ex.getMessage());   
        
// 集合ActionMessages中的key,和国际化资源文件中的key一样   
        property = error.getKey();   
    }   
  
    
this.logException(ex);   
  
    
// Store the exception   
    request.setAttribute(Globals.EXCEPTION_KEY, ex);   
    
// 放到ActionMessages集合中 getScope()默认request   
    this.storeException(request, property, error, forward, ae.getScope());   
  
    
return forward; 


第二种 个性化异常处理

代码
public void login(String username, String password) {   
        
if (!"admin".equals(username)) {   
                        
//user.not.found资源文件中的key, username 占位符   
            throw new ErrorCodeException("user.not.found", username);   
        }   
        
if (!"admin".equals(password)) {   
            
throw new ErrorCodeException("user.password.error");   
        }  
代码
<global-exceptions>  
    
<!-- key值随便配一个 具体的是在程序中控制-->  
    
<!-- type异常类 handler异常处理类 都是由我们来写和控制 -->  
    
<exception key="error.exception" type="demo.struts.ErrorCodeException" handler="demo.struts.ErrorCodeExceptionHandler"/>  
</global-exceptions>
代码
public class ErrorCodeException extends RuntimeException {   
  
    
// 错误码就是国际化资源文件的key   
    private String errorCode;   
  
    
// 占位符   
    private Object[] args;   
  
    
public ErrorCodeException(String errorCode) {   
        
this(errorCode, null);   
    }   
  
    
public ErrorCodeException(String errorCode, Object arg) {   
        
this(errorCode, new Object[]{arg});   
    }   
       
    
public ErrorCodeException(String errorCode, Object[] args){   
        
this.errorCode = errorCode;   
        
this.args = args;   
    }   
  
    
// 只提供get方法   
    public String getErrorCode() {   
        
return errorCode;   
    }   
  
    
public Object[] getArgs() {   
        
return args;   
    }  
代码
public class ErrorCodeExceptionHandler extends ExceptionHandler {   
  
    
public ActionForward execute(Exception ex, ExceptionConfig ae,   
            ActionMapping mapping, ActionForm formInstance,   
            HttpServletRequest request, HttpServletResponse response)   
            
throws ServletException {   
  
        
// 不是ErrorCodeException,我们不处理   
        if (!(ex instanceof ErrorCodeException)) {   
            
return super.execute(ex, ae, mapping, formInstance, request, response);   
        }   
           
        ActionForward forward 
= null;   
        ActionMessage error 
= null;   
        String property 
= null;   
  
        
// Build the forward from the exception mapping if it exists   
        
// or from the form input   
        if (ae.getPath() != null) {   
            forward 
= new ActionForward(ae.getPath());   
        } 
else {   
            forward 
= mapping.getInputForward();   
        }   
  
        
// Figure out the error   
        if (ex instanceof ModuleException) {   
            error 
= ((ModuleException) ex).getActionMessage();   
            property 
= ((ModuleException) ex).getProperty();   
        } 
else {   
            
// 原来的代码 error = new ActionMessage(ae.getKey(), ex.getMessage());   
            
// ae.getKey() 拿出的key是配置文件中<exception>写的,因为所有异常都用同一个key   
            
// 无法找到国际化资源文件中的key,好在我们在抛异常时,把key写进异常的errorCode中   
               
            ErrorCodeException ece 
= (ErrorCodeException) ex;   
            
// 拿到errorCode   
            String errorCode = ece.getErrorCode();   
            
// 拿到占位符   
            Object[] args = ece.getArgs();   
               
            error 
= new ActionMessage(errorCode, args);   
            property 
= error.getKey();   
        }   
  
        
this.logException(ex);   
  
        
// Store the exception   
        request.setAttribute(Globals.EXCEPTION_KEY, ex);   
        
this.storeException(request, property, error, forward, ae.getScope());   
  
        
return forward;   
  
    }  


如果我们不想写国际化配置文件,在程序中之际页面提示内容

<!-- 用默认的handler也能能执行 -->  
<exception key="error.exception" type="demo.struts.AppException" handler="demo.struts.AppExceptionHandler"/>  

国际化资源文件:

  1. # 只有一个占位符   
  2. error.exception={0}
    代码
    public void login(String username, String password) {   
        
    if (!"admin".equals(username)) {   
                           
    // 直接写内容   
            throw new AppException("用户不能找到【" + username + "");   
        }   
        
    if (!"admin".equals(password)) {   
            
    throw new ErrorCodeException("密码错误");   
        }   
    }  

 

public class AppException extends RuntimeException {   
    
public AppException(String msg){   
        
super(msg);   
    }   
}  
代码
public class AppExceptionHandler extends ExceptionHandler {   
  
    
public ActionForward execute(Exception ex, ExceptionConfig ae,   
            ActionMapping mapping, ActionForm formInstance,   
            HttpServletRequest request, HttpServletResponse response)   
            
throws ServletException {   
  
        
if(!(ex instanceof AppException)){   
            
return super.execute(ex, ae, mapping, formInstance, request, response);   
        }   
           
        ActionForward forward 
= null;   
        ActionMessage error 
= null;   
        String property 
= null;   
  
        
// Build the forward from the exception mapping if it exists   
        
// or from the form input   
        if (ae.getPath() != null) {   
            forward 
= new ActionForward(ae.getPath());   
        } 
else {   
            forward 
= mapping.getInputForward();   
        }   
  
        
// Figure out the error   
        if (ex instanceof ModuleException) {   
            error 
= ((ModuleException) ex).getActionMessage();   
            property 
= ((ModuleException) ex).getProperty();   
        } 
else {   
               
            AppException appe 
= (AppException) ex;   
            
// ae.getKey() 没用   
            
// appe.getMessage() ("用户不能找到【" + username + "】   
            error = new ActionMessage(ae.getKey(), appe.getMessage());   
            property 
= error.getKey();   
        }   
  
        
this.logException(ex);   
  
        
// Store the exception   
        request.setAttribute(Globals.EXCEPTION_KEY, ex);   
        
this.storeException(request, property, error, forward, ae.getScope());   
  
        
return forward;   
  
    }  
原文地址:https://www.cnblogs.com/Fskjb/p/1698578.html