閱讀408 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Struts 2基礎

Struts 2基礎


第2章 Struts 2

此內容是《Java Web開發教程——入門與提高篇(JSP+Servlet)》一書附贈資料的一部分。

2.1概述

Struts現在分兩個版本:Struts 1.X和Struts 2.X。Struts 1.X已經有很多年了,可以說非常流行,但是因為其他框架的快速發展以及自身存在的問題,Struts 2誕生了,Struts 2與Struts 1的區別非常大,實際上Struts 2的核心思想是基於另外一個非常成功的Web框架WebWork。兩者的區別如表20.1所示。下麵主要針對Struts 2進行介紹。

表2.1 Struts1和Struts2的比較

Feature

Struts 1

Struts 2

Action類

在Struts 1中要求Action類繼承抽象的基類。在Struts 1中一個普遍存在的問題就是麵向抽象類編程,而不是麵向接口編程。

Struts 2中的Action可以實現一個Action接口,同時可以實現其他的接口,這樣可以使用戶有選擇性地使用其它自定義的服務。Struts 2提供了基礎類ActionSupport,該類實現了一些通用的接口。Action接口不是必須的。任何具有execute方法的POJO對象都可以用作Struts 2的Action對象。

線程模型

Struts 1的Actions是單例的,因為隻有一個類的實例來處理所有對這個Action的請求,所以必須是線程安全的。單例策略對Struts 1的Action的能夠完成的功能有很大限製,有些功能需要額外的努力才能完成。Action資源必須是線程安全的或者synchronized

Struts 2的Action對象是為每個請求實例化的,因此沒有線程安全的問題。(在實踐中,Servlet容器會為每個請求生成多個throw-away對象,增加的對象不會對性能產生太大影響或者對垃圾回收產生影響)

Servlet依賴

Struts 1的Action依賴Servlet API,因為當調用Action的execute方法時需要傳參數HttpServletRequest和HttpServletResponse。

Struts 2的Action與容器不是緊密結合在一起的。多數情況下,servlet上下文被表示為Map對象,允許對Action進行獨立的測試。如果需要,Struts 2的Action仍然可以訪問原始的request和response對象。 然而,其它框架元素可以減少或者消除對HttpServetRequest和HttpServletResponse對象進行直接訪問的必要。

可測試性

測試Struts 1 Action的一個主要障礙就是execute方法使用了Servlet API。1個第三方擴展Struts TestCase,為Struts 1提供了一組模擬(mock)對象。

Struts 2的Action可以通過實例化、設置屬性和調用方法進行測試。依賴注入支持使測試更簡單。

獲取輸入

Struts 1使用ActionForm對象來獲取輸入。像Action一樣,所有的ActionForm必須繼承一個基類。因為其它的JavaBean不能用作ActionForm,開發人員經常需要創建多餘的類來獲取輸入。可以使用動態Form來替換傳統的ActionForm類,但是開發人員同樣可能需要重新描述已有的JavaBean。

Struts 2使用Action的屬性作為輸入屬性,不用創建第二個輸入對象。輸入屬性可以是複雜的對象類型,還可以有自己的屬性。可以在頁麵中通過taglib訪問Action屬性。Struts 2也支持ActionForm模式,以及POJO表單對象和POJO Action。複雜對象類型,包括業務或者域對象,都可以作為輸入/輸出對象。模型驅動的特性簡化了標簽庫對POJO輸入對象的引用。

表達式語言

Struts 1集成了JSTL,所以可以使用JSTL的EL語言,EL提供了基本的對象結構遍曆(object graph traversal),但是集合以及索引屬性支持比較弱。

Struts 2可以使用JSTL,同時Struts還支持另外一種功能更強大、使用更靈活的表達式語言,這種語言是Object Graph Notation Language,簡稱OGNL。

值與視圖的綁定

Struts 1使用了標準的JSP機製把對象與要訪問的頁麵上下文綁定。

Struts 2使用了一種ValueStack技術,這樣標簽庫不用把視圖與要呈現的對象類型關聯就可以訪問值。ValueStack策略允許重用涉及多個類型的視圖,這些類型可能有相同的屬性名,但是屬性類型不同。

類型轉換

Struts 1的ActionForm屬性通常都是字符串類型。Struts 1 使用Commons-Beanutils進行類型轉換。轉換器是針對每個類的,而不能為每個實例配置。

