struts个性化异常
在Struts国际化中处理个性化的异常消息:
在实际开发中,有些应用需要做国际化(I18N),估计大部分都是采用Struts的国际化机制吧,虽然JSTL也可以做国际化,但是真正要用得上国际化的项目,肯定少不了Struts类似的框架。
国际化消息包括页面的硬编码、动态提示信息、异常提示信息等,当我们配置好了国际化资源文件以后,对于硬编码,我们只需要在页面中使用<bean:message key=””/>即可显示国际化消息;对于动态提示的信息我们可以在程序中构建ActionMessage来传递消息,然后在页面中使用<html:message />或者<html:errors/>来动态显示信息。本人写这篇日志主要介绍一下,Struts在处理异常时动态显示个性化的异常I18N消息。重点:1、编写自己的异常类;2、编写自己的ExceptionHandler,重写execute()方法。
(本人的学习资料来自北京尚学堂,bluesun(蓝旭)是我以前所在的一个开发小组,后来因为成员考研,工作各方面的原因没能维持下去,可惜!)
前提条件:写好了国际化资源.properties文件,并且有对应的异常消息的key和value值。
user.login.usernotfount=User Not Found, UserName={0} user.login.passworderror=Password Error |
首先:建立自己的异常类,继承自RuntimeException,给两个私有属性异常编码errorCode,对应与国际化资源文件中的key;和该key对应的value的占位符列表Obect[] args,并有相应的geter方法。
package com.bluesun.struts; /** * struts国际化中异常处理:自定义的异常类 * @author lings * */ public class ErrorCodeException extends RuntimeException { /** * 异常的编码,对应与国际化资源文件中的key值 */ private String errorCode; /** * 该key对应的value的占位符列表 */ private Object[] args; public ErrorCodeException(String errorCode) { this.errorCode = errorCode; }
public ErrorCodeException(String errorCode, Object[] args) { this(errorCode); this.args = args; }
public ErrorCodeException(String errorCode, String args0) { this(errorCode, new Object[]{args0}); } public String getErrorCode() { return errorCode; } public Object[] getArgs() { return args; } } |
在构造方法中能处理无占位符,单个和多个占位符的情况(对应国际化资源文件),通过相应的key和占位符列表构造异常对象。
第二步:在业务逻辑中抛异常的时候一律抛自定义的异常类(throw new ErrorCodeException(“exception.key”, args)),这里exception.key是指国际化资源文件中相应的异常消息的key值,args是指该消息的占位符列表,如果没有可以不写,如果是单个,传String即可,详见自定义异常类的构造方法(ErrorCodeException)。
throw new ErrorCodeException("user.login.usernotfount", username); throw new ErrorCodeException("user.login.passworderror"); |
第三步:一般情况下,在struts中处理某个异常,除了编程式外,还可以在struts-config.xml中配置<exception type=”” key=”” path=””/>,这样无需在程序中手动捕获异常,而是在执行Action的execute()方法的时候Struts会帮我们捕捉这些异常,与标签中的type指定的异常类进行匹配,然后交给默认的Struts自己的ExceptionHandler处理,通过key指定的国际化消息,构造一个ActionMessage放到scope的ERROR_KEY属性中,最后通过path构造一个ActionForward返回给ActionServlet(大家阅读一下struts的源代码,就可以了解struts的工作流程了,然后你会发现,自己也可以模仿Struts写一个MVC的框架了,呵呵)。好了,我们现在可以在sturs-config.xml配置这个异常了,局部的或者是全局的都行,<exception type="com.bluesun.struts.ErrorCodeException" key="key" path="/login.jsp"/>,如果是这样的话,无论我们抛出的ErrorCodeException中的errorCode是什么,默认的ExceptionHandler都会将标签中的key拿去构造同样的一个ActionMessage,这样是与我们的意愿相违背的,我们希望是用我们自己抛出的ErrorCodeException中的errorCode来构造ActionMessage,所以我们自己重写一个ExceptionHandler,我叫它ErrorCodeExceptionHandler,从ExceptionHandler继承,然后找到struts源代码中ExceptionHandler的execute()方法,我们在自己的ErrorCodeExceptionHandler中模仿它重写execute()方法,根据相应的errorCode构造相应的ActionMessage。
package com.bluesun.struts; import javax.servlet.ServletException; import org.apache.struts.Globals; public class ErrorCodeExceptionHandler extends ExceptionHandler { ActionForward forward; // Build the forward from the exception mapping if it exists // 根据自己的异常类中的errorCode构造不同的ActionMessage this.logException(ex); // Store the exception if (!response.isCommitted()) { return null; |
最后别忘了,在struts-config.xml中的<exception type="com.bluesun.struts.ErrorCodeException" key="key" path="/login.jsp"/>里加上handler属性,<exception type="com.bluesun.struts.ErrorCodeException" key="key" path="/login.jsp" handler=” com.bluesun.struts.ErrorCodeExceptionHandler”/>,搞定!
最后:是在ActionForward指向的页面中显示了,因为struts处理异常的时候任然是把异常信息放到Scope的ERROR_KEY属性中了,所以用<html:errors />标签就可以了。
Struts1.X个性化异常学习
1.编写自己的个性化异常类。该类中,可以包含成员变量errorCode.需要填充properties占位符的args数组的Object数组类型成员变量。并定义他们的get()方法。定义四个构造函数,第一个构造函数为空,第二个构造函数为带errorCode,Object数组的构造方法,第三个为带errorCode参数的构造方法,第四为带errorCode参数,一个Object类型参数(非数组)的构造方法。后两个构造方法的实现中可以直接调用第二个声明个构造方法。
ErrorCodeException类:
- package wiki.struts;
- public class ErrorCodeException extends RuntimeException {
- //define the error code,
- //it is related to the properties file.
- private String errorCode;
- //if you want to dynamic fill with the args,use it object array.
- private Object[] args;
- public ErrorCodeException(){}
- //if not need to fill with the args in the properties.
- public ErrorCodeException(String errorCode){
- this(errorCode,null);
- }
- //if you want to fill with the args in the properties.
- public ErrorCodeException(String errorCode,Object args0){
- this(errorCode,new Object[]{args0});
- }
- public ErrorCodeException(String errorCode,Object[] args){
- this.errorCode = errorCode;
- this.args = args;
- }
- public String getErrorCode() {
- return errorCode;
- }
- public Object[] getArgs() {
- return args;
- }
- }
2.编写相应的ExceptionHandler类,继承自原有的ExceptionHandler。重写execute()方法。
ErrorCodeExceptionHandler类:
package wiki.struts;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.Globals;
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;
import org.apache.struts.util.ModuleException;
public class ErrorCodeExceptionHandler extends ExceptionHandler {
public ActionForward execute(
Exception ex,
ExceptionConfig ae,
ActionMapping mapping,
ActionForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException {
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 {
//deal with the exception,if the instance of
//exception is ErrorCodeException.
ErrorCodeException ece = (ErrorCodeException)ex;
error = new ActionMessage(ece.getErrorCode(), ece.getArgs());
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;
}
}
3.配置struts-config.xml<exception/>中的key值可以任意指定,type为自己的个性化异常类,handler为在2中编写的ExceptionHandler类。
- <exception key="error.exception"
- type="wiki.struts.ErrorCodeException"
- <STRONG><SPAN style="COLOR: #ff0000">handler="wiki.struts.ErrorCodeExceptionHandler"</SPAN>
- </STRONG>
- path="/login_error.jsp"
- />