1.使用默認攔截器時,<package>元素必須要有extends = "struts-default"
2.pageContext的作用。jsp九大內置對象都是通過pageContext來初始化的。
3.防止表單重複提交可以使用token攔截器(不過很少用),具體使用過程就是添加下邊的代碼:
①在相應的action中配置
<package name="test" namespace="/" extends="struts-default">
<action name="test" class="com.bjsxt.interceptor.InterceptorServlet">
<interceptor-ref name="token"></interceptor-ref>
<result name="success">/ok.jsp</result>
<result name="invalidate.token">/tokenInvalidate.jsp</result>
</action>
</package>
②增加tokenInvalidate.jsp
<%@ page language="java" jmport="java.util.*" pageEncoding="utf-8"%>
<h1>表單不能重複提交</h1>
③在所提交的表單上邊增加<s:token>標記
<s:token action="InterceptorServlet">
<s:textfield name="uname"><s:/textfield>
<s:token></s:token>
<s:submit></s:submit>
</s:token>
4.在官方默認的是
private File file;
private String contentType;
若要是自己寫,應該做相應的改變
private File upload;
private String uploadContentType;//一定要對應寫
5.在action的指定方法執行完畢後總會返回一個字符串,struts2根據返回的字符串(注意爲字符串,也就是說返回值是string類型)去action的配置中的result去找匹配的名字,根據配置執行下一步的操作。一個action可以有多個result.所以action中方法的返回值都是string類型。雖然有時用void也能達到同樣的目的,但這不完整,只能實現一部分功能。下邊用例子說明。如
UserAction中
public String add(){
uDao.add(user);
return "success";
}
對應的struts.xml如下
<action name="userAction" class="com.bjsxt.action.UserAction" >
<result name="success">/jsp/ok.jsp</result>
<result name="list" >/jsp/list.jsp</result>
</action>
表示在成功添加用戶後,會返回到一個頁面,體驗比較好。
public void add(){
uDao.add(user);
}
對應的struts.xml如下
<action name="userAction" class="com.bjsxt.action.UserAction" >
</action>
這樣也可以添加進用戶,但在成功添加後,也不會出現任何提示,體驗不好。所以推薦返回值爲string類型的。
6.struts2裏的模型驅動和屬性驅動還得注意在jsp頁面的寫法
屬性驅動property-driven必須這樣寫
用戶名:<input name="user.name"><br/><!--必須這樣寫,因爲它是通過屬性注入的,否則存不到數據庫 -->
手機號:<input name="user.tel"><br/>
模型驅動model-driven通常這樣寫
用戶名:<input name="name"><br/>
手機號:<input name="tel"><br/>
雖然它的jsp頁面也可以寫成和屬性驅動一樣的屬性驅動還必須得寫相應的get/set方法,模型驅動不需要
7.要在jsp頁面使用c標籤,除了要添加引入語句
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
之外,還得有一個前提,那就是action向作用域設置了值。如
request.setAttribute("role",role);
纔可以在jsp利用el表達式頁面獲取到。
而s標籤是struts2內置的,若想使用,則除了引入語句
<%@ taglib prefix="s" uri="/struts-tags" %>
之外,還是得往作用域中添加,這時與c標籤不一樣,c得手動添加,而s必須有相應的值才行,向作用域添加已經內部封裝。如
public String findAll(){
this.list = uDao.findAll();
return "view";
}
只要定義了那個list,在jsp頁面就可以用
<s:iterator value="list" var="result">
<result.name>
<result.id>
</s:iterator>
這樣的獲取,s標籤中value="list"的list和this.list中的對應。
有時獲取value前邊還得加一個#,這是爲了獲取stack context中的值(stack context常和value stack一起出現,可以用<s:debug>調出)。這也是ognl表達式。如:
Map<Integer,String> roleMap = new HashMap<Integer, String>();
roleMap.put(1, "學生");
roleMap.put(2, "教師");
sc.setAttribute("roleMap", roleMap);
此時在jsp頁面獲取roleMap時是這樣
<s:iterator value="#application.roleMap" var="obj" >
<s:property value="#application.roleMap[#obj.type]" /><!--不要忘記最後的“/”,否則報錯-->
</s:iterator>
8.struts的作用,把請求和視圖分開;namespace若不爲空,則必須以“/”開頭;
result的默認name爲success,若不寫,即表示name爲success;
struts2裏的action最好繼承ActionSupport,因爲它裏邊封裝了許多方法,可以直接繼承來使用。比如可以直接使用execute方法。不繼承會很麻煩,企業裏幾乎所有struts2都要繼承ActionSupport。
9.struts2可以通過屬性接收參數,即直接在瀏覽器地址欄輸入
http://localhost:8080/testStruts/userAction!add?name=aa&age=20
這樣的值,那麼本質上name和age是怎樣被action接受的?如Action爲
public class UserAction extends ActionSupport {
private String name;
//name和age能否被接收只與getName,getAge等方法中get後的參數有關
//而與這兩處聲明的全局變量是什麼無關,如只要get方法不變,這兒就
//算改爲private String ttttttname也能被正確接收
//但默認全局變量名和get中一致
private intring add() {
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
name和age能否被接收只與getName,getAge等方法中get後的參數有關。即實際上struts2是通過get方法接收參數的,而不是通過全局變量接收。10.<s:property>取出的是value stack中的值property value,而值棧value stack中存儲的是鍵值對。
11.類似於
Map request = (Map)ActionContext.getContext.get("request");
Map session = ActionContext.getContext.getSession;//獲取session
Map application = ActionContext.getContext.getApplication;//獲取application
//getContext是獲取Action執行的上下文
//context翻譯成中文就是“上下文”,表示當前程序執行時周圍的環境,比如在教室學習時,context就是指電腦、空調、電燈等的情況。
//struts會把這些周圍環境封裝到context內,可以把context看作容器
//servletContext表示servlet運行的環境,包括servlet的各種配置
//ActionContext包括getApplication,getResponse等
是一種單例模式,與struts2多例模式相悖,雖然這也能取得參數的值,但不推薦。
12.map類型的request,session,application真實類型爲HttpServerRequest,HttpSession,ServletContext
13.value stack(值棧)中的值可以直接獲取
stack context中內容可以讓s標籤利用"# + 作用域"獲取,這是ognl表達式。如
<s:property value="#request.r1">
這等同於
<%=request.getAttribute("r1")%>
類似的還有
<s:property value="#session.s1">||<%=session.getAttribute("s1")%>
<s:property value="#application.a1">||<%=application.getAttribute("a1")%>
14.ActionContext不是單例,而是ThreadLocal對象。存的是鍵值對,線程名和對應的存儲在該線程的值。
15.IOC(inverse of control)指的是控制反轉,用來訪問web元素,如request,session,application等。這種方法最常用。
並且用ioc絕大部分是用來獲取session的值,不需獲取request和application。例如:
private Map<String, Object> request;//不需要自己初始化,struts2容器會替我們初始化
private Map<String, Object> session;
private Map<String, Object> application;
public String execute() {
request.put("r1", "r1");
//實際上我們根本就不用去獲取request,它在value stack中會得到,而value stack是放在request裏邊
//這個方法只是用來演示ioc可以訪問request
session.put("s1", "s1");
application.put("a1", "a1");//application也是幾乎不用,所以綜合下來ioc大部分是取session的值
return SUCCESS;
}
public void setRequest(Map<String, Object> request) {
this.request = request;
}
//幾乎不用
public void setSession(Map<String, Object> session) {
this.session = session;
}
//這個需要,注意session爲map類型
public void setApplication(Map<String, Object> application) {
this.application = application;
}
//幾乎不用
16.result的type包括redirect和dispatcher,都只能跳轉到頁面,而不能是action,跳轉action用chain和redirectAction