1. 程式人生 > 其它 >struts2框架詳解

struts2框架詳解

struts2框架(1)---struts2入門

struts2框架

如果你之前在MVC模式的時候一直都是通過servlet,獲取和返回資料,那麼現在開始學習struts2框架,

Struts是一個實現MVC設計模式的優秀的框架。它的許多優點我就不說了。

我用自己做的一張圖說明servlet和struts2的區別。

寫一個最基本的開發步驟,完成開發。

(1)建立WEB 工程

(2)匯入必要jar包

(3)編寫JSP 頁面

(4)編寫Action 伺服器端處理邏輯

(5)進行框架配置web.xml、struts.xml

(6)執行測試

(1)建立WEB 工程

這步還是很正常一樣,建立一個普通web工程。如圖:

(2)匯入必要jar包

首先我要告訴你到哪裡去下載這個框架:在apache官網,你百度struts2下載就可以找到了。

Struts執行必要jar包介紹:

開發中為了方便匯入,可以使用app/struts2-blank.war 攜帶jar包

(3)編寫JSP 頁面

在webRoot下新建一個Demo檔案,網頁先訪問start.jsp之後通過框架返回到result頁面

start.jsp介面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
  <head>
  </head>
  <body>
    <h1>請求發起的頁面</h1>
    <!-- 發起一個請求 訪問Struts2框架 -->
    <!-- Struts2請求  預設是以.action結尾 -->
    <a href="${pageContext.request.contextPath }/hello.action">訪問Struts2入門程式</a>
  </body>
</html>

result.jsp介面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
  <head>
  </head> 
  <body>
    <h1>處理完成的結果頁面</h1>    
  </body>
</html>

(4)編寫Action 伺服器端處理邏輯

這裡就是通過java建立一個類,該類可以說是action最普通的一個類

1 package com.yudian.struts;
2 public class HelloAction {
3      public String execute() throws Exception{  //這裡取execute代表預設執行這個方法
4             System.out.println("我是執行的內容...");
5              return  "excutesuccess";   //有返回值,我們用來跳轉頁面
6         }
7 }

(5)進行框架配置web.xml、struts.xml

配置檔案才是核心關鍵,先配置web.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <display-name></display-name>    
 8   <!-- 配置Struts2的前端控制器 --><!--filter-class裡面很關鍵,固定  -->
 9    <filter>
