超全面 struts2 復習總結(jié)筆記

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

前言

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


從去年開始就經(jīng)澄悄保看到別人提“移動開發(fā)寒冬”忠蝗,而年初投簡歷的時候更是親身體會,不寫3年經(jīng)驗連面試機會都沒有漓拾,那么沒有經(jīng)驗或經(jīng)驗少的人能怎么辦呢阁最,從一開就找不到工作怎么可能會有經(jīng)驗?


然而絕望并沒有用骇两,我算運氣好速种,勉強找到一份工作。

從趨勢來看低千,近幾年移動開發(fā)待遇不會很好配阵,今年發(fā)現(xiàn)到處缺后端,于是決定還是搞后端吧示血,因為搞安卓不過一年棋傍,后端的知識還沒忘完(好吧,實際上以前后端也沒多深入)难审,于是利用下班時間復習后端(好吧瘫拣,其實好多是預習了●﹏●),并把知識整理出來分享給大家告喊。

目錄

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

正文

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

1.環(huán)境搭建

導包

  • 版本管理工具導入

    • 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 攔截器失球。

配置的時候需要注意,不同的版本的 StrutsPrepareAndExecuteFilter 包路徑不一樣,配置的時候实苞,可以用 IED 搜索這個類豺撑,復制路徑。比如 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

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

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

配置 Action

類似于 Servlet金赦,struts2 使用 action 來處理請求音瓷。
使用 action 需要進行配置。

xml 配置

在 struts.xml 的 struts 標簽里面配置 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 的屬性,后面配置詳解里會一一介紹大部分標簽和屬性漠烧。

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

注解配置

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

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

@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;
    }
}

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

向 Action 傳遞參數(shù)

登錄是很常見的 action堕担,這個時候一般要向服務器傳遞 username, password 等已慢。

User

創(chuàng)建一個 User 實體對象,假設(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)建一個 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;
    }
}