Struts 2使用OGNL進行類型轉換,框架包含了常用對象類型和基本數據類型的轉換器。

驗證

Struts 1支持手動驗證,通過ActionForm的validate方法或者通過繼承通用的驗證器來完成。對於同一個類可以有不同的驗證上下文環境,但是不能鏈接到對子類型的驗證。

Struts 2支持通過驗證方法進行手工驗證和XWork驗證框架。Xwork驗證框架支持對子屬性的鏈接驗證,使用為屬性類型定義的驗證規則和上下文。

Action執行的控製

Struts 1支持為每個模塊提供獨立的請求處理器(生命周期),但是同一個模塊中的所有Action具有相同的生命周期。

Struts 2通過攔截器棧支持為每個Action創建不同的生命周期。必要的時候,可以使用不同的Actio創建和使用自定義棧。

注:來自Struts的官方網站:https://struts.apache.org/2.0.11.2/docs/comparing-struts-1-and-2.html

Strust 2結構圖如圖2.1(原圖來自Strust 2文檔)所示:

圖2.1 Struts2結構圖

在處理一個請求的時候,主要使用3個類:Action、Interceptor和Result

處理流程:

u  請求到達服務器之後,首先經過一係列過濾器,有的是可選的,最主要的過濾器是FilterDispatcher。所有的請求都會提交給它處理,該過濾器是在web.xml中配置的。配置代碼如下:

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

u  FilterDispatcher過濾器接收到請求之後調用ActionMapper查看是否需要調用Action。ActionMapper提供了HttpRequest與Action調用請求之間的映射關係,可以決定當前請求是否需要調用Action。如果ActionMapper返回的信息表明需要調用Action。FilterDispatcher過濾器把控製前交給ActionProxy;

u  ActionProxy調用配置文件管理器ConfigurationManager,該管理器從struts.xml配置文件中獲取配置信息,獲取的信息主要包括當前請求對應哪個Action(對用戶的請求進行處理),對應哪些Result(決定了如何對用戶響應),有時候還涉及攔截器。然後根據這些信息創建ActionInvocation對象,該對象負責具體的調用過程。struts.xml是用戶需要提供的最主要的配置文件。下麵是一個struts.xml配置文件的部分內容。

<struts>

    <package name="default" extends="struts-default">

 

        <action name="Logon" >

            <result name="input">/pages/Logon.jsp</result>

            <result name="cancel" type="redirectAction">Welcome</result>

            <result type="redirectAction">MainMenu</result>

            <result name="expired" type="chain">ChangePassword</result>

        </action>

 

        <action name="Logoff" >

            <result type="redirectAction">Welcome</result>

        </action>

 

    </package>

</struts>

u  ActionInvocation對象按照順序執行當前請求所對應的攔截器,攔截器能夠對請求進行預處理,例如驗證、文件上傳等,並能夠對響應內容進行再處理。通常攔截器是由係統提供的,如果需要,編程人員隻需要進行配置即可。在調用Action的方法之前,會調用攔截器的預處理方法;

u  ActionInvocation對象調用攔截器的預處理方法之後會調用Action的execute方法,Action中的代碼主要由編程人員根據功能進行編寫的,通常從數據庫檢索信息或者向數據庫存儲信息。Action的方法返回一個字符串。下麵是一個簡單的Action例子。

package simple;

import java.util.Map;

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LogoutAction extends ActionSupport {

 

    public String execute() throws Exception {

     Map session = ActionContext.getContext().getSession();

     session.remove("logined");

     session.remove("context");

        return SUCCESS;

    }

 

}

u  ActionInvocation對象根據Action方法的返回結果以及struts配置文件生成Result對象。Result對象選擇一個模板文件來響應用戶,模板文件可以是JSP、FreeMarker和Velocity。

u  容器加載並執行模板文件,使用在Action中獲取的信息對模版中的變量進行賦值,也可能從資源文件或者其他內部對象中獲取信息。最終向瀏覽器呈現的是HTML、PDF或者其他內容。

u  模板文件執行的結果會經過攔截器進行再處理,最後通過過濾器返回給客戶端。