10        <filter-name>struts2</filter-name>
11        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
12    </filter>
13    <filter-mapping>
14        <filter-name>struts2</filter-name>
15        <url-pattern>/*</url-pattern>
16    </filter-mapping>
17   
18   
19   <welcome-file-list>
20     <welcome-file>index.jsp</welcome-file>
21   </welcome-file-list>
22 </web-app>

在配置struts.xml,注意了這個是放在src下面而不是包下面

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5 
 6 <struts>
 7     <package name="default"  extends="struts-default">
 8      <!-- 3.預設Action  和Action的預設處理類 -->
 9         <!-- 1.初步認識Struts2 --><!-- 這裡hello一定要和jsp中hello。action一致才能找到 -->
10        <action name="hello" class="com.yudian.struts.HelloAction">
11             <result name="excutesuccess">/demo/result.jsp</result>
12        </action>  <!-- result代表如果返回值為 excutesuccess則跳轉頁面-->            
13     </package>
14 </struts>

(6)執行測試

先通過瀏覽器訪問start介面:

當點選:訪問Struts2入門程式連線直接跳轉到了result.jsp

執行結果:

這上面是一個最基本的struts框架的運用,很簡單,主要是供大家理解,關於每一個細節我會在接下面慢慢補充.

歡迎大家的留言給出指點意見,謝謝!

Struts2系列筆記(2)---struts.XML

Struts2.xml

本篇部落格主要講struts.xml中package下的標籤和標籤屬性,主要分以下四個部分說明:

(1)action的配置基本屬性

(2)同一個Action類中不同方法滿足不同的action邏輯

(3)萬用字元解決多業務問題

(4)配置處理結果:

(1)action的配置基本屬性

 1  <!--首先宣告本片文章基本還是參考http://www.cnblogs.com/Nouno/p/5683447.html的部落格,特此說明-->
 2 <?xml version="1.0" encoding="UTF-8"?>  
 3   <!DOCTYPE struts PUBLIC  
 4       "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
 5       "http://struts.apache.org/dtds/struts-2.3.dtd">  
 6   <struts>  
 7       <!-- /primer/helloWorldAction.action  
 8           package:包  
 9               * name:包名,唯一的,必選項  
10               * namespace:名稱空間,唯一的,相當於房間號。可選項,省略情況下是"/"。頁面中請求連線的前半部分  
11               * extends:繼承  
12                  * extends="struts-default":struts2框架底層提供的核心包struts2-core-2.3.3.jar下的struts-default.xml檔案  
13                  * 為什麼要繼承這個struts-default.xml檔案?  
14                      * 因為struts2框架底層提供的struts-default.xml聲明瞭所有的攔截器和攔截器棧,  
15                                 知道在struts2框架執行時執行struts-default.xml檔案中的攔截器棧。  
16                      * 如果不繼承struts-default.xml檔案,就沒有辦法使用struts2框架提供的所有攔截器  
17          -->  
18       <package name="primer" namespace="/" extends="struts-default">  
19            
20          <!--   
21                   如果找不到對應的action名的時候,配置預設要執行的action   
22                 * name:指定action的名稱  
23          -->   
24          <default-action-ref name="error"></default-action-ref> 
25 27 <action name="error" class="com.yyc.struts.action.ErrorAction"> 28 <result name="error">/error.jsp</result> 29 </action> 30 <!-- 31 action: 32 * name:對應頁面中請求連線的後面半部分,這裡表示jsp請求連結為hello.action才會和它匹配 33 * class:對應要執行的類的完整路徑 ,表示Action類的完整路徑,相當於之前的servlet類 34 *method:對應的class類中要執行的方法,預設執行method="execute()" 35 --> 36 <action name="hello" class="cn.yht.primer.HelloWorldAction" method="execute()"> 37 <!-- 38 result:結果型別 ,可以用來把Action類處理好的資料跳轉到某介面 39 * name:對應的是執行的類的方法的返回值 40 public String execute() throws Exception { 41 System.out.println("HelloWorldAction ************* execute()"); 42 return "success"; 43 } 44 * 預設判斷name="success",後半部分的文字內容:要轉向到的頁面 45 --> 46 <result name="success">/primer/success.jsp</result> 47 </action> 48 <!-- 49 沒有為action指定class 50 * 在struts2框架底層的struts-default.xml檔案中,配置了預設執行的類 51 com.opensymphony.xwork2.ActionSupport 52 public String execute() throws Exception { 53 return SUCCESS; 54 } 55 * 實際上,預設執行的是底層提供的ActionSupport類的execute()方法 56 * result結果型別,預設是根據struts2框架底層提供的ActionSupport類的execute()方法返回值,進行跳轉 57 --> 58 <action name="actionNoClass"> 59 <result name="success">/primer/success.jsp</result> 60 </action> 61 </package> 62 </struts>

(2)同一個Action類中不同方法滿足不同的action邏輯

 1 <!--這個Action中有兩個方法
 2 public class ProductAction extends ActionSupport {
 3     public String add(){
 4         System.out.println("新增商品");
 5         return NONE;
 6     } 
 7     public String del(){
 8         System.out.println("刪除商品");
 9         return NONE;
10     }  
11 }-->
12 
13 <!-- 多個業務需求 -->
14        <action name="addBook" class="com.guigu.struts.action.BookAction" method="add"></action>
15        <action name="delBook" class="com.guigu.struts.action.BookAction" method="del"></action>
16 <!--這樣確實能夠實現一個Action類中的不同方法,都能被呼叫
17    但是你也許會注意到,每呼叫一個方法都需要配置action-->

(3)萬用字元解決多業務問題

 1 <!--這裡是jsp檔案  
 2      <h1>客戶管理</h1>
 3      <a href="${pageContext.request.contextPath }/customer_add">新增客戶</a><br/>
 4      <a href="${pageContext.request.contextPath }/customer_del">刪除客戶</a><br/>
 5      <a href="${pageContext.request.contextPath }/customer_edit">修改客戶</a><br/>
 6      <a href="${pageContext.request.contextPath }/customer_find">查詢客戶</a><br/>
 7      -->
 8  <!-- 使用萬用字元解決多業務問題 -->
 9        <!-- method 屬性{1}是取第一個* ,這樣就只需要寫一個action就可以了,我們只要在Action類中寫好相對應的方法即可-->
10        <action name="customer_*" class="com.guigu.struts.action.CustomerAction" method="{1}">
11           <result >/demo1/{1}.jsp</result>
12        </action>

(4)配置處理結果:

Struts2的Action處理使用者請求結束後,返回一個普通字串-邏輯檢視名,必須在struts.xml檔案中完成邏輯檢視和物理檢視資源的對映,才可讓系統轉到實際的檢視資源。

Struts2通過在struts.xml檔案中使用<result …/>元素來配置結果。Struts2提供了兩種結果。

a.區域性結果:將<result …/>作為<action …>元素的子元素配置。

b.全域性結果:將<result …/>作為<global-results …>元素的子元素配置。

在package元素中配置<global-results>子元素:

<!--全域性result(global-results)
有很多時候一個<result>可供很多<action>使用,這時可以使用<global-results>標籤來定義全域性的<result>l。執行順序:當一個Action返回的String沒有相應的<result>與之對應,Struts2就會查詢全域性的<result>。-->

<global-results>

<result name="error">/Error.jsp</result>
<result name="invalid.token">/Error.jsp</result>
<result name="login" type="redirect-action">Logon!input</result>

</global-results>

歡迎大家留言指點!

Struts2框架(3)---Action類的3種書寫方式

Action類的3種書寫方式

本文主要寫有關寫Action類的3種書寫方式:

(1)第一種Action可以是POJO(簡單模型物件) 不需要繼承任何父類 也不需要實現任何介面

(2)實現Action介面

(3)繼承ActionSupport(推薦)

那我們先來書寫第一種:

(1)第一種Action可以是POJO(簡單模型物件) 不需要繼承任何父類 也不需要實現任何介面

1 //這裡其實就是一個普通的類,類裡面的方法可以任意寫,如果寫execute()方法那就代表預設執行它
2 public class RequestAction1 {   
3     //提供滿足條件的方法   excute方法
4     //public 範圍的    帶有String返回值的 無參的方法
5     public String execute(){
6         System.out.println("測試方式一");
7         return null;//null表示不進行跳轉
8     }
9 }

(2)實現Action介面

 1 import com.opensymphony.xwork2.Action;
 2 public class RequestAction2  implements Action{
 3 
 4     public String execute() throws Exception {
 5         System.out.println("方式二 實現Action介面 成功執行....");
 6         return SUCCESS;
 7     }
 8 }
 9 /**
10  * Action介面中一共有5個五種邏輯檢視 和一個方法分別如些:
11  * public abstract interface com.opensymphony.xwork2.Action {
12                                                                資料處理成功(成功的跳轉頁面)
13       public static final java.lang.String SUCCESS = "success";
14                                                               頁面不進行跳轉 return null 
15       public static final java.lang.String NONE = "none";
16                                                                資料處理傳送錯誤(錯誤頁面)
17       public static final java.lang.String ERROR = "error";
18                                                         使用者處理資料 資料有誤 用於表單的校驗
19       public static final java.lang.String INPUT = "input";
20                                                                       主要是許可權認證
21       public static final java.lang.String LOGIN = "login";
22 
23   public abstract java.lang.String execute() throws java.lang.Exception;
24  }
25  */

(3)繼承ActionSupport(推薦)

 1 import com.opensymphony.xwork2.Action;
 2 import com.opensymphony.xwork2.ActionSupport;
 3 //為什麼推薦ActionSupport,在Action中如果使用基礎ActionSupport的方式 可以使用表單的校驗 錯誤資訊的設定 和國際化資訊 三個重要的功能。
 4 public class RequestAction3 extends ActionSupport {
 5     @Override
 6     public String execute() throws Exception {
 7         System.out.println("方式三 繼承ActionSupport完成 書寫"); 
 8         return super.execute();//返回SUCCESS
 9     }
10 }
11 /**ActionSupport類的特點,點進去發現它實現了許多的介面
12  * public class ActionSupport implements Action, Validateable, 
13  * ValidationAware, TextProvider, LocaleProvider, Serializable
14  * 這麼多介面說明它不簡單
15  * 
16  */

