上文如果资源文件改为:
error.login.usernull = user must not null{0}
则输出user must not null null
即参数由null来代替。
我们可以看到ExceptionHandler的excute方法里面是这样处理的。
error = new ActionMessage(ae.getKey(), ex.getMessage()); property = error.getKey();
可以看到new ActionMessage(ae.getKey(), ex.getMessage());
这里的ae.getKey()就是我们在配置文件的exception的key属性。
<action path="/logon" type="com.lwf.struts.action.LogonAction" name="logonForm" input="/logon.jsp" scope="session" validate="true" > <exception key="error.login.usernull" type="com.lwf.struts.util.UserNotFoundException" path="/index.jsp" ></exception> </action>
而第二个参数ex.getMessage()则是获取异常信息。
也就是说如果我们的异常处理类抛出一个带参数的异常如;
package com.lwf.struts.action.entity; import com.lwf.struts.exception.PasswordNotFoundException; import com.lwf.struts.exception.UserNotFoundException; public class UserManager { private static UserManager userManager = new UserManager(); private UserManager(){} public static UserManager instance(){ return userManager; } public boolean isValidaUser(String name, String pwd) throws Exception{ boolean flagPwd = false; boolean flagUser = false; if(name!=null && name.equals("admin")){ flagUser = true; }else{ throw new UserNotFoundException(“user incorrect”); } if(pwd!=null && pwd.equals("super")){ flagPwd = true; }else{ throw new PasswordNotFoundException("pwd incorrect"); } return flagPwd && flagUser; } }
new UserNotFoundException(“user incorrect”);
注意黑体部分。那么异常会输出:
user must not null user incorrect null
即资源文件的key内容+异常抛出的文本+参数化
当然上面参数化也没有显示出来。需要我们写一个自己的ExceptionHandler来处理。
我们使用一个统一的异常类。如下:
package com.lwf.struts.exception; public class ErrorCodeException extends RuntimeException { private static final long serialVersionUID = 1L; private String errorCode;//错误码,对应资源文件的key private Object[] args;//占位符,即参数 public ErrorCodeException(){} public ErrorCodeException(String errorCode){ this.errorCode = errorCode; } public ErrorCodeException(String errorCode, Object[] args){ this.errorCode = errorCode; this.args = args; } public ErrorCodeException(String errorCode, Object args){ this(errorCode,new Object[]{args}); } public String getErrorCode() { return errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } public Object[] getArgs() { return args; } public void setArgs(Object[] args) { this.args = args; } }
实际上我们是为构造ActionMessage做准备。
我们自己的handler类:
package com.lwf.struts.handler; 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 com.lwf.struts.exception.ErrorCodeException; public class LogonHandler 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; ActionMessage error; String property; if (ae.getPath() != null) { forward = new ActionForward(ae.getPath()); } else { forward = mapping.getInputForward(); } ErrorCodeException ece = (ErrorCodeException)ex; String errocode = ece.getErrorCode(); Object[] args = ece.getArgs(); error = new ActionMessage(errocode, 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; } }
error = new ActionMessage(errocode, args);
我们可以看到现在我们构造ActionMessage传入的第一个参数不再是ae.getKey()所以现在来说
配置文件exception的key属性在这里可以不需要与资源文件相对应,可随便取值。如下配置:
<action path="/login" type="com.lwf.struts.action.LoginAction" name="loginForm" input="/index.jsp" scope="session" validate="true" > <exception key="keyCode" type="com.lwf.struts.exception.ErrorCodeException" handler="com.lwf.struts.handler.LogonHandler"></exception> </action>
看上面key="keyCode"
下面action
package com.lwf.struts.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessages; import com.lwf.struts.action.entity.UserManager; import com.lwf.struts.form.LoginForm; public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LoginForm loginForm = (LoginForm)form; String name = loginForm.getUsername(); String pwd = loginForm.getPassword(); ActionMessages errors = new ActionMessages(); UserManager.instance().isValidaUser(name, pwd); return mapping.findForward("success"); } }
下面是UserManager类。
package com.lwf.struts.action.entity; import com.lwf.struts.exception.ErrorCodeException; import com.lwf.struts.exception.PasswordNotFoundException; public class UserManager { private static UserManager userManager = new UserManager(); private UserManager(){} public static UserManager instance(){ return userManager; } public boolean isValidaUser(String name, String pwd) throws Exception{ boolean flagPwd = false; boolean flagUser = false; if(name!=null && name.equals("admin")){ flagUser = true; }else{ throw new ErrorCodeException("user.name.incorrect",name); } if(pwd!=null && pwd.equals("super")){ flagPwd = true; }else{ throw new ErrorCodeException("user.pwd.incorrect",pwd); } return flagPwd && flagUser; } }
注意我们这里统一抛出的是ErrorCodeException异常,只是参数不同。第一个参数必须与资源文件的key对应,第二个参数则可以是对象或对象数组。对应于资源文件的点位符。如ApplicationResources.properties文件内容
user.name.incorrect = user incorrect {0} user.pwd.incorrect = pwd incorrect {0}
这里我们传入的是输入的用户名。
好测试一下。我们输入用户名为we
那么在页面上会看到:
user incorrect we
即实现了参数化