在該結構圖中,既包含了Struts框架提供的基礎接口,也包括了用戶要編寫的文件。其中,ActionMapper、ActionProxy、ConfigurationManager、ActionInvocation和Result是框架提供的核心類。過濾器和攔截器是框架提供的,用戶可以根據需要進行配置,當然也可以編寫自己的過濾器和攔截器。用戶需要編寫的文件是struts.xml、Action和模板文件,這些也是用戶在使用Struts 2框架時需要做的工作。

2.2 開發人員的主要任務

框架為開發人員提供了大量的輔助類,用戶在使用框架開發的時候隻需要編寫很少文件。在使用Struts 2開發的時候,首先應該把環境搭建起來,然後使用Struts 2提供的標簽開發界麵,然後編寫Action類,最後進行配置。

環境搭建

在進行具體的開發之前,需要先搭建環境。包括如下過程:

u  創建Web工程;

u  加載Struts 2的核心類庫,核心類庫包括commons-logging-1.0.4.jar、freemarker-2.3.8.jar、ognl-2.6.11.jar、struts2-core-2.0.11.2.jar和xwork-2.0.5.jar,把這些類庫放到Web工程的WEB-INF/lib下麵;

u  配置web.xml,主要配置Struts中心控製器FilterDispatcher,下麵是1個例子。

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="https://java.sun.com/xml/ns/j2ee" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee https://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

    <display-name>Struts Blank</display-name>

 

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

    </filter>

 

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

    <welcome-file-list>

        <welcome-file>index.html</welcome-file>

    </welcome-file-list>

 

</web-app>

u  創建struts.xml配置文件,與類文件放在一起,空白的struts文件如下所示。在使用Struts 2進行開發所有的配置基本上都在這個文件中完成。也可以根據需要創建多個配置文件,然後在這個配置文件中使用<include />進行包含。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "https://struts.apache.org/dtds/struts-2.0.dtd">

 

<struts>

 

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />

    <constant name="struts.devMode" value="false" />

 

    <include />

 

    <!-- Add packages here -->

 

</struts>

環境搭建完之後,在具體開發過程中主要完成3個方麵的工作:

u  製作模板文件,可以使用JSP、FreeMarker或者Velocity等;

u  編寫Action,基本上每個動作對應1個Action;

u  配置,主要在struts.xml中進行配置。

下麵分別介紹。

製作模板文件

模版文件的主要作用是接收用戶輸入的信息,並向用戶展示信息。Struts提供了多個標簽庫來簡化頁麵的代碼量,使用標簽之後頁麵也更容易維護。下麵是一段標簽:

<s:actionerror/>

<s:form action="Profile_update" validate="true">

  <s:textfield label="Username" name="username"/>

  <s:password label="Password" name="password"/>

  <s:password label="(Repeat) Password" name="password2"/>

  <s:textfield label="Full Name" name="fullName"/>

  <s:textfield label="From Address" name="fromAddress"/>

  <s:textfield label="Reply To Address" name="replyToAddress"/>

  <s:submit value="Save" name="Save"/>

  <s:submit action="Register_cancel" value="Cancel" name="Cancel"

            />

</s:form>

Struts 2中提供了兩類通用標簽和3類界麵標簽:

u  控製標簽

u  數據標簽

u  Form標簽

u  Non-Form用戶接口標簽

u  Ajax標簽

下麵對這些類型的標簽進行介紹。

控製標簽及其用法如表2.2所示。

表2.2 控製標簽

標簽名

描述

例子

if

與Java中的if基本相同

<s:if test="%{false}">

    <div>Will Not Be Executed</div>

</s:if>

<s:elseif test="%{true}">

    <div>Will Be Executed</div>

</s:elseif>

<s:else>

    <div>Will Not Be Executed</div>

</s:else>

else if

與Java中的else if基本相同

else

與Java中的else基本相同

append

按照順序把多個迭代器的元素組合到一個迭代器中,保持原來的順序不變。

<s:append var="myAppendIterator">

     <s:param value="%{myList1}" />

     <s:param value="%{myList2}" />

     <s:param value="%{myList3}" />

</s:append>

<s:iterator value="%{#myAppendIterator}">

     <s:property />

</s:iterator>

generator

根據val屬性的給定的值生成迭代器對象。

<s:generator val="%{'aaa,bbb,ccc,ddd,eee'}">

 <s:iterator>

     <s:property /><br/>

 </s:iterator>

</s:generator>

iterator

對迭代器或者集合進行遍曆,類似於Java中的for-each循環。

<s:iterator value="#it.days" status="rowstatus">

  <tr>

    <s:if test="#rowstatus.odd == true">

      <td ><s:property/></td>

    </s:if>

    <s:else>

      <td><s:property/></td>

    </s:else>

  </tr>

</s:iterator>

merge

把多個迭代器的元素合並到一個迭代器中,合並後的順序為1.1,2.1,3.1,1.2,1.3…,1.1表示第1個迭代器的第1個元素。

<s:merge var="myMergedIterator1">

     <s:param value="%{myList1}" />

     <s:param value="%{myList2}" />

     <s:param value="%{myList3}" />

</s:merge>

<s:iterator value="%{#myMergedIterator1}">

     <s:property />

</s:iterator>

sort

對List進行排序。

<s:sort var="mySortedList" comparator="myComparator" source="myList" />

subset

獲取集合的子集。

<s:subset var="mySubset" source="myList" count="13" start="3" />

數據標簽及其用法如表2.3所示。

表2.3 數據標簽

標簽名

描述

例子

a

生成HTML的<a>

<s:a href="%{testUrlId}"><img src="<s:url

value="/images/delete.gif"/>" border="none"/></s:a>

action

在JSP頁麵中直接調用Action

<s:action name="actionTagAction" executeResult="true" />

bean

實例化JavaBean對象

<s:bean name="org.apache.struts2.example.counter.SimpleCounter" var="counter">

  <s:param name="foo" value="BAR" />

  The value of foot is : <s:property value="foo"/> <br />

</s:bean>

date

創建Date對象

<s:date name="person.birthday" format="dd/MM/yyyy" />

debug

 

 

i18n

得到ResourceBundle對象。

<s:i18n name="myCustomBundle">

</s:i18n>

include

包含1個JSP或者Servlet的輸出。

<s:include value="myJsp.jsp">

   <s:param name="param1" value="value2" />

</s:include>

param

為其他標簽提供參數

參考上麵的例子

property

獲取屬性值

參考bean標簽的例子

push

把值保存起來使用

<s:push value="user">

    <s:propery value="firstName" />

    <s:propery value="lastName" />

</s:push>

set

把某個值保存到某個作用範圍的變量中。

<s:set name="personName" value="person.name"/>

Hello, <s:property value="#personName"/>. How are you?

text

呈現i18n的文本消息

<s:i18n name="struts.action.test.i18n.Shop">

    <s:text name="main.title"/>

</s:i18n>

url

用於生成URL

<s:url value="editGadget.action">

    <s:param name="id" value="%{selected}" />

</s:url>

Form標簽及其用法如表2.4所示。

表2.4 Form標簽

標簽名

描述

例子

checkbox

生成複選框

<s:checkbox label="checkbox test" name="checkboxField1"

value="aBoolean" fieldValue="true"/>

checkboxlist

生成多個複選框

<s:checkboxlist name="foo" list="bar"/>

combobox

輸入框與下拉框的組合。

<s:combobox

    label="My Favourite Fruit"

    name="myFavouriteFruit"

    list="{'apple','banana','grape','pear'}"

    headerKey="-1"

    headerValue="--- Please Select ---"

    emptyOption="true"

    value="banana" />

doubleselect

生成聯動菜單

<s:doubleselect label="doubleselect test1" name="menu"

list="{'fruit','other'}" doubleName="dishes"

doubleList="top == 'fruit' ? {'apple', 'orange'} : {'monkey', 'chicken'}" />

head

生成HTML的head部分。

<head>

  <title>My page</title>

  <s:head/>

</head>

file

生成文件輸入框

<s:file name="anUploadFile" accept="text/*" />

 

form

生成form表單

<p/>

<s:form ... />

<p/>

hidden

生成隱藏域

<s:hidden name="foo" value="bar" />

label

生成標簽

<s:label key="userName" />

optiontrans

-ferselect

生成兩個列表框,可以通過中間的按鈕把左邊的選項移動到右邊,也可以把右邊的選項移動到左邊。

<s:optiontransferselect

     label="Favourite Cartoons Characters"

     name="leftSideCartoonCharacters"

     list="{'Popeye', 'He-Man', 'Spiderman'}"

    doubleName="rightSideCartoonCharacters"

     doubleList="{'Superman', 'Mickey Mouse', 'Donald Duck'}"

 />

optgroup

在select中提供選項

<s:select label="My Selection"

           name="mySelection"

           value="%{'POPEYE'}"

           list="%{#{'SUPERMAN':'Superman', 'SPIDERMAN':'spiderman'}}">

   <s:optgroup label="Adult"

                list="%{#{'SOUTH_PARK':'South Park'}}" />

   <s:optgroup label="Japanese"

                list="%{#{'POKEMON':'pokemon','DIGIMON':'digimon',

'SAILORMOON':'Sailormoon'}}" />

</s:select>

select

生成下拉框

password

密碼輸入框

<s:password label="%{text('password')}" name="password"

size="10" maxlength="15" />

radio

單選按鈕

<s:radio label="Gender" name="male" list="#genders.genders"/>

reset

重值按鈕

<s:reset value="Reset" />

submit

提交按鈕

<s:submit value="OK" />

textarea

生成文本域

<s:textarea label="Comments" name="comments" cols="30" rows="8"/>

textfield

生成輸入框

<s:textfield key="user" />

 

token

阻止表單重複提交

<s:textfield key="user" />

 

updownselect

創建元素能夠上下移動的列表框

<s:updownselect

list="#{'england':'England', 'america':'America', 'germany':'Germany'}"

name="prioritisedFavouriteCountries"

headerKey="-1"

headerValue="--- Please Order Them Accordingly ---"

emptyOption="true" />

non-form UI標簽及其用法如表2.5所示。

表2.5 non-form標簽

標簽名

描述

例子

actionerror

呈現錯誤信息

<s:actionerror />

actionmessage

呈現提示信息

<s:actionmessage />

component

創建自定義組件

<s:component template="/my/custom/component.vm"/>

div

生成HTML <div>

 

fielderror

輸出關於輸入元素的錯誤信息

   <s:fielderror>

        <s:param>field1</s:param>

        <s:param>field2</s:param>

   </s:fielderror>

   <s:form .... >

      ....

   </s:form>

Ajax標簽包括a、autocompleter、bind、datetimepicker、div、head、submit、tabbedpanel、textarea、tree、treenode等。具體用法參考Struts 2幫助文檔。

編寫Action

針對每個功能可以編寫1個Action,也可以多個功能共享1個Action。Action完成的主要功能包括:

u  獲取用戶的輸入信息,這個獲取的過程是由框架完成的,但是用戶需要在Action中定義與用戶輸入表單元素名字相同的成員變量,關鍵是要提供對成員變量賦值的set方法,這樣框架在獲取用戶輸入信息之後會調用set方法把值賦給Action的成員變量。

u  根據用戶的請求信息,調用完成業務邏輯的JavaBean。如果希望要把某些執行結果傳遞給模板文件(JSP、FreeMarker和Velocity等),需要在Action中定義成員變量來表示這些結果,最關鍵的是要定義get方法,這樣在執行模版文件的時候會通過get方法來獲取這些信息。

u  根據執行的結果,返回1個字符串,這個字符串決定了使用什麼模板對用戶進行響應。

下麵是1個簡單的例子。

public class LoginAction extends ActionSupport {

 

    private String userId;

    private String passwd;

    // 對userId和passwd操作的setter和getter方法

    public String execute() throws Exception {

        if ("admin".equals(userId) && "password".equals(passwd)) {

            Map session = ActionContext.getContext().getSession();

            session.put("logined","true");

            session.put("context", new Date());

            return SUCCESS;

        }

        return ERROR;

    }

}

注意:並不是必須繼承ActionSupport,主要提供execute方法即可。

配置

通過配置文件Struts.xml對Web應用的流程進行管理,包括Action映射和Result處理,前者把請求與Action關聯起來,後者把Action執行的結果與響應界麵關聯起來。下麵是一段配置。下麵是一個簡單的例子。

<struts>

    <package name="default" extends="struts-default">

 

        <action name="Logon" >

            <result name="input">/pages/Logon.jsp</result>

            <result name="cancel" type="redirectAction">Welcome</result>

            <result type="redirectAction">MainMenu</result>

            <result name="expired" type="chain">ChangePassword</result>

        </action>

 

        <action name="Logoff" >

            <result type="redirectAction">Welcome</result>

        </action>

 

    </package>

</struts>

Struts 2中完成的主要配置如表2.6所示。

表2.6 Struts 2的主要配置信息

配置元素

例子

JavaBean

<bean type="com.opensymphony.xwork2.ObjectFactory"

name="myfactory" />

常量

<constant name="struts.devMode" value="true" />

<package name="employee" extends="struts-default" namespace="/employee">

   ...

</package>

命名空間

包含

<include />

攔截器

<interceptors>

  <interceptor name="security"

 />

  <interceptor-stack name="secureStack">

    <interceptor-ref name="security"/>

    <interceptor-ref name="defaultStack"/>

  </interceptor-stack>

</interceptors>

引用攔截器

<action name="VelocityCounter"

>

    <result name="success">...</result>

    <interceptor-ref name="defaultComponentStack"/>

</action>

全局Result:

<global-results>

    <result name="error">/Error.jsp</result>

    <result name="invalid.token">/Error.jsp</result>

</global-results>

Action

Result

異常配置

在Action中使用:

<exception-mapping exception="com.company.SecurityException" result="login"/>

全局:

<global-exception-mappings>

<exception-mapping exception="java.sql.SQLException" result="SQLException"/>

<exception-mapping exception="java.lang.Exception" result="Exception"/>

</global-exception-mappings>

Struts 2提供了大量的攔截器,用戶可以根據需要調用。

Struts 2的配置文件struts.xml的DTD定義如下。

<!--

   Struts configuration DTD.

   Use the following DOCTYPE

  

   <!DOCTYPE struts PUBLIC

          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

          "https://struts.apache.org/dtds/struts-2.0.dtd">

-->

 

<!ELEMENT struts (package|include|bean|constant)*>

 

<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>

<!ATTLIST package

    name CDATA #REQUIRED

    extends CDATA #IMPLIED

    namespace CDATA #IMPLIED

    abstract CDATA #IMPLIED

    externalReferenceResolver NMTOKEN #IMPLIED

 

<!ELEMENT result-types (result-type+)>

 

<!ELEMENT result-type (param*)>

<!ATTLIST result-type

    name CDATA #REQUIRED

    class CDATA #REQUIRED

    default (true|false) "false"

 

<!ELEMENT interceptors (interceptor|interceptor-stack)+>

 

<!ELEMENT interceptor (param*)>

<!ATTLIST interceptor

    name CDATA #REQUIRED

    class CDATA #REQUIRED

 

<!ELEMENT interceptor-stack (interceptor-ref*)>

<!ATTLIST interceptor-stack

    name CDATA #REQUIRED

 

<!ELEMENT interceptor-ref (param*)>

<!ATTLIST interceptor-ref

    name CDATA #REQUIRED

 

<!ELEMENT default-interceptor-ref (param*)>

<!ATTLIST default-interceptor-ref

    name CDATA #REQUIRED

 

<!ELEMENT default-action-ref (param*)>

<!ATTLIST default-action-ref

    name CDATA #REQUIRED

 

<!ELEMENT default-class-ref (param*)>

<!ATTLIST default-class-ref

    class CDATA #REQUIRED

 

<!ELEMENT global-results (result+)>

 

<!ELEMENT global-exception-mappings (exception-mapping+)>

 

<!ELEMENT action (param|result|interceptor-ref|exception-mapping)*>

<!ATTLIST action

    name CDATA #REQUIRED

    class CDATA #IMPLIED

    method CDATA #IMPLIED

    converter CDATA #IMPLIED

 