關於action類的建立我就說這麼多!請大家多指點!

Struts2框架(4)---Action類訪問servlet

Action類訪問servlet

Action類有三種方式servlet:

(1)間接的方式訪問Servlet API ---使用ActionContext物件

(2) 實現介面,訪問Action時完成注入

(3)直接通過ServletActionContext獲得Servlet的API

下面我來講第一種:

(1)間接的方式訪問Servlet API ---使用ActionContext物件

Struts2中提供了一個ActionContext類(當前Action的上下文物件),通過這個類可以訪問Servlet API。下面是該類中提供的幾個常用方法:

1.public static ActionContext getContext() :獲得當前Action的ActionContext例項。
2.public Object get(Object key) :此方法類似於呼叫HttpServletRequest的getAttribute(String name)方法。
3.public void put(Object key, Object value) :此方法類似於呼叫HttpServletRequest 的setAttribute(String name, Object o)。
4. public Map getParameters() :獲取所有的請求引數。類似於呼叫HttpServletRequest物件的getParameterMap() 方法。
5. public Map getSession() :返回一個Map物件,該Map物件模擬了HttpSession例項。
6. public void setSession(Map session) : 直接傳入一個Map例項,將該Map例項裡的key-value對轉換成session的屬性名-屬性值對。
7. public Map getApplication() :返回一個Map物件,該物件模擬了該應用的ServletContext例項。

8. public void setApplication(Map application) :直接傳入一個Map例項,將該Map例項裡

的key-value對轉換成application的屬性名- 屬性值對。

 1 import java.util.Map
 2 import com.opensymphony.xwork2.ActionContext;
 3 import com.opensymphony.xwork2.ActionSupport;
 4 public class LoginAction1  extends ActionSupport{
 5  
 6     public String login() throws Exception{
 7         //獲取ActionContext
 8         ActionContext actionContext =ActionContext.getContext();
 9         //1.獲取表單的請求引數
10         Map<String, Object> parameters=actionContext.getParameters();
11         //因為使用者名稱username可能有多個,所以返回陣列
12         String [] values =(String[]) parameters.get("username");
13         System.out.println("使用者名稱是:"+values[0]);
14         
15         //2.存取request 的Attribute
16         actionContext.put("company", "雨點的名字"); //相當於request.setAttribute("","");
17         System.out.println(actionContext.get("company"));
18         
19         //3.存取session 的Attribute
20         Map<String, Object> sessionMap=actionContext.getSession();
21         sessionMap.put("age", 11);//相當於session.setAttribute("","");
22         System.out.println(sessionMap.get("age"));
23         
24         //4.存取application的Attribute
25          Map<String, Object> applicationMap=actionContext.getApplication();
26          applicationMap.put("info", "下週考試第二階段");
27          System.out.println(applicationMap.get("info"));       
28         return SUCCESS;      
29     }
30 }

(2) 實現介面,訪問Action時完成注入

如果是實現結構注入一般需要實現3個介面

(1)ServletContextAware: 實現此介面的Action可直接訪問Web應用的ServletContext例項;

(2)ServletRequestAware: 實現此介面的Action可直接訪問Web應用的HttpServletRequest例項;

(3)ServletResponseAware: 實現此介面的Action可直接訪問Web應用的HttpServletResponset例項

 1 import java.util.Map;
 2 
 3 import javax.servlet.ServletContext;
 4 import javax.servlet.ServletResponse;
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletResponse;
 7 import org.apache.struts2.interceptor.RequestAware;
 8 import org.apache.struts2.interceptor.ServletRequestAware;
 9 import org.apache.struts2.interceptor.ServletResponseAware;
10 import org.apache.struts2.util.ServletContextAware;
11 
12 import com.opensymphony.xwork2.ActionContext;
13 import com.opensymphony.xwork2.ActionSupport;
14 
15 public class LoginAction2 extends ActionSupport implements ServletRequestAware,
16      ServletContextAware,ServletResponseAware {
17    
18     private HttpServletRequest request;
19     
20     private ServletContext context;
21     
22     private HttpServletResponse response;
23     
24     public String login() throws Exception{
25         //1.獲取表單的請求引數
26         System.out.println(request.getParameter("username"));
27         
28         //2.存取request 的Attribute
29         request.setAttribute("company","hzgg" );
30         
31         //3.存取session 的Attribute
32         request.getSession().setAttribute("age", 50);
33         
34         //4.存取application的Attribute
35         context.setAttribute("info", "今天下午你們可以出去玩");
36         
37         return SUCCESS;
38         
39     }
40      //實現ServletRequestAware介面必須實現的方法
41     public void setServletRequest(HttpServletRequest request) {
42         this.request=request;
43     }
44      //實現ServletContextAware介面必須實現的方法
45     public void setServletContext(ServletContext context) {
46         this.context=context;
47     }
48      //實現ServletResponseAware介面必須實現的方法
49     public void setServletResponse(HttpServletResponse response) {
50         this.response=response;
51     }
52 
53 }

(3)使用ServletActionContext工具類訪問Servlet API

在ServletActionContext工具類中常用的幾個方法(都是靜態方法):

(1)PageContext getPageContext(): 取得應用的PageContext物件;
(2)HttpServletRequest getRequest(): 取得該應用的HttpServletRequest物件;
(3)HttpServletRequest getResponse(): 取得該應用的HttpServletResponse物件;
(4)ServletContext getServletContext(): 取得該應用的ServletContext物件。
 1 import org.apache.struts2.ServletActionContext;
 2 import com.opensymphony.xwork2.ActionSupport;
 3 
 4 public class LoginAction3 extends ActionSupport {
 5 
 6     public String login() throws Exception {
 7         // 1.獲取表單的請求引數
 8        String username= ServletActionContext.getRequest().getParameter("username");
 9        System.out.println(username);
10        
11        // 2.存取request 的Attribute
12        ServletActionContext.getRequest().setAttribute("company", "haha");
13 
14         // 3.存取session 的Attribute
15        ServletActionContext.getRequest().getSession().setAttribute("age", 40);
16 
17         // 4.存取application的Attribute
18        ServletActionContext.getServletContext().setAttribute("info", "今天下課你們可以約會去了");
19 
20         return SUCCESS;
21     }
22 }

下面我來寫一個用第三種方法實現訪問servlet,從jsp到struts.xml在到Action類,最後從頁面顯示結果供大家學習:

