1. 程式人生 > >Struts2 學習筆記10--宣告式異常處理

Struts2 學習筆記10--宣告式異常處理

宣告式異常處理
在程式中出現異常可以儘管往外拋,由統一介面做頁面處理
程式碼:
服務層:丟擲異常

public List<Category> list() throws SQLException {
        Connection conn = DB.createConn();
        String sql = "select * from _category_";
        PreparedStatement ps = DB.prepare(conn, sql);
        List<Category> categories = new ArrayList<Category>();
        try {
            ResultSet rs = ps.executeQuery();
            Category c = null;
            while(rs.next()) {
                c = new Category();
                c.setId(rs.getInt("id"));
                c.setName(rs.getString("name"));
                c.setDescription(rs.getString("description"));
                categories.add(c);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw(e);
        }
        DB.close(ps);
        DB.close(conn);
        return categories;
    }
 



Action:呼叫服務,丟擲異常

public String list() throws Exception {
        categories = categoryService.list();
        return SUCCESS;
    }
 



配置宣告異常:

<package name="bbs2009_default" extends="struts-default">
    <global-results>
            <result name="error">/error.jsp</result>
        </global-results>
    <global-exception-mappings>
            <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
        </global-exception-mappings>
</package>
 


這樣丟擲的異常java.lang.Exception由struts2處理,跳轉到/error.jsp頁面。
這個異常宣告是全域性的,也可以宣告成區域性的。

原理:
Struts2利用exception的攔截器try…catch Action的呼叫,在catch中做異常的跳轉處理。
這個攔截器的實現類可以從struts2-core.jar中的struts-default.xml檔案中找到:

<package name="struts-default" abstract="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        </result-types>

        <interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
            <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/>
            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
            <interceptor name="exception
" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor "/>
 


ExceptionMappingInterceptor類中

public String intercept(ActionInvocation invocation)
{
String result;
    try
    {
            result = invocation.invoke();
    }
    catch(Exception e)
    {
            if(isLogEnabled())
                handleLogging(e);
            List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
           String mappedResult = findResultFromExceptions(exceptionMappings, e);
            if(mappedResult != null)
            {
                result = mappedResult;
             publishException(invocation, new ExceptionHolder(e));
            } else
            {
                throw e;
            }
       }
       return result;
}

ActionInvocation為Action的呼叫過程。

I18N
1、原理:
    a)ResourceBundle和Locale的概念
    b)資原始檔
    c) native2ascii

2、Struts資原始檔
    a)Action-Package-App級
    b)一般只用app
        i.在struts.xml中定義<constant name="struts.custom.i18n.resources" value="bbs2009">

            </constant>
        ii.頁面中去國際化值使用<s:property value="getText('login.username')"/>
    c)    PropertiesEditor外掛

補充:LocalizedTextUtil是Struts 2.0中國際化的工具類,<s:text>標誌就是通過呼叫它實現國際化的

國際化佔位符使用:
如:

welcome.msg=歡迎你:{0}
頁面:
<s:text name="welcome.msg">
    <s:param value="username"></s:param>
</s:text>
或
<s:text name="welcome.msg">
    <s:param>test</s:param>
</s:text>

上面value中設定變數為取得是值棧中的屬性值

動態語言切換
     通過在當前頁面加個連結並且這個連結是自動繼續返回到這個當前頁面,需要在頁面連結後面加上一個引數     

    request_locale:

<a href="admin/lang?request_locale=en_US">en</a>
<a href="admin/lang?request_locale=zh_CN">cn</a>

    前面admin/lang這個action請求是返回到當前這個頁面



標籤取出國際化值:

      <s:textfield name="name" label="%{getText('UserName')}"/>
      或者
      <s:property value="%{getText('UserName')}"/>

    其中這個呼叫getText表示OGNL表示式呼叫Action中的普通方法:

public String getText(String aTextName, String defaultValue)



資原始檔查詢順序
     之所以說Struts2的國際化更靈活是因為它可以能根據不同需要配置和獲取資源(properties)檔案。在Struts 2.0中

     有下面幾種方法:

1.使用全域性的資原始檔,方法如上例所示。這適用於遍佈於整個應用程式的國際化字元
   串,它們在不同的包(package)中被引用,如一些比較共用的出錯提示;
2.使用包範圍內的資原始檔。做法是在包的根目錄下新建名的package.properties
   和 package_xx_XX.properties檔案。這就適用於在包中不同類訪問的資源;
3.使用Action範圍的資原始檔。做法為 Action的包下新建檔名(除副檔名外)
   與Action類名同樣的資原始檔。它只能在該Action中訪問。如此一來,我們就可以
   在不同的 Action裡使用相同的properties名錶示不同的值。例如,在ActonOne中
   title為“動作一”,而同樣用title在 ActionTwo表示“動作二”,節省一些命名工夫;
4.使用<s:i18n>標誌訪問特定路徑的properties檔案。使用方法請參考我早前的文
   章《常用的Struts 2.0的標誌(Tag)介紹》。在您使用這一方法時,請注意
   <s:i18n>標誌的範圍。在<s:i18n name="xxxxx">到</s:i18n>之間,所有的
    國際化字串都會在名為xxxxx資原始檔查詢,如果找不到,Struts 2.0就會輸出
    預設值(國際化字串的名字)。

上面我列舉了四種配置和訪問資源的方法,它們的範圍分別是從大到小,而Struts 2.0在查詢國際化字串所遵循的是特定的順序 ,如圖所示:


糾正圖中查詢在struts.properties中配置的預設資原始檔,在struts2.1.6中是配置在default.properties,也可以配置在struts.xml中。

struts.xml:
    <constant name="struts.custom.i18n.resources" value="bbs2009"></constant>
    這樣就會在classpath下查詢bbs2009_locale.properties的資原始檔。

在Application級別時需要配置資原始檔名稱:
    在strut2-core.jar#org.apache.struts2.default.properties中找到