超全面 struts2 復(fù)習(xí)總結(jié)筆記

原創(chuàng)版權(quán)申明:本文章從本人 csdn 博客轉(zhuǎn)到簡書。
如有轉(zhuǎn)載,請申明:轉(zhuǎn)載自 IT天宇http://www.itdecent.cn/p/cf2d189c45bf

前言

What ? 最近怎么開始寫后端的博客了?


從去年開始就經(jīng)??吹絼e人提“移動(dòng)開發(fā)寒冬”,而年初投簡歷的時(shí)候更是親身體會,不寫3年經(jīng)驗(yàn)連面試機(jī)會都沒有,那么沒有經(jīng)驗(yàn)或經(jīng)驗(yàn)少的人能怎么辦呢,從一開就找不到工作怎么可能會有經(jīng)驗(yàn)?


然而絕望并沒有用,我算運(yùn)氣好,勉強(qiáng)找到一份工作。

從趨勢來看,近幾年移動(dòng)開發(fā)待遇不會很好,今年發(fā)現(xiàn)到處缺后端,于是決定還是搞后端吧,因?yàn)楦惆沧坎贿^一年,后端的知識還沒忘完(好吧,實(shí)際上以前后端也沒多深入),于是利用下班時(shí)間復(fù)習(xí)后端(好吧,其實(shí)好多是預(yù)習(xí)了●﹏●),并把知識整理出來分享給大家。

目錄

  1. 環(huán)境搭建
  2. Action
  3. 配置詳解
  4. 通配符和動(dòng)態(tài)方法調(diào)用
  5. OGNL
  6. Struts 標(biāo)簽
  7. Validator
  8. Interceptor
  9. 國際化
  10. 常見例子

正文

<a id="1"> </a>

1.環(huán)境搭建

導(dǎo)包

  • 版本管理工具導(dǎo)入

    • Gradle
      compile "org.apache.struts:struts2-core:2.5.10.1"
      
    • Maven
      <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>2.5.10.1</version>
      </dependency>
      

    上面的僅僅是核心包,根據(jù)需要可引入其他包,比如注解包

    compile "org.apache.struts:struts2-convention-plugin:2.5.10"
    

配置

web.xml

struts2 基于攔截器,因此,配置的第一步是在 WEB-INF/web.xml 中配置 struts2 攔截器。

配置的時(shí)候需要注意,不同的版本的 StrutsPrepareAndExecuteFilter 包路徑不一樣,配置的時(shí)候,可以用 IED 搜索這個(gè)類,復(fù)制路徑。比如 Idea 的搜索類快捷鍵是 Ctrl + N。

  • 2.5.x 版本

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

為了防止篇幅過大,其他版本就不寫了。

struts.xml

在 src 目錄下建立 struts.xml,Idea 中需要放到 resources 下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>

</struts>

<a id="2"> </a>

2.Action

HelloAction

編寫一個(gè)類繼承 ActionSupport, 并提供一個(gè)無參返回字符串且公開的方法,如下:

public class HelloAction extends ActionSupport {
    public String hello() throws Exception {
        System.out.println("hello world!");
        return SUCCESS;
    }
}

配置 Action

類似于 Servlet,struts2 使用 action 來處理請求。
使用 action 需要進(jìn)行配置。

xml 配置

在 struts.xml 的 struts 標(biāo)簽里面配置 action
如下:

<package name="p1" extends="struts-default">
    <action name="hello" class="com.ittianyu.web.action.HelloAction" method="login">
        <result name="success">hello.jsp</result>
    </action>
</package>

action 外面是 package,類似于 java 的包。
這里簡單介紹 action 的屬性,后面配置詳解里會一一介紹大部分標(biāo)簽和屬性。

name: 訪問 action 的名稱,如果沒有配置 namespace,則 根路徑/name 就是 action 的訪問地址。
class 和 method 則是指定 action 的類和方法。

注解配置

使用注解前必須保證 已經(jīng)導(dǎo)入了 struts2-convention-plugin 的包。

在 Action 類上加上 @ParentPackage("struts-default")
在對應(yīng)的方法上加上

@Action(value = "hello", results = {
           @Result(name = "success", location="/hello.jsp")})

如下:

@ParentPackage("struts-default")
public class HelloAction extends ActionSupport {
    @Action(value = "hello", results = {
               @Result(name = "success", location="/hello.jsp")})
    public String hello() throws Exception {
        System.out.println("hello world!");
        return SUCCESS;
    }
}

配置好后,就可以通過瀏覽器訪問(根路徑取決于項(xiàng)目配置)
http://127.0.0.1/strut2/hello.action
如果訪問成功,控制臺后打印 hello world!。

向 Action 傳遞參數(shù)

登錄是很常見的 action,這個(gè)時(shí)候一般要向服務(wù)器傳遞 username, password 等。

User

創(chuàng)建一個(gè) User 實(shí)體對象,假設(shè)里面只有 username, password。

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

UserAction

創(chuàng)建一個(gè) UserAction 來處理請求,簡單起見,使用注解方式配置。

@ParentPackage("struts-default")
public class UserAction extends ActionSupport implements ModelDriven<User>{
    private User user = new User();
    @Action(value = "login", results = {
               @Result(name = "success", location="/home.jsp")})
    public String login() throws Exception {
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        return SUCCESS;
    }
    @Override
    public User getModel() {
        return user;
    }
}

實(shí)現(xiàn) ModelDriven 方法,返回 user。
然后在執(zhí)行 login 方法之前,ModelDriven 攔截器會給 user 設(shè)置請求提交的值。

獲取 Servlet Api

使用 ServletActionContext
比如:

ServletActionContext.getRequest();
ServletActionContext.getResponse();

<a id="3"> </a>

3.配置詳解

include

用于引入其他 struts2 配置文件
比如:

<struts>
    <include file="struts-part1.xml"/>
    <include file="struts-part2.xml"/>
</struts>

package

|名稱 |類型 |默認(rèn) |必須 |描述
|----|-----|-----|----|-----|---
|name |string |無 |yes |包的名稱
|extends |string |無 |no |這個(gè)包所繼承的父包名稱.一般繼承 struts-default
|namespace |string |/ |no |包的命名空間,如果配置了,在訪問時(shí)要加上包名
|abstract |boolean |false |no |是否是抽象包,如果是,專門設(shè)計(jì)來被繼承,一般配置了自己的攔截器棧時(shí),會設(shè)計(jì)基礎(chǔ)包。

action

|名稱 |類型 |默認(rèn) |必須 |描述
|----|-----|-----|----|-----|---
|name |string |無 |yes |動(dòng)作的名稱
|class |string |com.opensymphony.xwork2.ActionSupport |no |綁定的動(dòng)作類。若不配置,則為默認(rèn)返回 success 的動(dòng)作類。
|method |string |execute |no |動(dòng)作綁定的方法
|converter |string |無 |no |動(dòng)作的類型轉(zhuǎn)換器

result

<result> 是 <action>的一個(gè)子元素,用于指定 action 的結(jié)果視圖。

|名稱 |類型 |默認(rèn) |必須 |描述
|----|-----|-----|----|-----|---
|name |string |success |no |對應(yīng)動(dòng)作方法的返回值
|type |string |dispatcher |no |結(jié)果類型。struts定義的結(jié)果類型有10種。

type 類型

|序號 |結(jié)果類型 |取值 |描述
|----|-----|-----|----|-----
|1 |Chain Result |chain |轉(zhuǎn)發(fā)方式轉(zhuǎn)到一個(gè)antion
|2 |Dispatcher Result |dispatcher | 轉(zhuǎn)發(fā)到一個(gè)頁面
|3 |FreeMarker Result |freemarker |
|4 |HttpHeader Result |httpheader |
|5 |Redirect Result |redirect | 重定向到一個(gè)頁面
|6 |Redirect Action Result |redirectAction |重定向轉(zhuǎn)到一個(gè)action
|7 |Stream Result |stream | 輸出流,一般用于下載
|8 |Velocity Result |velocity |
|9 |XSL Result |xslt |
|10 |PlainText Result |plainText |常用于顯示個(gè)別頁面的源碼