jsp介面:

start.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
   <head>
  </head>
  <body>
    <form action="${pageContext.request.contextPath }/hello.action">
            姓名:<input type="text">
            <input type="submit" value="提交">
    </form>
  </body>
</html>

struts.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE struts PUBLIC
 3       "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4       "http://struts.apache.org/dtds/struts-2.3.dtd">
 5    <struts>
 6       <package name="default"  extends="struts-default">
 7         <action name="hello" class="com.guigu.struts.action2.LoginAction3" method="login">
 8            <result>/result.jsp</result>
 9         </action>            
10       </package>
11  </struts>
result.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
  <head>
  </head>
  <body>
   <p>${company}</p>
   <p>${age}</p>
   <p>${info}</p>
  </body>
</html>

  執行結果如下:

當點選提交的時候

發現數據已經從Action類中轉發到了介面

這篇文章就講到這裡,歡迎大家指點和點評!

Struts2框架(5)---result結果集

result結果集

上一篇文章主要講Struts2框架(4)---Action類訪問servlet這篇主要講result結果集

在Struts.xml中的result元素指的是:指定動作類的動作方法執行完後的結果檢視.

(1)區域性結果和全域性結果

他有兩個屬性:

  name:字串,與動作方法返回的值一致。預設是success

  type:指定處理結果的結果型別的別名。預設值是dispatcher

首先處理結果分為兩種,一種是區域性結果一種是全域性結果。

區域性結果:

 <action name="login" class="com.study.struts.action2.LoginAction" method="login">
       <!--在action內配置的是針對某個Action起作用的區域性的配置 -->
         <result name="success" >/demo2/result.jsp</result> 
 </action>

全域性結果:

 <!--全域性結果檢視:包中所有的action都能使用同一個檢視 -->
      <global-results>
       <!--  <result name="success">/index.jsp</result> -->
        <!-- a.預設的結果集型別 -->
       <result name="error" type="dispatcher">/error.jsp</result> 
        <!-- b.轉發到另外一個Action -->
       <!--  <result name="success" type="chain">hello</result> -->
       <!-- c.重定向到jsp頁面 -->
        <!-- <result name="success" type="redirect">/index.jsp</result> -->
        <!-- d.重定向到action -->
        <!-- <result name="success" type="redirectAction">hello</result> -->
      </global-results> 

這裡同時要思考一個問題,如果你返回的是success,但在全域性和區域性都配置了,那麼會執行哪個呢?

按照規則,先看區域性變數是否配置,配置了就執行區域性變數的,而且一般成功的結果集不會配置成全域性的,只有在錯誤(error)的時候可能配置全域性

(2)結果型別

在struts-default.xml 配置常用結果型別有10種:

當然在我們實際開發中運用的比較多的也就4.5種,這裡我就寫4種

舉例:

 1        <action name="main">
 2             <result type="dispatcher">/main.jsp</result>
 3         </action>
 4         
 5         <action name="main2">
 6             <result type="redirect">/main2.jsp</result>
 7         </action>
 8         
 9         <action name="main3">
10             <result type="chain">main3</result>
11         </action>
12         
13         <action name="main4">
14             <result type="redirectAction">main4</result>
15         </action>

a)dispatcher(預設) forward到一個JSP或者HTML或者其他結果頁面,不能是Action

請求轉發,底層呼叫RequestDispatcher的forward() 方法,dispatcher是result的type屬性預設值,通常用於轉向一個JSP。

b)redirect 重定向到結果檢視 重定向到一個URL

重定向,新頁面無法顯示Action中的資料,因為底層呼叫 response.sendRedirect("")方法,無法共享請求範圍內的資料。

c)chain 伺服器forward(轉發)到一個另一個Action

將action的帶著原來的狀態請求轉發到新的action,兩個action共享一個ActionContext,actionName指定轉向的新的Action的名字,method指定轉向哪個方法,

namespace指定新的Action的名稱空間,不寫表示與原Action在相同的名稱空間;

d)redirectAction 重定向到另外一個Action

重定向到另一個Action,引數與chain用法相同,允許將原Action中的屬性指定新名稱帶入新Action中,可以在Result標籤中新增 <param name=”b”>${a} </param>,

這表示原Action中的變數a的值被轉給b,下一個Action可以在值棧中使用b來操作

(3)重定向和轉發的區別?

1 請求轉發只能將請求轉發給同一個WEB應用中的元件,而重定向還可以重新定向到同一站點不同應用程式中的資源,甚至可以定向到一絕對的URL。

2 重定向可以看見目標頁面的URL,轉發只能看見第一次訪問的頁面URL,以後的工作都是有伺服器來做的。

3 請求響應呼叫者和被呼叫者之間共享相同的request物件和response物件,重定向呼叫者和被呼叫者屬於兩個獨立訪問請求和響應過程。

4 重定向跳轉後必須加上return,要不然頁面雖然跳轉了,但是還會執行跳轉後面的語句,轉發是執行了跳轉頁面,下面的程式碼就不會在執行了。

(4)結果型別中redirect和redirectAction 首先要知道: 只要是重定向,那麼之前凡是儲存在request裡面的東西就全都消失了
因為重定向實際是傳送第二個請求,故請求中的東西也就不會出現在第二個請求裡面了
也就是說重定向是不共享request的東西,重定向後的頁面中無法接收request裡的東西 區別:

redirect是在處理完當前Action之後,重定向到另外一個實際的物理資源
redirectAction也是重定向,但它重定向到的是另外一個Action

(5)思考,在我們實際開發中是麼時候使用重定向什麼時候轉發?

我個人觀點:就是你在request作用域進行相關操作後,需要從資料庫返回進行回顯的話,比如說你在點選修改的時候就需要把資訊回顯,這就建議轉發,因為用重定向是無法得到回顯資料

還有你要跳轉到外部網站,比如www.baidu.com,那你就不能用轉發,就指定用重定向,這個上面第一點就說了。

本文章就講到到這裡,如果哪裡有不足,或者可以修改的更好,歡迎留言指出。

Struts框架(6)---action接收請求引數

action接收請求引數

在web開發中,去接收請求引數來獲得表單資訊非常的常見,自己也總結整理了有關Struts2通過action接收請求引數的幾種方法。

Struts2 提供三種資料封裝的方式:

(1) Action 本身作為model物件,通過成員setter封裝

