actionMessages(),actionError(),ActionMessage介紹

來源:互聯網
上載者:User

actionMessages(),actionError()介紹
儘管Struts架構提供了有效異常處理機制,但不能保證處理所有的錯誤,這時Struts架構會把錯誤拋給Web容器,在預設情況下Web容器會向使用者瀏覽器直接返回原始資訊。如果想避免直接讓使用者看到這些原始資訊,可以在web.xml中配置<error-page>元素,以下代碼示範了如何避免使用者看到HTTP 404、HTTP 500錯誤和Exception異常。

web.xml:
  <error-page>
    <error-code>404</error-code>
    <location>/exception/error404.jsp</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/exception/error500.jsp</location>
  </error-page>
  <error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/exception/default.jsp</location>
  </error-page>
當WEB容器捕獲到exception-type或error-code指定的錯誤時將跳到由location指定的頁面。

問題:當form bean 為動態bean時,在action中無法對form bean資料進行驗證,因為formbean沒有具體實作類別。action中無法引用
ActionError/ActionErrors/ActionMessage/ActionMessages:

有時候你需要向使用者提供相關處理資訊,包括表單驗證時發現錯誤等。
1. 相關類介紹:
ActionMessage:用於儲存一個與資源束對應的提示資訊。主要建構函式如:
ActionMessage(String message);
ActionMessage(String message,paramater)。

ActionMessages:用於儲存多個ActionMessage。並在html:errors 和html:messages中起作用。
主要建構函式:
ActionMessages().
主要方法是add(String property,ActionMessage message)
ActionMessages有一個HashMap類型messages儲存多個ActionMessage對象,每個ActionMessage對象都有唯一的一個property標識。這個property可以是自訂的任一字元串,也可以由org.apache.struts.action.ActionMessages.GLOBAL_MESSAGE指定
html:messages/html:errors使用property屬性訪問某個資源

ActionErrors:用於儲存一個與資源束對應的錯誤資訊。用法跟ActionMessages差不多。
ActionError不贊成使用。

2. 版本:
struts1.1中用ActionErrors報告錯誤,用ActionMessages提供資訊。
在struts1.2中使用ActionMessages提供資訊和錯誤,不贊成使用ActionError
struts1.3中已經沒有ActionError類了。

3. AtionErrors和ActionMessages的區別

1. ActionErrors是ActionMessages的一個子類,功能幾乎相同,不同點在於標籤<html:errors/>和<html:messages>的使用上的區別。
html:errors指定了footer和header屬性。預設值為errors.header和errors.footer,需要時可以自己指定。如果資源屬性檔案配置了 errors.header和errors.footer,則任何時候使用html:errors時開頭和結尾都是這兩個屬性對應的資源資訊。
而html:message預設情況下沒有errors.header和errors.footer值,當然可以自己指定。

2. html:errors可以根據property屬性指定顯示一個錯誤資訊。html:messages有一個必添項id。html:messages不能直接顯示資訊,它將選出的資訊放入一個用id標識的Iterator對象裡,然後在用ben:write或JSTL c:out標籤顯示每個資訊.例如:
<html:messages message="true" id="msg">
    <c:out value="${msg}"/><br />
</html:messages>

3. 具體的一個例子:
接受輸入頁面input.jsp:

  <html:form action="/errormessage/input">
    phoneNumber : <html:text property="phoneNumber"/> <html:errors     property="<%=org.apache.struts.action.ActionMessages.GLOBAL_MESSAGE %>"/><br/>
  <html:submit/><html:cancel/>
  </html:form>

struts-config.xml:
  <form-beans >
    <form-bean name="inputForm" type="cn.rolia.struts.form.errorexception.InputForm" />
  </form-beans>
  <action-mappings >
    <action
      attribute="inputForm"
      input="/errormessage/input.jsp"
      name="inputForm"
      path="/errormessage/input"
      scope="request"
      type="com.yourcompany.struts.action.errormessage.InputAction"
      validate="false">
      <forward name="success" path="/errormessage/success.jsp" />
    </action>
  </action-mappings>

InputAction.java:

public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) {
  cn.rolia.struts.form.errorexception.InputForm inputForm = (cn.rolia.struts.form.errorexception.InputForm) form;// TODO Auto-generated method stub
  String phoneNumber = inputForm.getPhoneNumber();
  if(phoneNumber.length()<4){
  ActionErrors messages = new ActionErrors();
    messages.add(org.apache.struts.action.ActionMessages.GLOBAL_MESSAGE,new ActionMessage("error.errormessage.input"));
    this.saveErrors(request, messages);
    return mapping.getInputForward();
  }

  return mapping.findForward("success");
}
解說:使用者輸入手機號碼,頁面跳轉到InputAction控制層進行處理,若輸入資料小於4,則建立一個ActionMessage類儲存相關錯誤資訊。然後再建立ActionErrors類將此ActionMessage放入ActionErrors。再調用Action的saveErrors方法將此ActionErrors儲存的request範圍裡,然後返回input.jsp頁面要求重新輸入並用html:errors提示錯誤資訊。