global-results

包內(nèi)全局的結(jié)果視圖,包內(nèi) action 沒有配置 result 時(shí),會使用全局結(jié)果視圖。一般是在基礎(chǔ)包里面配置,比如全局的登錄驗(yàn)證。

interceptors

用于聲明攔截器。

在 interceptors 中配置 interceptor, interceptor-stack,interceptor-ref 等聲明攔截器。

default-interceptor-ref

用于配置包的默認(rèn)攔截器。

constant

用于配置 struts2 中的常量。

<a id="4"> </a>

4.通配符和動(dòng)態(tài)方法調(diào)用

通配符

struts2 中 action 的 name 支持通配符 *。
用于匹配0個(gè)或多個(gè)字符。
舊版中可以直接使用,在新版中,需要啟用通配符。
在 package 開頭加上

<!--動(dòng)態(tài)方法配置,2.5之后額外配置允許的方法名-->
<global-allowed-methods>regex:.*</global-allowed-methods>

此外還可以通過 {n} 來引用 匹配的值。

<action name="*_*" class="com.ittianyu.javaeetest.web.action.{2}Action" method="{1}{2}">
    <result name="success">/{1}{2}.jsp</result>
</action>

如上配置,我們訪問 hello_World 時(shí),會自動(dòng)匹配方法 helloWorld,并在方法執(zhí)行完成后,轉(zhuǎn)發(fā)到 helloWorld.jsp

動(dòng)態(tài)方法調(diào)用

struts2 支持動(dòng)態(tài)指定 action所綁定的方法名,也就是不需要配置 action 的 method。
在請求中使用 !分割,后面寫調(diào)用的方法名。
比如:

http://127.0.0.1/struts2/user!add

默認(rèn)是關(guān)閉的,要使用需要配置。在 struts 標(biāo)簽下加上:

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

<a id="5"> </a>

5.OGNL

OGNL 是 Object Graph Navigation Language (對象圖形導(dǎo)航語言)的縮寫。
主要用來訪問 棧 和 map 中的對象。

  • 支持對象方法調(diào)用,如 xxx.doSomeSpecial();
  • 支持類靜態(tài)的方法調(diào)用和值訪問,表達(dá)式的格式:
    @[類全名]@[方法名 | 值名],例如:
    @java.lang.String@format('foo %s', 'bar') 或
    @tutorial.MyConstant@APP_NAME;
    
    但需要設(shè)置 struts.ognl.allowStaticMethodAccess=true
  • 支持賦值操作和表達(dá)式串聯(lián),如 price=100, discount=0.8,
    price*discount,這個(gè)表達(dá)式會返回80;
  • 訪問OGNL上下文(OGNL context)和ActionContext;
  • 操作集合對象。

在 jsp 中使用 OGNL 需要引入 struts tag lib。

<%@ taglib prefix="s" uri="/struts-tags" %>

然后使用 標(biāo)簽 s:property:

<s:property value="'hello world'"/>

使用引號引起來表示字符串,否則就是 OGNL 表達(dá)式

ValueStack

ValueStack 實(shí)際是一個(gè)接口,在 Struts2 中利用OGNL時(shí),實(shí)際上使用的是該接口實(shí)現(xiàn)類 OgnlValueStack。

每個(gè) Action 類的對象實(shí)例都有一個(gè) ValueStack 對象,用于保存參數(shù)或結(jié)果。

在 ValueStack 對象的內(nèi)部有兩個(gè)邏輯部分:

  • ObjectStack: Struts 把動(dòng)作和相關(guān)對象壓入 ObjectStack 中,看作 List 容器。
  • ContextMap: Struts 把各種各樣的映射關(guān)系存入 ContextMap 中,看作 Map 容器。

Struts2 會把下面這些對象存入 ContextMap 中

  • parameters: 該 Map 中包含當(dāng)前請求的請求參數(shù)
  • request: 該 Map 中包含當(dāng)前 request 對象中的所有屬性
  • session: 該 Map 中包含當(dāng)前 session 對象中的所有屬性
  • application:該 Map 中包含當(dāng)前 application 對象中的所有屬性
  • attr: 該 Map 按如下順序來檢索某個(gè)屬性: request, session, application

訪問 ValueStack

  • ObjectStack: 直接通過元素的名稱進(jìn)行訪問。
  • ContextMap: 需要在開頭加一個(gè) #。

比如 ObjectStack 和 ContextMap 中都存放了一個(gè) User,而 User
有屬性 username,那么我們可以通過如下代碼進(jìn)行訪問:

jsp 中:

<%--不加修飾符是在棧中查找對象是否有g(shù)etUsername方法
可以通過[n].來指定從第幾個(gè)開始查找,n從0開始
如果沒找到,就會報(bào)錯(cuò)
--%>
<s:property value="username" />

<%--加修飾符# 是在 map 中查找 key 為 user 的 值
如果存在 session 中,則訪問路徑為 #session.user.username
--%>
<s:property value="#user.username" />

Action 中:

ValueStack vs = ActionContext.getContext().getValueStack();
// setValue 方法的第一個(gè)參數(shù)是 OGNL 表達(dá)式,不加#表示放到棧中
vs.setValue("name", "Mike");// 在棧中查找是否有對象有 setName 方法
vs.setValue("#name", "Mike");// 往 map 中存入 key 為 name,值為 Mike 數(shù)據(jù)。

// set 方法是對 棧 進(jìn)行操作
// 如果棧頂是 map,則把數(shù)據(jù)放入map,否則在棧頂新建一個(gè) map,并存入數(shù)據(jù)。
vs.set("username", "Jane");

# $ % 的使用

  • 1、取 contextMap 中 key 時(shí)使用,例如 <s:property value="#name" />
    2、OGNL 中創(chuàng)建Map對象時(shí)使用,例如: <s:radio list="#{'male':'男','female':'女'}" />
  • $
    1、在JSP中使用EL表達(dá)式時(shí)使用,例如 ${name}
    2、在xml配置文件中,編寫OGNL表達(dá)式時(shí)使用,例如文件下載時(shí),文件名編碼。
    struts.xml——>${@java.net.URLEncoder.encode(filename)}
    
  • %
    在struts2中,有些標(biāo)簽的value屬性取值就是一個(gè)OGNL表達(dá)式,例如 <s:property value="OGNL Expression" />
    還有一部分標(biāo)簽,value屬性的取值就是普通字 符串,例如 <s:textfield value="username"/>,如果想把一個(gè)普通的字符串強(qiáng)制看成時(shí)OGNL,就需要使用 %{} 把字符串套起來。
    例如 <s:textfield value="%{username}"/>。當(dāng)然在 <s:property value="%{OGNL Expression}" /> 也可以使用,但不會這么用。

投影

  • “?#”:過濾所有符合條件的集合,如:users.{?#this.age > 19};
  • #”:過濾第一個(gè)符合條件的元素,如:users.{#this.age > 19};
  • “$#”:過濾最后一個(gè)符合條件的元素,如:users.{$#this.age > 19}

<a id="6"> </a>

6.Struts 標(biāo)簽

表單標(biāo)簽

常見的表單標(biāo)簽在 struts2 中都有

比如: form,textfield,password,checkbox,checkboxlist ,hidden,submit,reset 等。

<s:form action="register">
    <s:textfield name="username" label="用戶名" requiredLabel="true" requiredPosition="left"/>
    <s:password name="password" label="密碼"/>
    <s:textfield name="birthday" label="生日"/>
    <s:checkbox name="married" value="true" label="已婚"/>
    <s:checkboxlist list="{'吃飯','睡覺','寫代碼'}" name="hobby" label="愛好" />
    <s:select list="#{'BJ':'北京','SH':'上海','SZ':'深圳'}" label="城市" headerKey="" headerValue="---請選擇城市---"/>
    <s:radio name="gender" list="#{'male':'男','female':'女'}" label="性別" value="'male'"/>
    <s:textarea label="描述" rows="5" cols="30"/>
    <s:submit value="注冊" />
    <s:reset value="重置" />
</s:form>

set

<%-- set 屬性詳解
    value: ognl 表達(dá)式,會存入 map 中
    var:作為存入 map 數(shù)據(jù)的 key
    scope:指定存入的是哪個(gè) map,有 application,session,request,page,action
 --%>

<%-- 并不會往 map 中存入任何值,因?yàn)?value 被解釋為 OGNL 之后是非法的,所以結(jié)果是空 --%>
<s:set value="Mike" var="name" scope="session"/>

<%--  加上單引號之后,解釋為字符串,存到 session 中 --%>
<s:set value="'Mike'" var="name2" scope="session"/>

<%-- 不寫 scope 默認(rèn)存到 request 和 contextMap 中了 --%>
<s:set value="'Mike'" var="name3"/>

action

<%-- action 屬性詳解 
    name: action 名稱
    executeResult: 是否執(zhí)行 action
一般用于調(diào)用其他 action 并在頁面上顯示結(jié)果
--%>
<s:action name=="action1" executeResult="true">

if elseif else

<%--存入一個(gè)成績--%>
<s:set var="grade" value="90"/>
<s:if test="#grade<60">差</s:if>
<s:elseif test="#grade<80">中</s:elseif>
<s:else>優(yōu)秀</s:else>

url a

<%-- s:url 屬性詳解 
    value: 輸出的 value 值。不是 OGNL 表達(dá)式
    action: action 名稱
    var: 如果寫了,就會把 action 的地址存到 contextMap 中,var 作為 key。
--%>

<%-- 指定 value 直接在頁面輸出 value的值 --%>
<s:url value="哈哈哈"/> <br/>

<%-- 指定 action 在頁面輸出 action 的完整地址 --%>
<s:url action="addUser1"/> <br/>

<%-- 指定了 var 則存到 map 中 --%>
<s:url action="addUser1" var="url">
    <%--可定義參數(shù),相當(dāng)于get表單的地址一樣--%>
    <s:param name="name" value="'張三'"/>
</s:url>

a 標(biāo)簽和 url 類似

<a id="7"> </a>

7.Validator

struts2為我們共內(nèi)置了16個(gè)驗(yàn)證器,且全部是基于字段的驗(yàn)證器。

required

驗(yàn)證字段的值是不是 null。注意,不是空字符串或空白字符串。

<validators>
    <field name="password">
        <field-validator type="required">
            <message>The password field is required!</message>
        </field-validator>
    </field>
</validators>

requiredstring

驗(yàn)證字段的值既不是null、也不是空白。

參數(shù):

  • fieldName:要驗(yàn)證的字段名
  • trim:是否去掉首尾空格
<validators>
    <field name="userName">
        <field-validator type="requiredstring">
            <message>Please input the userName!</message>
        </field-validator>
    </field>
    <field name="password">
        <field-validator type="requiredstring">
            <param name="trim">false</param>
            <message>Please input the password!</message>
        </field-validator>
    </field>
</validators>

int

驗(yàn)證某個(gè)字段的值是否可以被轉(zhuǎn)換為一個(gè)整數(shù)。還可以驗(yàn)證是否在允許的范圍內(nèi)。

參數(shù):

  • fieldName:要驗(yàn)證的字段名
  • min:允許的最小值
  • max:允許的最大值

基于字段的驗(yàn)證

<validators>
    <field name="age">
        <field-validator type="int">
            <param name="min">18</param>
            <param name="max">60</param>
            <message>The age must be between ${min} and ${max}</message>
        </field-validator>
    </field>
</validators>

基于驗(yàn)證器的驗(yàn)證

<validators>
    <validator type="int">
        <param name="fieldName">age</param>
        <param name="min">18</param>
        <param name="max">60</param>
        <message>The age must be between ${min} and ${max}</message>
    </validator>
</validators>

long short

同 int

double

用來驗(yàn)證某個(gè)字段的值是否可以被轉(zhuǎn)換為一個(gè)雙精度浮點(diǎn)數(shù)。還可驗(yàn)證是否在允許的范圍內(nèi)。

參數(shù):

  • fieldName:要驗(yàn)證的字段名
  • minInclusive:允許的最小值,包含最小值
  • maxInclusive:允許的最大值,包含最大值
  • minExclusive:允許的最小值,不包含最小值
  • maxExclusive:允許的最大值,不包含最大值
<validators>
    <field name="percentage1">
        <field-validator type="double">
            <param name="minInclusive">20.1</param>
            <param name="maxInclusive">50.1</param>
            <message> The age must be between ${ minInclusive } and ${ maxInclusive }(含)</message>
        </field-validator>
    </field>
    <field name="percentage2">
        <field-validator type="double">
            <param name="minExclusive">0.345</param>
            <param name="maxExclusive">99.987</param>
            <message> The age must be between ${ minExclusive } and ${ maxExclusive }(不含)</message>
        </field-validator>
    </field>
</validators>

date

用來確保給定的日期字段的值在指定的范圍內(nèi)。

參數(shù):

  • fieldName:要驗(yàn)證的字段名
  • min:允許的最小值,包含最小值
  • max:允許的最大值,包含最大值
<validators>
    <field name="birthday">
        <field-validator type="date">
            <param name="min">2011-01-01</param>
            <param name="max">2011-12-31</param>
            <message>日期必須為2011年</message>
        </field-validator>
    </field>
</validators>

expression

用于驗(yàn)證是否滿足一個(gè)OGNL表達(dá)式。這是一個(gè)非字段的驗(yàn)證。只有給定的參數(shù)的返回值是true時(shí)才能驗(yàn)證通過。驗(yàn)證不通過時(shí)產(chǎn)生一個(gè)動(dòng)作錯(cuò)誤,因此要顯示該錯(cuò)誤,需要使用<s:actionerror/>標(biāo)簽。

<validators>
    <validator type="expression">
        <param name="expression">
            maxNumber>minNumber
        </param>
        <message>最大值必須大于最小值</message>
    </validator>
</validators>

field expression

用于驗(yàn)證某個(gè)字段是否滿足一個(gè)OGNL表達(dá)式。這是一個(gè)基于字段的驗(yàn)證。只有給定的參數(shù)的返回值是true時(shí)才能驗(yàn)證通過。驗(yàn)證不通過時(shí)產(chǎn)生一個(gè)字段錯(cuò)誤。

參數(shù):

  • fieldName:要驗(yàn)證的字段名
  • expression:OGNL表達(dá)式,只有該表達(dá)式為true才能驗(yàn)證通過
<validators>
    <field name="maxNumber">
        <field-validator type="fieldexpression">
            <param name="expression">
            maxNumber>100
        </param>
        <message>最大值必須大于最小值1</message>
        </field-validator>
    </field>
</validators>

email

用來驗(yàn)證給定的字段是否符合一個(gè)Email的規(guī)范。它的正則表達(dá)式為

\\b(^[_A-Za-z0-9-](\\.[_A-Za-z0-9-])*@([A-Za-z0-9-])+((\\.com)|(\\.net)|(\\.org)|(\\.info)|(\\.edu)|(\\.mil)|(\\.gov)|(\\.biz)|(\\.ws)|(\\.us)|(\\.tv)|(\\.cc)|(\\.aero)|(\\.arpa)|(\\.coop)|(\\.int)|(\\.jobs)|(\\.museum)|(\\.name)|(\\.pro)|(\\.travel)|(\\.nato)|(\\..{2,3})|(\\..{2,3}\\..{2,3}))$)\\b
<validators>
    <field name="email">
        <field-validator type="email">
            <message>請輸入正確的郵箱</message>
        </field-validator>
    </field>
</validators>

url

用來驗(yàn)證給定的字段值是否是一個(gè)合法的URL地址。

<validators>
    <field name="url">
        <field-validator type="url">
            <message>請輸入正確的地址</message>
        </field-validator>
    </field>