(2) 建立獨立model物件,頁面通過ognl表示式封裝

(3) 使用ModelDriven介面,對請求資料進行封裝(推薦)

下面我們來講解第一種:

(1) Action類本身作為model物件通過成員的setter方法封裝(屬性驅動)

setXxx()的xxx必須與請求的引數名一樣。就是指和form表單中的name對應的屬性要一致

action類的程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 importjava.util.Arrays; importcom.ssh.struts2.model.User; importcom.opensymphony.xwork2.ActionSupport; /* * 通過這種方法最簡單,但也有缺點如果要把資料封裝到model物件中然後傳遞給業務層和資料層 * 還需要單獨定義model物件進行傳遞資料 */ publicclassRegisterAction1extendsActionSupport { privateString username; privateString [] hobby; @Override publicString execute()throwsException { //獲取表單的資料 System.out.println("使用者名稱是:"+username); System.out.println("興趣愛好是:"+Arrays.toString(hobby)); returnnull; } //這裡必須提供set方法,get方法可有可無 publicvoidsetUsername(String username) { this.username = username; } publicvoidsetHobby(String[] hobby) { this.hobby = hobby; } } /*當你在介面中使用者名稱輸入:zhangsan,興趣愛好選擇:體育和讀書那麼執行結果如下: * 使用者名稱是:zhangsan * 興趣愛好是:[sport, read] */

struts.xml

1 2 3 4 5 6 7 8 9 10 <?xmlversion="1.0" encoding="UTF-8" ?> <!DOCTYPEstruts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <packagename="default" extends="struts-default"> <actionname="register1" class="com.ssh.struts2.action.RegisterAction1"> </action> </package> </struts>

register.jsp

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> </head> <body> <h4>登錄檔單1 </h4> <formaction="${pageContext.request.contextPath }/register1.action" method="post"> 使用者名稱:<inputtype="text" name="username"><br/> 愛好:<inputtype="checkbox" name="hobby" value="sport">體育 <inputtype="checkbox" name="hobby" value="music">音樂 <inputtype="checkbox" name="hobby" value="read">讀書 <br/> <inputtype="submit" value="註冊"> </form> </body> </html>

網頁:

(2) 建立獨立model物件,頁面通過ognl表示式封裝

該方法首先要建立一個專門的領域物件進行封裝

User領域物件

import java.util.Arrays;
public class User {

    private String username;      
    private String [] hobby;
//為這兩個常量提供set和get方法和toString方法

Action類

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 importcom.ssh.struts2.model.User; importcom.opensymphony.xwork2.ActionSupport; publicclassRegisterAction2extendsActionSupport{ //直接定義model物件 privateUser user; @Override publicString execute()throwsException { System.out.println("user:"+user); returnNONE; } /* * 必須提供get方法 * 封裝第一個引數 建立一個新的User物件 然後把username屬性封裝到這個建立的user物件中 User user =new User();user.setUserName(""); * 封裝第二個引數 已經存在user物件 User user =getUser(); user.setPassword("); */ publicUser getUser() { returnuser; } publicvoidsetUser(User user) { this.user = user; } } /* * 如果jsp介面輸入:使用者名稱:aa 興趣愛好:體育讀書 * 後臺輸出:user:User [username=aa, hobby=[sport, music]] */

register.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4   </head>
 5   <body>
 6   <!-- 用ognl表示式要注意的一點就是,標籤的屬性name在取名字的時候是:領域物件.屬性 
 7    user.username這裡user是具體的物件,username是領域物件的屬性-->
 8      <h4>登錄檔單1 </h4>
 9      <form action="${pageContext.request.contextPath }/register2.action" method="post">
10            使用者名稱:<input type="text" name="user.username"><br/>
11           愛好:<input type="checkbox" name="user.hobby" value="sport">體育
12           <input type="checkbox" name="user.hobby" value="music">音樂
13           <input type="checkbox" name="user.hobby" value="read">讀書  <br/>     
14           <input type="submit" value="註冊">
15      </form>
16   </body>
17 </html>

說明:struts2首先通過反射技術呼叫User的預設構造器建立User物件,然後通過反射技術呼叫User中與請求引數同名的屬性的setter方法來獲取請求引數值。在這裡需要注意的一點是:User物件一定要有預設的構造器。

採用複合型別接收請求引數的好處,可以減少action中的setter和getter方法,同時可以把相應的屬性組合成一個類,這樣使程式碼更好清晰,程式碼有更好的結構。

 (3)使用ModelDriven介面,對請求資料進行封裝

第三種方法比較方便,和方法(1)不同在於它也要先建立一個領域物件類進行物件的封裝。其它和方法(1)一樣

 Action類

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 importcom.ssh.struts2.model.User; importcom.opensymphony.xwork2.ActionSupport; importcom.opensymphony.xwork2.ModelDriven; //實現ModelDriven<User>介面 publicclassRegisterAction3extendsActionSupportimplementsModelDriven<User> { /** * 方式三 使用模型驅動 */ //這裡需要注意,方法2中的user物件不需要自己建立,而這裡必須手動初始化 privateUser user =newUser(); publicUser getModel() { returnuser; } @Override publicString execute()throwsException { System.out.println("user:"+user); returnNONE; } } /* * 如果jsp介面輸入:使用者名稱:aa 興趣愛好:體育讀書 * 後臺輸出:user:User [username=aa, hobby=[sport, music]] */

  

 最後我們來思考兩個問題,也是常見的筆面試題:

問題一:Action封裝資料會不會有執行緒問題?

問題二:在使用第一種方式進行封裝的時候資料封裝到Action 屬性中不能把Action傳遞給業務層資料如何傳遞?

謝謝大家瀏覽,歡迎大家指點!

Struts2系列筆記(7)---Struts2型別轉換

Struts2型別轉換

struts2中內建了大量的型別轉換器用來完成資料型別轉換的問題,這篇隨筆主要通過兩個方面來寫Struts型別轉換

1:Struts2內建的型別轉換器

2:如何自定義型別轉換器

那麼首先我們來學習有關Struts2內建的型別

1:Struts2內建的型別轉換器

Struts2的內建型別轉換器,可以為你處理大多數的型別轉換,這包括了以下型別和String型別之間的轉換!

1.String

將int,double,boolean,String型別的陣列或java.util.Date型別轉換成字串。

2:boolean和Boolean

在字串與boolean之間轉換

3:char/Character

在字串和字元之間轉換

4:int/Integer,float/Float,long/Long,double/Double

在字串與數值型別之間進行轉換

5:date

在字串和日期型別之間進行轉換,預設格式是:YYYY-MM-DD

6:陣列

由於陣列本身就有型別,可以將多個同名引數,轉換到陣列中(在之前總結的興趣愛好多選擇,如果你選擇多個,同時他們name屬性相同就自動變為陣列)

7:集合

支援將資料儲存到List或者Map 集合

關於內建型別轉換器舉例:

Action類

 1 import java.util.Date;
 2 import com.opensymphony.xwork2.ActionSupport;
 3 
 4 public class CustomerAction extends ActionSupport {
 5 
 6     private String username;
 7 
 8     private int age;
 9 
10     private Date birthday;
11 
12     @Override
13     public String execute() throws Exception {
14         System.out.println("客戶姓名是:" + username + ",年齡是:" + age + ",生日:" + birthday);
15 
16         return NONE;
17     }
18     public void setUsername(String username) {
19         this.username = username;
20     }
21     public void setAge(int age) {
22         this.age = age;
23     }
24     public void setBirthday(Date birthday) {
25         this.birthday = birthday;
26     }
27 }
28 /*控制檯輸出結果:客戶姓名是:zhangsan,年齡是:12,生日:Tue Jul 09 00:00:00 CST 1996
29 */

jsp介面

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4   </head>
 5   <body>
 6     <form action="${pageContext.request.contextPath }/customer.action">
 7      客戶姓名:<input type="text" name="username"><br/>
 8      年齡:<input type="text" name="age"><br/>
 9      生日:<input type="text" name="birthday"><br/>
10      <input type="submit" value="提交">     
11     </form>    
12   </body>
13 </html>

介面輸入:這裡年齡只能輸入合法年齡,日期的預設格式:yyyy-MM-dd,如果你輸入不合規則網頁會報錯,比如你輸入1996/7/9頁面就會報錯

2:如何自定義型別轉換器

為什麼需要自定義型別轉換器,這個問題相信大家都知道,就像我上面所說的,日期的預設格式是yyyy-MM-dd,那如果你想輸入yyyy/mm/dd或者其它的

這個時候就需要你修改你自己的型別轉換器,否則會報錯。下面我寫一個有關自定義型別轉換器的方法:繼承StrutsTypeConverter

DateConverter 
 1 import java.text.DateFormat;
 2 import java.text.ParseException;
 3 import java.text.SimpleDateFormat;
 4 import java.util.Date;
 5 import java.util.Map;
 6 
 7 import javax.xml.bind.TypeConstraintException;
 8 import org.apache.struts2.util.StrutsTypeConverter;
 9 
10 public class DateConverter extends StrutsTypeConverter {
11     //為方便支援多種日期格式的轉換,可增加時間格式
12     private final DateFormat [] dateformats={
13             new SimpleDateFormat("yyyy-MM-dd"),
14             new SimpleDateFormat("yyyy年MM月dd日"),
15             new SimpleDateFormat("yyyy.MM.dd"),
16             new SimpleDateFormat("yyyy/MM/dd")
17     };
18     /* 將一個或多個字串值轉換為指定的型別
19      * 
20      */
21     @Override
22     public Object convertFromString(Map arg0, String[] values, Class toType) {
23         //從表單獲取的日期字串
24         String dateStr = values[0];//思考:這裡為什麼是陣列而不是字串?我自己也沒有搞明白,希望大神看到後宰評論區給予解答,謝謝
25         for(int i = 0;i<dateformats.length;i++){//遍歷日期型別進行轉換
26             
27             try { //SimpleDateFormat類中parse()方法用於將輸入的特定字串轉換成Date類的物件
28                 return dateformats[i].parse(dateStr);
29             } catch (Exception e) {
30                 continue; //很關鍵
31             }
32         }
33         throw new TypeConstraintException("遍歷結束仍沒有指定的型別轉換");
34     }
35 
36     /* 將指定物件轉化為字串
37      * method:這個方法是用來回顯用的,就是你需要回顯成什麼樣的格式就可以設定什麼樣的格式
38      */
39     @Override
40     public String convertToString(Map context, Object object) {
41         Date date = (Date) object;
42         //指定輸出的格式
43         return new SimpleDateFormat("yyyy年MM月dd日").format(date);
44     }
45 }
46 /*主要講這裡的continue,就是如果你是輸入的是1992-2-2,那麼dateformats[0]和你直接匹配
47  * 那麼直接返回,當如果你開始輸入的是1992/2/2那麼就和dateformats[0]不匹配,那麼出現異常執行
48  * catch中的內容,而catch中是continue代表終止本次迴圈進入下一次迴圈,那麼有和dateformats[1]
49  * 進行匹配,如果都不匹配才會異常,所以這裡用的太關鍵了
50  *

Aation(類)

 1 import java.util.Date;
 2 import com.opensymphony.xwork2.ActionSupport;
 3 
 4 public class RegisterAction1 extends ActionSupport {  
 5     private Date brithday1;
 6     private Date brithday2;
 7     private Date brithday3;
 8     private Date brithday4;
 9     /*
10      * 為上面四個提供set和get方法
11      */
12 
13     @Override
14     public String execute() throws Exception {
15         //獲取表單的資料
16        System.out.println("生日1"+brithday1);
17        System.out.println("生日2"+brithday2);
18        System.out.println("生日3"+brithday3);
19        System.out.println("生日4"+brithday4);     
20         return SUCCESS;
21     }
22 } 
23 /*後臺輸出結果:
24  * 生日1Sun Feb 02 00:00:00 CST 1992
25  * 生日2Sun Feb 02 00:00:00 CST 1992
26  * 生日3Sun Feb 02 00:00:00 CST 1992
27  * 生日4Sun Feb 02 00:00:00 CST 1992 
28  */

register.jsp(登入介面)

 1 <html>
 2   <head>
 3     <title>註冊</title>
 4   </head> 
 5   <body>
 6      <!-- 這裡有四個生日 -->
 7      <form action="${pageContext.request.contextPath }/register1.action" method="post">
 8             生日1:<input type="text" name="brithday1"><br/><br/>
 9             生日2:<input type="text" name="brithday2"><br/><br/>
10             生日3:<input type="text" name="brithday3"><br/><br/>
11             生日4:<input type="text" name="brithday4"><br/><br/>
12           <input type="submit" value="註冊">
13      </form>
14   </body>
15 </html>

struts.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5 <struts>
 6     <!-- 開發者模式 -->
 7     <constant name="struts.devMode" value="true"></constant>
 8     
 9     <package name="default"  extends="struts-default">    
10         <action name="register1" class="com.guigu.struts2.action.RegisterAction1">
11            <result>/result.jsp</result>
12         </action>
13     </package>
14 </struts>
result.jsp
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@ taglib uri="/struts-tags"  prefix="s"%>
 3 <html>
 4   <head>
 5   </head>
 6   <body>
 7   <!-- 回顯的時候發現儘管前面輸入格式不一樣,但輸出格式是一樣的 -->
 8   生日1:<s:property value="brithday1"/><br/>
 9   生日2:<s:property value="brithday2"/><br/>
10   生日3:<s:property value="brithday3"/><br/>
11   生日4:<s:property value="brithday4"/><br/> 
12   </body>
13 </html>
介面:

最終返回介面:

注意:這中間還有很重要的東西需要配置:配置轉換器

4、配置轉換器 Struts2提供了兩種方式配置轉換器 方式一:應用於全域性範圍的型別轉換器,在src目錄下建立xwork-conversion.properties 轉換類全名=型別轉換器類全名 java.util.Date=com.sytudy.struts2.action.DateConverter (前面是你需要轉換的型別,後面是型別轉換器類 方式二:應用於特定類的型別轉換器,在特定類的相同目錄下建立一個名為ClassName-conversion.properties的屬性檔案 特定Action類的屬性名=型別轉換器類全名

這篇文字就講到這裡,如果哪裡有不足,歡迎大家指點,謝謝

Struts2框架(8)---Struts2的輸入校驗

Struts2的輸入校驗

在我們專案實際開發中在資料校驗時,分為兩種,一種是前端校驗,一種是伺服器校驗:

客戶端校驗:主要是通過jsp寫js指令碼,它的優點很明顯,就是輸入錯誤的話提醒比較及時,能夠減輕伺服器的負擔,但是客戶端校驗並不是安全的,簡單來講就是防君子防不了小人。

伺服器端校驗:最大特點就是資料安全,但是如果只有伺服器端校驗,會大大增加伺服器端的負擔。

所以一般在我們開發中,是客戶端和伺服器端校驗相結合作用的。

那這篇文章,我只講伺服器端校驗,在Struts2支援兩種校驗方式:

程式碼校驗:在伺服器通過編輯java程式碼完成資料校驗

配置校驗:xml配置校驗 通過xml配置檔案完成資料的校驗

(1)程式碼校驗:

程式碼校驗分為三個步驟:

步驟一、封裝資料

步驟二、實現要校驗的Action 必須繼承ActionSupport

步驟三、覆蓋Validate方法 然後完成業務邏輯資料的校驗

使用者介面register.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
 3 <%@ taglib uri="/struts-tags" prefix="s" %>
 4 <html>
 5   <head>
 6     <title>使用者註冊</title>
 7   </head> 
 8   <body style="text-align: center;">
 9     <table align="center" width="50%">
10         <tr>
11             <td style="color: red">
12                 <!-- <s:fielderror></s:fielderror>  --> <!-- 這裡是顯示錯誤的地方 -->
13             </td>
14         </tr>  
15     </table>
16   
17         <form action="${pageContext.request.contextPath }/login" method="post"  >
18         
19             使用者名稱:<input type="text"  name="username"><br><br>
20             密     碼:<input type="text"  name="password"><br><br>
21                     確認密碼:<input type="text"  name="password2"><br><br>
22                         <input type="reset" value="清空">
23                         <input type="submit" value="註冊">
24                 
25         </form>
26   </body>
27 </html>

struts.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5 <struts>  
 6       <!-- 配置常量資訊 -->
 7       <constant name="struts.devMode" value="true"></constant>       
 8       
 9      <package name="struts2" extends="struts-default" >
10          <action name="login" class="com.study.Login.RegisterAction">
11          <result name="success">/success.jsp</result>
12          <!-- 在input檢視中可以通過<s:fielderror/>顯示失敗資訊 -->
13          <result name="input">/register.jsp</result>
14          </action>
15      </package>         
16 </struts>
RegisterAction.java
 1 import com.opensymphony.xwork2.ActionSupport;
 2 public class RegisterAction extends ActionSupport{
 3 
 4     private String username;
 5     private String password;
 6     private String password2;
 7     //這裡我通過set方法封裝資料    
 8   public void setUsername(String username) {
 9         this.username = username;
10     }
11     public void setPassword(String password) {
12         this.password = password;
13     }
14     public void setPassword2(String password2) {
15         this.password2 = password2;
16     }
17 
18     @Override
19     public String execute() throws Exception {
20         return NONE;
21     }
22     
23     //在伺服器端需要完成對資料的校驗
24     @Override
25     public void validate() {
26         //測試是否得到屬性值,證實已經得到
27     System.out.println(username+"---"+password+"---"+password2);
28     if(username==null || username.length()<6 || username.length()>20){
29         //把錯誤資訊儲存到欄位中
30         this.addFieldError("username", "有戶名輸入不合法");
31     }
32     
33     if(password==null || password.length()<6 || password.length()>20){
34         //把錯誤資訊儲存到欄位中
35         this.addFieldError("password", "密碼輸入不合法");
36     }else if( password2==null || password2.length()<6 || password2.length()>20){
37         this.addFieldError("password2", "密碼輸入不合法");
38     }else if(!password.equals(password2)){
39         this.addFieldError("password2", " 兩次密碼不一致");
40     }
41     
42         super.validate();
43     }
44 }
執行結果:

(2)框架校驗

框架校驗也就是通過XML配置方式進行資料校驗 ,這也是我們在企業開發的主流校驗。

XML校驗原理: 將很多規則程式碼已經寫好只需要在xml檔案中定義需要使用的校驗規則即可。,所以大大減少了我們的開發時間。

我先把步驟寫一下:

步驟一:編寫JSP

步驟二:編寫Action 繼承ActionSupport或者Validateable介面

 步驟三:封裝請求引數

  步驟四:編寫xml校驗規則檔案

Xml校驗檔案的命名規則: Action類名-validation.xml 對Action中所有的方法都執行校驗

舉例命名規則RegisterAction-validation.xml

同時要滿足:Xml校驗檔案和Action類要在同一包下

步驟一:register.jsp

register.jsp

步驟二:RegisterAction.java

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class RegisterAction extends ActionSupport implements ModelDriven<User>{

 //手動建立一個物件
    private User user =new User();

    @Override
    public String execute() throws Exception {
        return NONE;
    }

    public User getModel() {
        return user;
    }        
}

步驟三:封裝請求引數

上面手動校驗的案例我是用set方法封裝資料,那這裡我採用的是使用ModelDriven介面,對請求資料進行封裝,

在之前我講過封裝資料的三種方法不清楚的可以看下這篇文章:Struts框架(6)---action接收請求引數

User.java

 1 import java.util.Date;
 2 public class User {
 3     
 4     private String username;
 5     private String password;
 6     private String password2;
 7     private Integer age;
 8     private String email;
 9     private Date birthday;
10     private Date graduation;
11     
12     /*
13      * 給屬性提供get和set方法
14      */
15 }

步驟四:RegisterAction-validation.xml

<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.2//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
 <validators>
  <!--dtd約束在xwork-core-**.jar包中 -->   
      <field name="username">
              <field-validator type="requiredstring">
                  <param name="trim">true</param>
                  <message>使用者民不能為空</message>
              </field-validator>
              
              <field-validator type="stringlength">
                <param name="minLength">6</param>
                <param name="maxLength">15</param>
                <message>有戶名長度必須在 ${minLength} 和 ${maxLength}之間 </message>
              </field-validator>
      </field> 
      
      
        <field name="password">
              <field-validator type="requiredstring">
                  <param name="trim">true</param>
                  <message>密碼不能為空</message>
              </field-validator>
              
              <field-validator type="stringlength">
                <param name="minLength">6</param>
                <param name="maxLength">15</param>
                <message>密碼必須在 ${minLength}和${maxLength}之間 </message>
              </field-validator>
       </field> 
       
      <field name="password2">
          <field-validator type="fieldexpression">
             <param name="expression"><![CDATA[password==password2]]></param>
             <message>兩次密碼不一致</message>
          </field-validator>
      </field>
      
      <field name="age">
          <field-validator type="required">
              <param name="trim">true</param>
              <message>年齡不能為空</message>
          </field-validator>
          <field-validator type="int">
              <param name="min">1</param>
              <param name="max">150</param>
              <message>年齡必須在 ${min} 和 ${max}之間</message>
          </field-validator>
        
      </field>
      
      <field name="email">
           <field-validator type="email">
               <message>不是一個合法的郵箱地址</message>
           </field-validator>
      </field>
      
       <field name="birthday">
          <field-validator type="date">
              <param name="min">2001-01-01</param>
              <param name="max">2003-12-31</param>
              <message>生日必須在 ${min} 和${max}之間</message>
          </field-validator>        
      </field> 
      
 </validators>

struts.xml不需要任何改變,和之前一樣就可以了

執行結果:

如果你覺得提示錯誤的位置有點醜,那你可以運用Struts2的<s:form>標籤,效果會更好

現在兩種方式都講了,現在對xml配置的要點一些知識要點進行歸納。

xml校驗檔案詳解:

<validators>:根元素

<field>:指定action中要校驗的屬性,name屬性指定將被驗證的表單欄位的名字

<field-validator>:指定校驗器, type 指定驗證規則

上面指定的校驗器requiredstring是由系統提供的,系統提供了能滿足大部分驗證需求

的校驗器,這些校驗器的定義可以在xwork-2.x.jar中的

com.opensymphony.xwork2.validator.validators下的default.xml中找到。

<param>:子元素可以向驗證程式傳遞引數

<message>:子元素為校驗失敗後的提示資訊,如果需要國際化,可以為message

指定key屬性,key的值為屬性檔案中的key。

struts2校驗規則:

系統提供的校驗器如下:

required(必填校驗器,要求被校驗的屬性值不能為null)

requiredstring(必填字串校驗器,要求被校驗的屬性值不能為null,並且長度大於0,預設情況下會對字串去前後空格)

stringlength(字串長度校驗器,要求被校驗的屬性值必須在指定的範圍內,否則校驗失敗,minLength引數指定最小長度,maxLength引數指定最大長度,trim引數指定校驗field之前是否去除字串前後的空格)

regex(正則表示式校驗器,檢查被校驗的屬性值是否匹配一個正則表示式,expression引數指定正則表示式,caseSensitive引數指定進行正則表示式匹配時,是否區分大小寫,預設值為true)

int(整數校驗器,要求field的整數值必須在指定範圍內,min指定最小值,max指定最大值)

double(雙精度浮點數校驗器,要求field的雙精度浮點數必須在指定範圍內,min指定最小值,max指定最大值)

fieldexpression(欄位OGNL表示式校驗器,要求field滿足一個ognl表示式,expression引數指定ognl表示式,該邏輯表示式基於ValueStack進行求值,返回true時校驗通過,否則不通過)

email(郵件地址校驗器,要求如果被校驗的屬性值非空,則必須是合法的郵件地址)

url(網址校驗器,要求如果被校驗的屬性值非空,則必須是合法的url地址)

date(日期校驗器,要求field的日期值必須在指定範圍內,min指定最小值,max指定最大值)

conversion(轉換校驗器,指定在型別轉換失敗時,提示的錯誤資訊)

visitor(用於校驗action中複合型別的屬性,它指定一個校驗檔案用於校驗複合型別屬性中的屬性)

expression(OGNL表示式校驗器,它是一個非欄位校驗器, expression引數指定ognl表示式,該邏輯表示式基於ValueStack進行求值,返回true時校驗通過,否則不通過,該校驗器不可用在欄位校驗器風格的配置中)

最後講一個細節:

編寫校驗檔案時,不能出現幫助資訊

在編寫ActionClassName-validation.xml校驗檔案時,如果出現不了幫助資訊,可以按下面方式解決:

windwos->preferences->myeclipse->files and editors->xml->xmlcatalog

點“add”,在出現的視窗中的location中選“File system”,然後在xwork-2.1.2解壓目錄的src\java目錄中選擇xwork-validator-1.0.3.dtd,

回到設定視窗的時候不要急著關閉視窗,應把視窗中的Key Type改為URI 。Key改為http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd