轻量级JavaEE企业应用实战(十二)

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对应的消息
注:每一步执行的前提是在上一步未搜索到的情况下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章