</validators>

visitor

該驗(yàn)證程序可以提高代碼的可重用性,你可以利用它把同一個(gè)驗(yàn)證程序配置文件用于多個(gè)動(dòng)作。

<validators>
    <field name="streetName">
        <field-validator type="requiredstring">
            <message>請輸入正確街道地址</message>
        </field-validator>
    </field>
</validators>

<validators>
    <field name="address">
        <field-validator type="visitor">
            <message>Address:</message>
        </field-validator>
    </field>
</validators>

stringlength

用來驗(yàn)證一個(gè)非空的字段值是不是有足夠的長度。

regex

用來檢查給定字段是否與給定的正則表達(dá)式相匹配。正則表達(dá)式的詳細(xì)內(nèi)容可以參考 JDK 的 java.util.regex.Pattern 類。

參數(shù):

  • fieldname:要驗(yàn)證的字段名
  • expression:正則表達(dá)式
  • caseSensitive:是否區(qū)分大小寫的情況,默認(rèn) true
  • trim:是否去掉首尾空格,默認(rèn) true
<validators>
    <field name="userName">
        <field-validator type="regex">
            <param name="expression"><![CDATA[([aAbBcCdD][123][eEfFgG][456])]]></param>
            <message> 用戶名必須符合規(guī)范</message>
        </field-validator>
    </field>
</validators>

<a id="8"> </a>

8.Interceptor

Struts2 攔截器在訪問某個(gè) Action 方法之前或之后實(shí)施攔截, Struts2 攔截器是可插拔的, 攔截器是 AOP 的一種實(shí)現(xiàn).

常用攔截器

  • conversionError:將錯(cuò)誤從ActionContext中添加到Action的屬性字段中。
  • fileUpload:提供文件上傳功能
  • i18n:記錄用戶選擇的locale
  • model-driven:如果一個(gè)類實(shí)現(xiàn)了ModelDriven,將getModel得到的結(jié)果放在Value Stack中。
  • params:將請求中的參數(shù)設(shè)置到Action中去。
  • servletConfig:提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。
  • token:避免重復(fù)提交
  • validation:使用 action-validation.xml 文件中定義的內(nèi)容校驗(yàn)提交的數(shù)據(jù)。
  • workflow:調(diào)用 Action 的 validate 方法,一旦有錯(cuò)誤返回,重新定位到 INPUT 視圖

自定義攔截器

  1. 自定義攔截器
    public class PermissionInterceptor implements Interceptor {
       private static final long serialVersionUID = -5178310397732210602L;
       public void destroy() {
       }
       public void init() {
       }
       public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("進(jìn)入攔截器");    
        if(session里存在用戶){
            String result = invocation.invoke();
        }else{
            return “l(fā)ogon”;
        }
        //System.out.println("返回值:"+ result);
        //return result;
        }
    }
    
  2. 在 struts.xml 文件中配置自定義的攔截器
    <package name="itcast" namespace="/test" extends="struts-default">
        <interceptors>
                 <interceptor name=“permission" class="cn.itcast.aop.PermissionInterceptor" />
                 <interceptor-stack name="permissionStack">
             <interceptor-ref name="defaultStack" />
            <interceptor-ref name=" permission " />
                  </interceptor-stack>
        </interceptors>
        <action name="helloworld_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
            <result name="success">/WEB-INF/page/hello.jsp</result>
            <interceptor-ref name="permissionStack"/>
        </action>
    </package>
    

<a id="9"> </a>

9.國際化

struts2 中使用的 properties 文件來做國際化

配置資源包

  • 全局資源包
<!--
在struts.xml 中配置常量指定全局字符串包位置
-->
<constant name="struts.custom.i18n.resources" value="com.ittianyu.i18n.strings" />
  • 包范圍的資源包:把 資源包放在某包下面,命名為:package_語言代碼_國家代碼.properties
  • 局部消息資源包:把 資源包放在某動(dòng)作類路徑下,命名為:動(dòng)作類名稱_語言代碼_國家代碼.properties

