<filter> 前端
<filter-name>struts2</filter-name> web
<filter-class> 正則表達式
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter express
</filter-class> apache
</filter> 數組
<filter-mapping> 瀏覽器
<filter-name>struts2</filter-name> session
<url-pattern>/*</url-pattern> app
</filter-mapping> dom
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- 頭部信息能夠在自帶jar包的例子中找 -->
<struts>
</struts>
命名規則: actionname+「-」+conversion.properties
配置demo:birthday = cn.xiaoge.convert.MyConverter
birthday:須要轉換的字段名稱
cn.xiaoge.convert.MyConverter:自定義類型轉換器的全稱類名
1.4.1 自定義攔截器類
a. 實現Interceptor接口
b. 繼承AbstractInterceptor類
c. 繼承MethodFilterInterceptor類(首選)
1.4.2 配置攔截器(在struts.xml中配置)
a.註冊自定義攔截器
b.自定義攔截器棧
c.將自定義攔截器棧生命爲默認攔截器棧
<interceptors>
<!-- #1 配置自定義的攔截器 -->
<interceptor name="loginInterceptor" class="cn.xiaoge.web.interceptor.LoginInterceptor">
</interceptor>
<!-- #2 配置自定義攔截器棧 -->
<interceptor-stack name="loginStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="loginInterceptor">
param name="excludeMethods">login</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 3.配置自定義攔截器棧 -->
<default-interceptor-ref name="loginStack"></default-interceptor-ref>
1.5.1 全局配置
命名規則:配置名+「_」+「國家」+」_」+「地區」(可省略)+」.properties」
存放位置: src目錄下
配置文件中配置: name = value
在jsp中的用法:<s:text name="tip"></s:text>
備註: tip是配置文件中的name
在struts.xml中配置:
<constant name="struts.custom.i18n.resources" value="wel"></constant>
1.5.2 包級別配置
命名規則:配置名+「_」+「國家」+」_」+「地區」(可省略)+」.properties」
存放位置:相應包下
備註:在經過action訪問頁面時,會加載包級別的國際化資源配置
1.5.3 action級別配置
命名規則:Action名字+「_」+「國家」+」_」+「地區」(可省略)+」.properties」
存放位置:與相應的action同包
備註:訪問action時,會加載action級別的國際化資源配置,
1.5.3 臨時配置
命名規則:配置名+「_」+「國家」+」_」+「地區」(可省略)+」.properties」
存放位置:src文件夾下
備註:在jsp中使用方法(其中,「ls」是臨時配置文件的文件名)
<s:i18n name="ls">
<s:text name="tip"></s:text>
</s:i18n>
備註:
在action中使用時:(使用getText()方法)
public class I18nAction extends ActionSupport {
private String name;
@Override
public String execute() throws Exception {
addFieldError("name", getText("title"));
System.out.println(getText("title"));
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在xml文件中使用時:(title是國際化配置文件中的鍵)
<validators>
<field name="name">
<field-validator type="requiredstring">
<message key="title" ></message>
</field-validator>
</field>
</validators>
1.6.1 xml配置信息(記得添加dtd文件: xwork-core-2.3.15.3.jar /xwork-validator-1.0.3.dtd)
單個方法進行校驗配置(針對某個action的方法有效)
命名規則:ActionName +「-」+ action的請求路徑(xx_add) +「-」+validation.xml
放置位置:與訪問的action同包
全局方法進行校驗配置(對action中的全部方法有效)
命名規則:ActionName +「-」+validation.xml
放置位置:與訪問的action同包
1.6.2 數據校驗器:
位置:xwork-core-2.3.15.3.jar /com.opensymphony.xwork2.validator.validators/default
<validator name="required" 判斷對象是否爲空
<validator name="requiredstring" 判斷字符串是否爲空
<validator name="int" 可判斷數值範圍
<validator name="long" 可判斷數值範圍
<validator name="short" 可判斷數值範圍
<validator name="double" 可判斷數值範圍
<validator name="date" 可判斷日期範圍
<validator name="expression" 可判斷表達式
<validator name="fieldexpression"
<validator name="email" 可判斷格式是否符合eamil的格式
<validator name="url" 可判斷格式是否符合URL格式
<validator name="visitor"
<validator name="conversion"
<validator name="stringlength"
<validator name="regex" 可用來自定義正則表達式
<validator name="conditionalvisitor"
1.6.3 xml驗證案例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<field name="name">
<field-validator type="requiredstring">
<message>用戶名不能爲空</message>
</field-validator>
</field>
<field name="age">
<field-validator type="required">
<message>年齡不能爲空</message>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">160</param>
<message>請輸入${min}到${max}之間的數字</message>
</field-validator>
</field>
<field name="birthday">
<field-validator type="date">
<param name="min">1900-01-01</param>
<param name="max">2016-01-01</param>
<message>請輸入有效日期[${min}-${max}]</message>
</field-validator>
</field>
</validators>
1.6.4 手動數據校驗
在action中,重寫validate方法(action必須先繼承ActionSupport類)
@Override
public void validate() {
if("".equals(vname.trim()) || vname.length() == 0){
addFieldError("", "用戶名不能爲空");
}
if("".equals(vpsd.trim()) || vpsd.length() == 0){
addFieldError("", "密碼不能爲空");
}else{
if(vpsd.length() < 6){
addFieldError("", "密碼長度不能低於6位");
}
}
}
小結:
配置文件比較總結 |
||||
配置類型 |
web.xml |
struts.xml |
.xml文件 |
.properties文件 |
前端控制器 |
1 |
|
|
|
Action配置 |
|
1 |
|
|
數據轉換器 |
|
|
|
1 |
攔截器 |
|
1 |
|
|
數據校驗器 |
|
|
1 |
|
國際化資源 |
|
1 |
|
1 |
OGNL可分爲context與root部分(存放數據,要求有OgnlContext對象)
context中存放Map類型數據,root理論上存聽任何類型數據(root底層也是map)
//獲取root中對象的username屬性值
System.out.println(Ognl.getValue("userName", oc, oc.getRoot()));
//獲取context中鍵名爲name1的值的長度
System.out.println(Ognl.getValue("#name1.length()", oc, oc.getRoot()));
//獲取context中鍵名爲name2的值
System.out.println(Ognl.getValue("#name2", oc, oc.getRoot()));
//將context中鍵名爲name2的值以大寫形式輸出
System.out.println(Ognl.getValue("#name2.toUpperCase()", oc, oc.getRoot()));
//獲取數組中指定位置的值
System.out.println(Ognl.getValue("{1,2,3}[2]", oc, oc.getRoot()));
System.out.println(Ognl.getValue("{1,2,3}.get(2)", oc, oc.getRoot()));
//獲取數組中指定鍵的值
System.out.println(Ognl.getValue("#{'name':'tommap','age':18}['name']", oc, oc.getRoot()));
System.out.println(Ognl.getValue("#{'name':'tommap','age':18}.get('name')", oc, oc.getRoot()));
//投影及選擇都是對list而言的
//投影(記得是在root中取值,即list)
List<User> list = new ArrayList<User>();
list.add(new User("tom",18));
list.add(new User("jack",20));
list.add(new User("jerry",12));
list.add(new User("rose",16));
oc.setRoot(list);
System.out.println(Ognl.getValue("#this.{userName}", oc, oc.getRoot()));
//選擇(從投影結果中,選取內容)
System.out.println(Ognl.getValue("#this.{?age > 15}.{userName}", oc, oc.getRoot()));
備註:
獲取root中的數據,不須要添加「#」,可是獲取Context中的數據,必須添加「#」
訪問靜態類的靜態方法或屬性,須要在類前及方法前添加「@「
將strut2中的Map類型數據,放到ognl的context中,其餘類型數據放入到root,以便在前臺jsp頁面中,利用ognl表達式進行取值顯示。
其中,須要用到ActionContext進行存值
表單標籤demo:
<s:form action="personAction" namespace="/" method="post">
<s:textfield name="name" label="姓名"></s:textfield>
<s:password name="password" label="密碼"></s:password>
<s:textfield name="age" label="年齡"></s:textfield>
<s:select list="#{'UK':'英國','US':'美國','KR':'韓國'}" label="國籍" name="country" headerKey="CN" headerValue="中國"></s:select>
<s:radio list="#{'boy':'男','girl':'女'}" name="gender" label="性別"></s:radio>
<s:checkboxlist name="hobby" label="愛好" list="{'籃球','足球','乒乓球'}"></s:checkboxlist>
<s:submit value="提交"></s:submit>
</s:form>
數據標籤:
<s:if if elseif else通常連用,相似於c標籤庫中的 <c:choose>標籤
<s:elseif
<s:else
<s:iterator 迭代器,用法相似於c標籤庫中的 <c:foreach>標籤
<s:iterator value="#person.hobby" var="hob">
<s:property value="hob"/>
</s:iterator>
控制標籤:
a 超連接標籤,提供namespace與actionname可自動拼裝訪問路徑
param 參數標籤,通常與a標籤連用,用來存放標籤中的參數
url 訪問路徑標籤,能夠自動生成路徑,在拼裝時,注意設置escapeApm屬性
property 屬性標籤,用來獲取ognl中存放的數值
非表單標籤:
ActionMessage action中的提示信息
ActionError action中的錯誤信息
FiledError 字段錯誤信息
文件上傳中jsp的要求:
(1)form中enctype=」multipart/form-data」
(2)form表單的提交方式要求是post
(3)form中上傳組件的name要與action中的file的name保持一致
Action中要求:
(1)要求準備三個屬性:
private File image; //其中image是上傳的jsp文件中的組件名
private String imageFilename; //用於保存上傳文件的文件名
private String imageContentType; //用於保存上傳文件的文件類型
(2)準備這個三個屬性的setter方法: 用於封裝上傳文件的相關數據
Action中execute的流程:
(1)獲取上傳位置的真實路徑
String dir = ServletActionContext.getServletContext().getRealPath("/WEB-INF/temp");
(2)拷貝文件
FileUtils.copyFile(image, new File(dir , imageFileName));
(3)返回視圖
jsp頁面:
準備下載的超連接,action=「執行下載操做的action」
下載action中:
準備兩個屬性:
private InputStream target; //用於存放文件流
private String downName; //用於存放文件名
準備這兩個屬性的getter方法:getTarget() 及getDownName()
//getter方法做用:便於在strust.xml中讀取字符流,獲取文件名
準備執行的下載方法:
在方法中準備 InputStream 及 文件名:
//下載文件
public String download() throws UnsupportedEncodingException{
//獲取下載的文件名
String dname = ServletActionContext.getRequest().getParameter("dfilename");
//解決下載文件中的中文亂碼問題
this.downName = new String(dname.getBytes("ISO-8859-1"),"UTF-8");
//獲取下載的文件路徑並以流的方式獲取要下載的文件
String dpath = ServletActionContext.getRequest().getParameter("dpath");
this.target = ServletActionContext.getServletContext().getResourceAsStream(dpath);
//返回視圖
return "download";
}
struts.xml中配置:
<result name="download" type="stream">
<param name="contentDisposition">attachment;filename=${downName}</param>
<param name="inputName">target</param>
</result>
相似於驗證碼的功能,主要用於避免表單的重複提交,惡意註冊等
jsp中:
隨機生成一個字符串
將隨機字符串存放到session做用域
將隨機字符串以隱藏域的方式發送給瀏覽器
(<input type=」hidden」name=」token」 value=」隨機字符串」>)
token攔截器:
得到session中存放的隨機字符串,而後將session做用域的內容移除
得到標籤提交的隱藏域的字符串
將得到的session中的字符串與表單提交的字符串進行比較匹配
若是一致,正常提交;
若是不一致,返回字符串「invalid.token」
自定義實現:
<%--
//自定義實現
String tokenId = UUID.randomUUID().toString(); //生成隨機字符串
session.setAttribute("tokenId", tokenId); //將字符串放到session域中
//將隨機字符串放到hidden標籤中,並在瀏覽器端保存
out.print("<input type='hidden' name='mytoken' value='"+tokenId+"'>");
--%>
jsp中代碼:
<s:form namespace="/" action="demo05Action">
<s:token></s:token>
<s:submit value="提交"></s:submit>
</s:form>
action中代碼:
public String execute() throws Exception {
System.out.println("成功");
return NONE;
}
struts.xml中配置:
<action name="demo05Action" class="cn.itcast.demo05.TokenAction">
<!-- token出錯處理 -->
<result name="invalid.token">/demo05/message.jsp</result>
<!-- 添加攔截器,屬於action級別的攔截器,與package級別的攔截器不一樣-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="token"></interceptor-ref>
</action>
message.jsp中代碼:(用於顯示錯誤信息)
<s:fielderror></s:fielderror>
<s:actionerror/>