4. Action包含saveErrors()方法和saveMessages()方法。如果建立的ActionErrors則應該調用saveErrors(),若建立的是ActionMessages則應該調用saveMessages()方法。
saveErrors()接收ActionMessages而不是ActionErrors;同時將其儲存在request中並用一個由org.apache.struts.Globals.ERROR_KEY指定的常量” org.apache.struts.Globals.ERROR_KEY”標識這個ActionMessages,便於html:errors尋找。saveMessages()方法接收ActionMessages同時將其儲存在request中並用一個由org.apache.struts.Globals.MESSAGE_KEY指定的常量” org.apache.struts.Globals.MESSAGE_KEY”標識這個ActionMessages,進而讓html:messages從常量Globals.ERROR_KEY中遍曆擷取資訊。可以將其屬性message設定為true,那麼它將從常量Globals.MESSAGE_KEY中遍曆擷取資訊。

5. 預設情況下html:messages從
如果你想將資訊儲存在session裡而不是request,struts1.2提供了
struts1.1沒有的saveMessages(HttpSession session, ActionMessages messages)方法和saveErrors(javax.servlet.http.HttpSession session, ActionMessages errors)方法。
InputAction.java:

public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) {
cn.rolia.struts.form.errorexception.InputForm inputForm = (cn.rolia.struts.form.errorexception.InputForm) form;// TODO Auto-generated method stub
  String phoneNumber = inputForm.getPhoneNumber();
  if(phoneNumber.length()<4){
    ActionErrors messages = new ActionErrors();
    messages.add(org.apache.struts.action.ActionMessages.GLOBAL_MESSAGE,new ActionMessage("error.errormessage.input"));
    this.saveErrors(request.getSession(true), messages);
    return mapping.getInputForward();
  }

  return mapping.findForward("success");
}

 

--------------------------------------------------

 

ActionForm是表單的物件化,有關於表單資料的完整性檢查工作該在其中進行,例如使用者是否填寫了所有的欄位,ActionForm中所有的屬性是否被設定了,您可以重新定義ActionForm的validate()方法來進行這項工作,例如:
代碼:
package onlyfun.caterpillar;

import javax.servlet.http.*;
import org.apache.struts.action.*;

public class UserForm extends ActionForm {
    protected String name;
    protected String password;

    public void setName(String name) {
        this.name = name;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getName() {
        return name;
    }
    public String getPassword() {
        return password;
    }
    public void reset(ActionMapping mapping, HttpServletRequest req) {
        name = null;
        password = null;
    }

    public ActionErrors validate(ActionMapping mapping,
                                 HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();

        if(getName() == null || getUsername().length() < 1) {
            errors.add("name",new ActionError("error.name.required"));
        }
        if(getPassword() == null || getPassword().length() < 1) {
            errors.add("password",new ActionError("error.password.required"));
        }

        return errors;
    }
}

當使用者發送表單,而表單中有欄位沒有填寫時,則請求中會包括參數名稱,但是值為空字串,如果ActionForm具有某些屬性,而表單並沒有發送對應的參數,則不會設定ActionForm中對應的屬性,這些屬性將為null,我們的validate()中主要在檢查這兩個情況。

validate()方法會傳回ActionErrors物件,ActionErrors可以儲存ActionError的訊息,每一個ActionError會查詢資源檔中的key-value對應,當validate()丟回ActionErrors物件時,ActionServlet就不會繼續進行接下來的工作,而是導回structs-config.xml所設定的位置,例如:
代碼:
    <global-forwards>
        <forward
            name="welcome"
            path="/Welcome.do"/>
    </global-forwards>
                                                                                               
    <form-beans>
        <form-bean
            name="userForm"
            type="onlyfun.caterpillar.UserForm"/>
    </form-beans>
                                                                                               
    <action-mappings>
        <action
            path="/Welcome"
            type="org.apache.struts.actions.ForwardAction"
            parameter="/pages/Welcome.jsp"/>
                                                                                               
