Struts2的异常处理机制
我们在execute犯法中使用try—catch方法可以捕获异常,当捕捉到指定异常时,系统返回对应逻辑视图名。这种方式完全是手动处理异常,可维护性不好;
Struts2允许通过struts.xml文件来配置异常的处理,通过此方法我们无需在execute中进行异常捕捉,仅需在struts.xml中配置异常处理;为了使用这种机制,需要打开异常映射功能需要的拦截器
<interceptors>
<interceptor name="exception" class="com.opensymphony
.xwork.interceptor.ExceptionMapping.Interceptor" />
<interceptor-stack name="defaultStack"
<interceptor-ref name="exception" />
</interceptor-stack>
</interceptors>
声明式异常捕捉
Struts2异常处理机制,在struts.xml中配置exception-mapping元素,需要以下属性:
exception:指定该异常映射所设置的异常类型
result:指定Action出现该异常时,系统返回result属性值对应的逻辑视图名
public class LoginAction implements Action {
...
if(getUsername().equalsIngoreCase("sql")) {
throw new java.sql.SQLException("用户名不能为SQL");
}
if(getUsername().equalsIngoreCase("user")) {
throw newe MyException("自定义异常");
}
}
<global-exception-mappings>
<exception-mapping exception="java.sql.SQLException" result="sql">
<exception-mapping exception="java.lang.Exception" result="root">
<action name="login" class="com.action.LoginAction">
<exception-mapping exception="com.exception.MyException">
...
</action>
</global-exception-mappings>
输出异常信息
<s:property value="exception" /> 输出异常对象本身
<s:property value="exceptionStack" /> 输出异常堆栈信息
使用国际化文件
<constant name="struts.custom.i18n.resources" value="messageResource" />
输出:
<s:text name="propertiesKey" />
输出带占位符的国际化消息:使用<s:param />标签来替代占位符的值,支持多个
welcomeMsg = {0},您好,现在时间是{1}
<jsp:useBean id="d" class="java.util.Date" scope="page" />
<s:text name="welcomeMsg">
<s:param><s:property value="username"></s:param>
<s:param>${d}</s:param>
</s:text>
另外方式:
welcomeMsg = ${username},您好,现在时间是{0}
<s:text name="welcomeMsg">
<s:param>${d}</s:param>
</s:text>
加载资源文件的方式
为Struts2应用指定包范围资源文件的方法:
在包的根路径下建立多个文件名为page_language_country.properties的文件,一旦建立了这个系列的国际化资源文件,应用中处于该包下的所有Action都可以访问该资源文件
注:如果有中文和英文两种资源文件,会根据语言环境优先选择
临时指定资源文件
<s:i18n name="tmp">
<s:text name="loginPage">
</s:i18n>
<s:i18n name="tmp">
<s:form action="login">
<s:textfield name="username" key="user"> //key为资源文件左边部分
<s:textfield name="password" key="pass">
<s:submit key="login" />
</s:form>
</s:i18n>
加载资源文件的效率
假设:我们需要在ChildAction中访问国际化文件
1.优先加载系统中保存在ChildAction的类文件相同位置
2.假如ChildAction有父类,则加载parentAction的类相同位置,且baseName为ParentAction的系列资源文件
3.假如ChildAction由实现接口,则加载系统保存在IChildAction的类相同文件,且baseName为IChildAction的系列资源文件
4.假如ChildAction有实现接口ModelDriven,则对于getModel()方法返回的对象,重新执行第一步操作
5.查找当前包下baseName为package的系列资源文件
6.沿着当前包上溯,知道最顶层包来查找baseName为package的系列资源文件
7.查找struts.custom.i18n.resources常量指定baseName的系列资源文件
8.系统停止搜索,直接输出该key对应的消息
注:每一步执行的前提是在上一步未搜索到的情况下