原創(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)到處缺后端,于是決定還是搞后端吧示血,因為搞安卓不過一年棋傍,后端的知識還沒忘完(好吧,實際上以前后端也沒多深入)难审,于是利用下班時間復習后端(好吧瘫拣,其實好多是預習了●﹏●),并把知識整理出來分享給大家告喊。
目錄
- 環(huán)境搭建
- Action
- 配置詳解
- 通配符和動態(tài)方法調(diào)用
- OGNL
- Struts 標簽
- Validator
- Interceptor
- 國際化
- 常見例子
正文
<a id="1"> </a>
1.環(huán)境搭建
導包
- 直接下載導入
http://struts.apache.org/download.cgi
可根據(jù)需要選擇 all min src 等包麸拄,如果僅僅是學習,選擇 min 包就夠了
-
版本管理工具導入
- 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"
- Gradle
配置
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)用和值訪問,表達式的格式:
@[類全名]@[方法名 | 值名]笋熬,例如:
但需要設(shè)置 struts.ognl.allowStaticMethodAccess=true@java.lang.String@format('foo %s', 'bar') 或 @tutorial.MyConstant@APP_NAME碟渺;
- 支持賦值操作和表達式串聯(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的規(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 視圖
自定義攔截器
- 自定義攔截器
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; } }
- 在 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.常見例子
防重復提交
-
使用重定向吁恍,避免刷新就提交
<result type="redirect">/success.jsp</result>
-
使用 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>