資源包的使用順序:局部 > 包范圍 > 全局

讀取資源包

  • Action
    public class I18nAction extends ActionSupport {
        public String execute() {
            String value = getText("key");
        }
    }
    
  • jsp
    <s:text name="key"/>
    

手動(dòng)指定讀取的資源包

當(dāng)注定的包下沒有找到指定的值時(shí),會按順序搜索配置了的資源包

<s:i18n name="com.xxxx.package">
    <s:text name="key"/>
</s:i18n>

<a id="10"> </a>

10.常見例子

防重復(fù)提交

  1. 使用重定向,避免刷新就提交

        <result type="redirect">/success.jsp</result>
    
  2. 使用 tokensession 或 token 攔截器
    表單中加入 <s:token />

        <s:form action="login">
            <s:token />
        </s:form>
    

    配置中加入 tokensession 攔截器

    <action name="login" class="xxxx">
        <interceptor-ref name="defaultStack" />
        <interceptor-ref name="tokensession" />
        <result type="redirect">/success.jsp</result>
    </action>
    

    token 和 tokensession 功能一樣,但有一些差別。
    token 攔截到重復(fù)提交后,會轉(zhuǎn)向 invalid.token 結(jié)果視圖
    而 tokensession 攔截之后不轉(zhuǎn)向任何視圖

上傳

html

<s:form action="upload.action" enctype="multipart/form-data">
    <s:textfield name="username" label="用戶名"/>
    <s:file name="photo" label="照片"/>
    <s:submit value="上傳"/>
</s:form>

action

public class UploadAction extends ActionSupport{
    public String username;
    public File photo;
    public String photoFileName;// 上傳文件名。變量命名規(guī)格 字段名+FileName
    public String photoContentType;// 上傳文件的MIME類型。變量命名規(guī)格 字段名+ContentType

    public String upload() {
        // 獲取文件存儲目錄
        ServletContext servletContext = ServletActionContext.getServletContext();
        String path = servletContext.getRealPath("/WEB-INF/files");
        File file = new File(path);
        if (!file.exists())
            file.mkdirs();
        // 存儲到目標(biāo)路徑
        photo.renameTo(new File(file, photoFileName));
        return NONE;
    }
}

修改上傳文件大小限制

<!--限制上傳最大尺寸為 1048576 byte-->
    <constant name="struts.multipart.maxSize" value="1048576"/>

限制上傳文件擴(kuò)展名

<action name="upload" class="com.ittianyu.javaeetest.web.action.UploadAction" method="upload">
    <interceptor-ref name="defaultStack">
        <param name="fileUpload.allowedExtensions">jpg,png</param>
    </interceptor-ref>
    <result name="input">upload.jsp</result>
</action>

多文件上傳需要把

public File photo;
public String photoFileName;// 上傳文件名。變量命名規(guī)格 字段名+FileName
public String photoContentType;// 上傳文件的MIME類型。變量命名規(guī)格 字段名+ContentType

改成,也就是改成數(shù)組

public File[] photo;
public String[] photoFileName;// 上傳文件名。變量命名規(guī)格 字段名+FileName
public String[] photoContentType;// 上傳文件的MIME類型。變量命名規(guī)格 字段名+ContentType

下載

action

public class DownloadAction extends ActionSupport {
    public InputStream inputStream;
    public String filename;

    public String download() throws Exception{
        // 找到文件路徑
        String path = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/1.jpg");
        // 包裝成流
        inputStream = new FileInputStream(path);
        // 設(shè)置瀏覽器接收時(shí)文件名
        filename = "圖片.jpg";

        return SUCCESS;
    }
}

配置

<action name="download" class="com.ittianyu.javaeetest.web.action.DownloadAction" method="download">
    <result name="success" type="stream">
        <!--下載類型為 bin-->
        <param name="contentType">application/octet-stream</param>
        <!--下載打開方式-->
        <param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename, "UTF-8")}
        </param>
        <!--流名稱-->
        <param name="inputName">inputStream</param>
    </result>
</action>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容