實現(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

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

action

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

result

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

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

type 類型

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

global-results

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

interceptors

用于聲明攔截器璃俗。

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

default-interceptor-ref

用于配置包的默認攔截器悉默。

constant

用于配置 struts2 中的常量。

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

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

通配符

struts2 中 action 的 name 支持通配符 *苟穆。
用于匹配0個或多個字符抄课。
舊版中可以直接使用,在新版中雳旅,需要啟用通配符跟磨。
在 package 開頭加上

<!--動態(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 時,會自動匹配方法 helloWorld型豁,并在方法執(zhí)行完成后僵蛛,轉(zhuǎn)發(fā)到 helloWorld.jsp

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

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

http://127.0.0.1/struts2/user!add

默認是關(guān)閉的衣形,要使用需要配置驼侠。在 struts 標簽下加上:

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

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

5.OGNL

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

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

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

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

然后使用 標簽 s:property:

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

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

ValueStack

ValueStack 實際是一個接口蔬捷,在 Struts2 中利用OGNL時垄提,實際上使用的是該接口實現(xiàn)類 OgnlValueStack。

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

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

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

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

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

訪問 ValueStack

  • ObjectStack: 直接通過元素的名稱進行訪問勾给。
  • ContextMap: 需要在開頭加一個 #滩报。

比如 ObjectStack 和 ContextMap 中都存放了一個 User,而 User
有屬性 username播急,那么我們可以通過如下代碼進行訪問:

jsp 中:

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

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

Action 中:

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

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

# $ % 的使用

  • 1、取 contextMap 中 key 時使用长已,例如 <s:property value="#name" />
    2悬蔽、OGNL 中創(chuàng)建Map對象時使用,例如: <s:radio list="#{'male':'男','female':'女'}" />
  • $
    1怨绣、在JSP中使用EL表達式時使用柱查,例如 ${name}
    2、在xml配置文件中,編寫OGNL表達式時使用,例如文件下載時,文件名編碼伶椿。
    struts.xml——>${@java.net.URLEncoder.encode(filename)}
    
  • %
    在struts2中,有些標簽的value屬性取值就是一個OGNL表達式氓侧,例如 <s:property value="OGNL Expression" />
    還有一部分標簽脊另,value屬性的取值就是普通字 符串,例如 <s:textfield value="username"/>约巷,如果想把一個普通的字符串強制看成時OGNL偎痛,就需要使用 %{} 把字符串套起來。
    例如 <s:textfield value="%{username}"/>独郎。當然在 <s:property value="%{OGNL Expression}" /> 也可以使用踩麦,但不會這么用。

投影

  • “?#”:過濾所有符合條件的集合氓癌,如:users.{?#this.age > 19}谓谦;
  • #”:過濾第一個符合條件的元素,如:users.{#this.age > 19}贪婉;
  • “$#”:過濾最后一個符合條件的元素反粥,如:users.{$#this.age > 19}

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

6.Struts 標簽

表單標簽

常見的表單標簽在 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 表達式谓松,會存入 map 中
    var:作為存入 map 數(shù)據(jù)的 key
    scope:指定存入的是哪個 map星压,有 application,session,request,page,action
 --%>

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

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

<%-- 不寫 scope 默認存到 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

<%--存入一個成績--%>
<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 表達式
    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ù),相當于get表單的地址一樣--%>
    <s:param name="name" value="'張三'"/>
</s:url>

a 標簽和 url 類似

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

7.Validator

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

required

驗證字段的值是不是 null。注意甘桑,不是空字符串或空白字符串拍皮。

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

requiredstring

驗證字段的值既不是null歹叮、也不是空白。

參數(shù):

  • fieldName:要驗證的字段名
  • 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

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

參數(shù):

  • fieldName:要驗證的字段名
  • min:允許的最小值
  • max:允許的最大值

基于字段的驗證

<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>

基于驗證器的驗證

<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

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

參數(shù):

  • fieldName:要驗證的字段名
  • 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:要驗證的字段名
  • 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

用于驗證是否滿足一個OGNL表達式。這是一個非字段的驗證惫确。只有給定的參數(shù)的返回值是true時才能驗證通過手报。驗證不通過時產(chǎn)生一個動作錯誤,因此要顯示該錯誤改化,需要使用<s:actionerror/>標簽掩蛤。

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

field expression

用于驗證某個字段是否滿足一個OGNL表達式。這是一個基于字段的驗證陈肛。只有給定的參數(shù)的返回值是true時才能驗證通過揍鸟。驗證不通過時產(chǎn)生一個字段錯誤。

參數(shù):

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

email

用來驗證給定的字段是否符合一個Email的規(guī)范阳藻。它的正則表達式為

\\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

用來驗證給定的字段值是否是一個合法的URL地址。

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

visitor

該驗證程序可以提高代碼的可重用性谈撒,你可以利用它把同一個驗證程序配置文件用于多個動作腥泥。

<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

用來驗證一個非空的字段值是不是有足夠的長度。

regex

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

參數(shù):

  • fieldname:要驗證的字段名
  • expression:正則表達式
  • caseSensitive:是否區(qū)分大小寫的情況,默認 true
  • trim:是否去掉首尾空格溯乒,默認 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 攔截器在訪問某個 Action 方法之前或之后實施攔截, Struts2 攔截器是可插拔的, 攔截器是 AOP 的一種實現(xiàn).

常用攔截器

  • conversionError:將錯誤從ActionContext中添加到Action的屬性字段中夹厌。
  • fileUpload:提供文件上傳功能
  • i18n:記錄用戶選擇的locale
  • model-driven:如果一個類實現(xiàn)了ModelDriven,將getModel得到的結(jié)果放在Value Stack中裆悄。
  • params:將請求中的參數(shù)設(shè)置到Action中去矛纹。
  • servletConfig:提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問光稼。
  • token:避免重復提交
  • validation:使用 action-validation.xml 文件中定義的內(nèi)容校驗提交的數(shù)據(jù)或南。
  • workflow:調(diào)用 Action 的 validate 方法逻住,一旦有錯誤返回,重新定位到 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("進入攔截器");    
        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
  • 局部消息資源包:把 資源包放在某動作類路徑下瞎访,命名為:動作類名稱_語言代碼_國家代碼.properties

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

讀取資源包

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

手動指定讀取的資源包

當注定的包下沒有找到指定的值時,會按順序搜索配置了的資源包

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

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

10.常見例子

防重復提交

  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 攔截到重復提交后冀瓦,會轉(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();
        // 存儲到目標路徑
        photo.renameTo(new File(file, photoFileName));
        return NONE;
    }
}

修改上傳文件大小限制

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

限制上傳文件擴展名

<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è)置瀏覽器接收時文件名
        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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市询微,隨后出現(xiàn)的幾起案子崖瞭,更是在濱河造成了極大的恐慌,老刑警劉巖撑毛,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件书聚,死亡現(xiàn)場離奇詭異,居然都是意外死亡藻雌,警方通過查閱死者的電腦和手機雌续,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胯杭,“玉大人驯杜,你說我怎么就攤上這事∏复荩” “怎么了艇肴?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叁温。 經(jīng)常有香客問我,道長核畴,這世上最難降的妖魔是什么膝但? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谤草,結(jié)果婚禮上跟束,老公的妹妹穿的比我還像新娘莺奸。我一直安慰自己,他們只是感情好冀宴,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布灭贷。 她就那樣靜靜地躺著,像睡著了一般略贮。 火紅的嫁衣襯著肌膚如雪甚疟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天逃延,我揣著相機與錄音览妖,去河邊找鬼。 笑死揽祥,一個胖子當著我的面吹牛讽膏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拄丰,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼府树,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了料按?” 一聲冷哼從身側(cè)響起挺尾,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎站绪,沒想到半個月后遭铺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡恢准,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年魂挂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馁筐。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡涂召,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敏沉,到底是詐尸還是另有隱情果正,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布盟迟,位于F島的核電站秋泳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏攒菠。R本人自食惡果不足惜迫皱,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辖众。 院中可真熱鬧卓起,春花似錦和敬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奕筐,卻和暖如春舱痘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背救欧。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工衰粹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笆怠。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓铝耻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹬刷。 傳聞我的和親對象是個殘疾皇子瓢捉,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容