        <action
            path="/LoginAction"
            type="onlyfun.caterpillar.LoginAction"
            name="userForm"
            validate="true"
            input="/pages/Welcome.jsp">
            <forward name="greeting" path="/pages/greeting.jsp"/>
        </action>
    </action-mappings>

為了要能使用validate()方法,<action>中的validate屬性必須設定為true,而input屬性也是必要的,當validate()傳回ActionErrors時,就會forward至input屬性所設定的位置,ActionErrors中的訊息,我們可以使用<html:errors/>標籤來顯示,待會就會看到。

ActionForm中驗證了屬性為null及空字串的可能,這是資料完整性的驗證,接下來我們要驗證資料的正確性,是否符合我們所設定的名稱與密碼,我們改寫前一個主題的LoginAction,看看寫法有何不同:
代碼:
package onlyfun.caterpillar;

import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.commons.beanutils.*;

public class LoginAction extends Action {
    public ActionForward execute(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    throws Exception {

        String name = (String) PropertyUtils.getSimpleProperty(form, "name");
        String password = (String) PropertyUtils.getSimpleProperty(form, "password");

        if(!(name.equals("caterpillar") && password.equals("1234"))) {
            ActionMessages messages = new ActionMessages();
            messages.add(ActionMessages.GLOBAL_MESSAGE,
                         new ActionMessage("message.namepass.notmatched"));
            saveMessages(request, messages);
            return mapping.findForward("welcome");
        }
        else {
            request.getSession().setAttribute("valid_user", form);
            return mapping.findForward("greeting");
        }
    }
}

在這次的程式中,我們使用了org.apache.commons.beanutils中的PropertyUtils類別來協助我們取ActionForm中的值,好處是不用理會ActionForm真正的形態,PropertyUtils會自動幫我們判斷,getSimpleProperty()傳回的是Object,我們將之轉換為String。

ActionMessages是Struts 1.1所新增的類別,它變成了ActionErrors的父類別,同樣的,ActionMessage也是Struts 1.1新增的類別,它是ActionError的父類別,資料的格式與完整性檢查在ActionForm中我們已經驗證了,接下來我們在Action中檢查是否符合名稱與密碼,如果不符合就加入相關的訊息。

在Struts 1.1中特意將Message與Error區別,該是認定所謂的Error是使用者的輸入在完整性或格式等上有誤,而Message是指輸入的資料基本上沒有錯誤,但不能符合後續的商務處理。

為了要能夠顯示錯誤與訊息,我們必須在application_zh.properties中加入key-value對應,如下:
代碼:
# -- error --
error.name.required=沒有輸入名稱
error.password.required=沒有輸入密碼
                                                                                               
#-- message --
message.namepass.notmatched=名稱與密碼不正確

為了要能使用中文,記得使用native2ascii工具程式進行轉換,接下來我們來看看我們的Welcome.jsp如何撰寫,要注意的是在<html:errors/>與<htm:messages/>的使用:
代碼:
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@page contentType="text/html; charset=Big5"%>
<html:html locale="true">
<head>
<title><bean:message key="welcome.title"/></title>
<html:base/>
</head>
<body bgcolor="white">
<html:errors/>

<html:messages id="messages" message="true">
    <bean:write name="messages"/>
</html:messages>

<h3>請登入</h3>

<html:form action="/Login">
    名稱:<html:text property="name" size="20"/><br>
    密碼:<html:password property="password" size="20"/><br>
    <html:submit/> <html:reset/>
</html:form>

</body>
</html:html>

如果由於ActionForm傳回ActionErrors物件而返回Welcome.jsp,則<html:errors/>標籤會顯示ActionErrors中的相關錯誤訊息,我們利用<html:messages/>來檢查返回中是否也包括ActionMessages物件,如果有的話就取出並使用<bean:write/>標籤顯示之。

下面是執行時未填寫欄位所顯示的錯誤訊息的一個例子:
代碼:
<html lang="zh">
<head>
<title>哈囉!Struts!</title>
<base href="http://localhost:8080/HelloStruts/pages/Welcome.jsp">
</head>
<body bgcolor="white">
<UL>
<LI>沒有輸入名稱
</LI><LI>沒有輸入密碼
</LI></UL>

<h3>請登入</h3>

<form name="UserForm" method="post" action="/HelloStruts/Login.do">
    名稱:<input type="text" name="name" size="20" value=""><br>
    密碼:<input type="password" name="password" size="20" value=""><br>
    <input type="submit" value="Submit"> <input type="reset" value="Reset">
</form>

</body>
</html>

注意到ActionErrors在Struts 1.2之後可能會被標示為deprecated,將來可能會改以ActionMessages取代,所以<html:errors/>在將來必須以下面的方式來取代:
代碼:
<html:messages id="msg" >
  <bean:write name="msg"/>
</html:messages>

在之前的例子中,在<html:messages/>的屬性上設定message為true,這表示顯示ActionMessages的內容:
代碼:
<html:messages id="messages" message="true">
    <bean:write name="messages"/>
</html:messages>

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.