struts声明式异常:
在配置文件中配置exception属性,并配以相应在的异常类型,那么程序中遇到这类异常就会自动处理异常信息.
如下例:登录action处理中会抛出UserNotFoundException,那么采用声明式异常:
login.jsp
上面注释部分就是采用编程式异常的代码.现在采用声明式异常就不用不需要再catch异常
查看配置文件中注意:
type异常类型,key消息文本.当struts碰到这个异常会默认转向到input指向的jsp页面.消息文本为key所指的值.
如果在exception添加path属性,如上面path="/index.jsp" 那么异常会转向到index.jsp而不是logon.jsp
ApplicationResources.properties文件中内容:
运行程序输出结果:
user must not null
看看struts源代码:
那么当前应用如果配置了input属性,发生异常转向该属性所指页面,如果当前应用配置了exception配置了path则转向path所指页面,如果当前应用input,path都没有或者当前应用没配置exception,那么查找是否配置全局异常,如果有配置,那么转向到全局应用的path所指页面
在上面我们知道声明式异常默认采用ExceptionHandler来处理.但我们修改资源文件将
error.login.usernull = user must not null
改为
error.login.usernull = user must not null{0}
即增加参数我们会发现默认的异常处理并不能输出参数信息.
在配置文件中配置exception属性,并配以相应在的异常类型,那么程序中遇到这类异常就会自动处理异常信息.
如下例:登录action处理中会抛出UserNotFoundException,那么采用声明式异常:
<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>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html:html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>logon</title>
</head>
<body>
<html:errors/>
<html:form action="logon">
<table border="0" width="100%">
<tr>
<th align="right"><bean:message key="login.user"/></th>
<td align="left"><html:text property="username" size="20" maxlength="20"></html:text></td>
</tr>
<tr>
<th align="right"><bean:message key="login.pwd"/></th>
<td align="left"><html:password property="password" size="20" maxlength="20"></html:password></td>
</tr>
<tr>
<td align="right"><html:submit>logonin</html:submit> </td>
<td align="left"><html:button property="register" >register</html:button><html:reset>reset</html:reset></td>
</tr>
</table>
</html:form>
</body>
</html:html>
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.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.lwf.struts.form.LogonForm;
import com.lwf.struts.util.UserManageEntity;
import com.lwf.struts.util.UserNotFoundException;
public class LogonAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
ActionMessages errors = new ActionMessages();
ActionForward forward = new ActionForward();
LogonForm logonForm = (LogonForm)form;
String name = logonForm.getUsername();
String pwd = logonForm.getPassword();
UserManageEntity.UserManager(name);
// try {
// UserManageEntity.UserManager(name);
// errors.add("logonerror1", new ActionMessage("error.login.user"," myerrmsg"));
// this.saveMessages(request, errors);
// request.getSession().setAttribute("user", logonForm);
// forward = mapping.findForward("success");
// } catch (UserNotFoundException e) {
// errors.add("logonerror2", new ActionMessage("error.login.again"," error2"));
// this.saveErrors(request, errors);
// forward = mapping.findForward("error");
// }
//
forward = mapping.findForward("success");
return forward;
}
}
上面注释部分就是采用编程式异常的代码.现在采用声明式异常就不用不需要再catch异常
package com.lwf.struts.util;
public class UserNotFoundException extends Exception {
public UserNotFoundException(){}
public UserNotFoundException(String message){
super(message);
}
}
查看配置文件中注意:
<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>
type异常类型,key消息文本.当struts碰到这个异常会默认转向到input指向的jsp页面.消息文本为key所指的值.
如果在exception添加path属性,如上面path="/index.jsp" 那么异常会转向到index.jsp而不是logon.jsp
ApplicationResources.properties文件中内容:
error.login.usernull = user must not null
运行程序输出结果:
user must not null
看看struts源代码:
// Call the Action instance itself
ActionForward forward =
processActionPerform(request, response, action, form, mapping);
protected ActionForward processActionPerform(HttpServletRequest request,
HttpServletResponse response, Action action, ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
try {
return (action.execute(mapping, form, request, response));
} catch (Exception e) {
return (processException(request, response, e, form, mapping));
}
}
protected ActionForward processException(HttpServletRequest request,
HttpServletResponse response, Exception exception, ActionForm form,
ActionMapping mapping)
throws IOException, ServletException {
// Is there a defined handler for this exception?
ExceptionConfig config = mapping.findException(exception.getClass());
if (config == null) {
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);
}
}
// Use the configured exception handling
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 来处理,我们可以自己定义异常处理类,从而改变默认声明式异常处理的行为.在配置文件中exception 中增加handler属性*/
public ActionForward execute(Exception ex, ExceptionConfig ae,
ActionMapping mapping, ActionForm formInstance,
HttpServletRequest request, HttpServletResponse response)
throws ServletException {
LOG.debug("ExceptionHandler executing for exception " + ex);
ActionForward forward;
ActionMessage error;
String property;
// Build the forward from the exception mapping if it exists
// or from the form input
<strong> if (ae.getPath() != null) {
forward = new ActionForward(ae.getPath());
} else {
forward = mapping.getInputForward();
}</strong>
// Figure out the error
if (ex instanceof ModuleException) {
error = ((ModuleException) ex).getActionMessage();
property = ((ModuleException) ex).getProperty();
} else {
<strong> error = new ActionMessage(ae.getKey(), ex.getMessage());</strong>
property = error.getKey();
}
this.logException(ex);
// Store the exception
request.setAttribute(Globals.EXCEPTION_KEY, ex);
this.storeException(request, property, error, forward, ae.getScope());
if (!response.isCommitted()) {
return forward;
}
LOG.debug("Response is already committed, so forwarding will not work."
+ " Attempt alternate handling.");
if (!silent(ae)) {
handleCommittedResponse(ex, ae, mapping, formInstance, request,
response, forward);
} else {
LOG.warn("ExceptionHandler configured with " + SILENT_IF_COMMITTED
+ " and response is committed.", ex);
}
return null;
}
/*以上代码是不是解释了异常会默认转向到input指向的jsp页面. 如果在exception添加path属性,如上面path="/index.jsp" 那么异常会转向到index.jsp而不是logon.jsp上面代码也解释了为什么配置文件exception的key属性在这里要与资源文件相对应。因为
*/
error = new ActionMessage(ae.getKey(), ex.getMessage());
这个方法传入的第一个参数为ae.getKey()即exception下的key值。如果我们继承ExceptionHandler并复写了excute方法,可以改变传入的参数值。
//我们也可以定义全局异常
<global-exceptions>
<exception key="error.login.usernull" type="com.lwf.struts.util.UserNotFoundException" path="/index.jsp" ></exception>
</global-exceptions>
那么当前应用如果配置了input属性,发生异常转向该属性所指页面,如果当前应用配置了exception配置了path则转向path所指页面,如果当前应用input,path都没有或者当前应用没配置exception,那么查找是否配置全局异常,如果有配置,那么转向到全局应用的path所指页面
在上面我们知道声明式异常默认采用ExceptionHandler来处理.但我们修改资源文件将
error.login.usernull = user must not null
改为
error.login.usernull = user must not null{0}
即增加参数我们会发现默认的异常处理并不能输出参数信息.