<!ELEMENT param (#PCDATA)>

<!ATTLIST param

    name CDATA #REQUIRED

 

<!ELEMENT result (#PCDATA|param)*>

<!ATTLIST result

    name CDATA #IMPLIED

    type CDATA #IMPLIED

 

<!ELEMENT exception-mapping (#PCDATA|param)*>

<!ATTLIST exception-mapping

    name CDATA #IMPLIED

    exception CDATA #REQUIRED

    result CDATA #REQUIRED

 

<!ELEMENT include (#PCDATA)>

<!ATTLIST include

    file CDATA #REQUIRED

 

<!ELEMENT bean (#PCDATA)>

<!ATTLIST bean

    type CDATA #IMPLIED

    name CDATA #IMPLIED

    class CDATA #REQUIRED

    scope CDATA #IMPLIED

    static CDATA #IMPLIED

    optional CDATA #IMPLIED

 

<!ELEMENT constant (#PCDATA)>

<!ATTLIST constant

    name CDATA #REQUIRED

    value CDATA #REQUIRED   

2.3實例

功能:登錄。

涉及的文件有:

l  Login.jsp,用於輸入登錄信息;

l  welcome.jsp,登錄之後的歡迎界麵;

l  loginCheck.jsp,判斷用戶是否登錄;

l  LoginAction.java,完成登錄業務處理,正常情況下會調用其他業務邏輯JavaBean來完成;

l  LogoutAction.java,完成退出業務處理;

l  struts.xml,應用的配置文件。

下麵分別介紹。

Login.jsp

源文件:Login.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

 pageEncoding="ISO-8859-1"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

</head><body>

<form action="login.action" method="post">

User id<input type="text" name="userId" /> <br/>

Password <input type="password" name="passwd" /> <br />

<input type="submit" value="Login"/>

</form>

</body>

</html> 

/pages/welcome.jsp 

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

<%@ taglib prefix="ww" uri="/webwork" %>

<jsp:include page="WEB-INF/inc/loginCheck.jsp" />

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Welcome</title>

</head>

 

<body>Welcome, you have logined. <br />

The attribute of 'context' in session is

<ww:property value="#session.context" />

<br /><br /><br />

<a xhref="<%= request.getContextPath() %>/logout.action">Logout</a>

<br />

<a xhref="<%= request.getContextPath() %>/logout2.action">Logout2</a>

</body>

</html> 

/WEB-INF/inc/loginCheck.jsp

<%@ taglib="/webwork" prefix="ww" %>
<ww:if test="#session.login != 'true'">
<jsp:forward page="<%= request.getContextPath() %>/login.jsp" />
</ww:if> 

simple.LoginAction.java

package simple;

import java.util.Date;import java.util.Map;

 

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LoginAction extends ActionSupport {

 

    private String userId;

    private String passwd;

 

    public String execute() throws Exception {

        if ("admin".equals(userId) && "password".equals(passwd)) {

//            HttpSession session = ServletActionContext.getRequest().getSession();

//            session.setAttribute("logined","true");

//            session.setAttribute("context", new Date());

// Better is using ActionContext

  Map session = ActionContext.getContext().getSession();

session.put("logined","true");

            session.put("context", new Date());

            return SUCCESS;

        }

        return ERROR;

    }

 

    public String logout() throws Exception {

//        HttpSession session = ServletActionContext.getRequest().getSession();

//        session.removeAttribute("logined");

//        session.removeAttribute("context");

 Map session = ActionContext.getContext().getSession();

 session.remove("logined");

        session.remove("context");

        return SUCCESS;

    }

 

    public String getPasswd() {

        return passwd;

    }

 

    public void setPasswd(String passwd) {

        this.passwd = passwd;

    }

 

    public String getUserId() {

        return userId;

    }

 

    public void setUserId(String userId) {

        this.userId = userId;

    }

}

 simple.LogoutAction.java

package simple;

import java.util.Map;

import javax.servlet.http.HttpSession;

 

import com.opensymphony.webwork.ServletActionContext;

import com.opensymphony.xwork.ActionSupport;

 

public class LogoutAction extends ActionSupport {

 

    public String execute() throws Exception {

     Map session = ActionContext.getContext().getSession();

session.remove("logined");

session.remove("context");

        return SUCCESS;

    }

 

} 

 /WEB-INF/classes/xwork.xml

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "https://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

 

<xwork>

    <include />

 

    <package name="default" extends="webwork-default">

        <!-- Add your actions here -->

        <action name="login" >

            <result name="success" type="dispatcher">/pages/welcome.jsp</result>

            <result name="error" type="redirect">/login.jsp</result>

        </action>

 

        <action name="logout2" method="logout" >

            <result name="success" type="redirect">/login.jsp</result>

        </action>

 

        <action name="logout" >

            <result name="success" type="redirect">/login.jsp</result>

        </action>

    </package>

</xwork>


最後更新:2017-04-03 22:15:32

  上一篇:go 列舉3年內使用Chrome OS的5大理由
  下一篇:go 編程能力強化(4)——模擬SQL語句解析