首先說明,struts必須拼寫對,不要忘記第2個t
1.1.新建第一個項目
①先在新建web project中的web.xml添加配置項。這個可以在struts2-blank.war文件夾裏找到
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
②再建個struts.xml(一定要拼寫正確,並且該名稱是固定的,不能寫成struts2.xml),寫入屬性.可放在src文件夾內
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="firstAction" class="com.bjsxt.action.FirstAction"></action>
</package>
</struts>
注意action name相當於以前的<url-pattern>,name是什麼,就在瀏覽器輸入相應的值即可。
③新建action文件,可以簡單地寫爲
public class FirstAction {
public String execute(){
System.out.println("跑了!");
return null;
}
}
可以發現struts與servlet相比有幾點不同--1.不用繼承HttpServlet
--2.少了doGet()和doPost()方法
④在瀏覽器輸入http://localhost:8080/Struts2/firstAcion,即可看到輸出結果。注意不要寫“.java”後綴。
PS:struts2裏默認的方法是execute(),上邊若改爲其它名稱,如add(),則要用動態調用,加!。即瀏覽器地址變爲
http://localhost:8080/Struts2/firstAcion!add
2.struts2的action是多例模式,每一次請求(即一個url就是一個請求)都實例化一個action對象,彼此之間完全獨立,多例是線程安全的。而servlet是單例,只會實例化一個對象。
3.一般自己寫的方法,不包括繼承,都要拋出異常來使代碼更完善。如
public String add() throws Exception(){}
4.可通過動態方法調用,即在url內添加“actionname!methodname”來直接使用相應的方法。如在地址欄輸入:
http://localhost:8080/Struts2_001/firstAction!test2
5.屬性驅動(property-driven)和模型驅動(model-driven)這兩個主要是用來進行表單數據的封裝,以便於在action直接調用。以後再也不需要用getParameter()方法來獲取屬性,簡化了不少。
①model-driven(模型驅動)使用時必須new一個實例才能獲取到值,即需要添加類似的
private User user = new User();
而property-driven(屬性驅動)則不需要這一步。
②使用ModelDriven 模型實例對象雖然在valueStack中, 但是我們只能通過實例對象的屬性直接獲取對應的value。
即類似${name}這樣的,而不是${user.name}。後邊的這種取不到值。
property-driven,必須添加相應的get和set方法。而model-driven,不需添加。因爲不加set/get方法,value stack中也會傳入name,id,password等值,但沒有user對象,此時用${name}獲取屬性即可,不能用${user.name}獲取。添加get/set方法後,會增加user對象,但也有name,id等屬性,重複了。所以添加get/set方法後,仍然只能用${name}等取得屬性。不管加沒加get/set方法,都只能直接通過屬性獲取值,即只能用${name}這樣的,不能用${user.name}這樣的。
綜上所述:
Property Driven:利用屬性驅動利用對象把參數注入到當前的Action類(必須使用getters setters方法),一般要繼承ActionSupport
Model Driven:利用模型驅動把參數注入到當前的Action類 必須實現ModelDriven接口,實現接口時必須重寫getModel方法, 並且實例化其注入對象(專門應用於數據傳輸層的VO對象),即有類似於下邊這樣的:
private UserVO userVO = new UserVO();
再如:
public class ModelAction implements ModelDriven<UserVO> {
private UserVO userVO = new UserVO();
public UserVO getModel(){//實現接口時必須重寫getModel方法,並且ModelDriven<UserVO>中的UserVO和返回值類型UserVO對應return userVO;
}
}
③從jsp頁面往action中傳值時:在property-driven中,jsp頁面只能爲
id<input name="user.id">
姓名<input name = "user.name">
不能爲
id<input name="id">
姓名<input name = "name">
因爲property-driven通過屬性注入的,前邊需要加對象。
而在model-driven中,既可以是
id<input name="user.id"> 姓名<input name = "user.name">
也可以用
id<input name="id">
姓名<input name = "name">
不需要添加模型名稱,直接寫屬性即可。
獲取值時還是隻能用${id},${name}等來直接獲取,而不能用${user.id},jsp頁面上可以這樣寫${user.name},取值時不能這樣取${user.name}
④若想獲取從瀏覽器地址欄的值,還是拿user舉例。則模型驅動中用${name}即可。地址欄爲:
http://localhost:8080/Struts_001_helloworld/model!add?username=y
屬性驅動中用${user.name},否則無法顯示。地址欄爲:
http://localhost:8080/Struts_001_helloworld/property!add?user.username=y
同時注意傳遞參數的寫法,model中沒有屬性,property中必須寫屬性user才能獲取到。
6.指定web的默認字符集可使用
<constant name="struts.i18n.encoding" value="utf-8">
這等價於
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
指定開發模式則是:
<constant name="struts.devMode" value="true">
添加該段代碼後,在struts.xml修改數據後,就可以不再重啓服務器。這句話只是針對struts.xml,而在action添加或刪除方法後還是需要重啓服務器。
7.namespace與路徑有關。默認的爲“/”,可以自己修改,但相應地在地址欄內也要發生變化。如
namespace="/";
url地址爲
http://localhost:8080/Struts2/firstAction
當變爲:
namespace="/admin"
url地址爲:
http://localhost:8080/Struts2/admin/firstAction
8.web.xml中的filter默認攔截的是/*,爲了減少衝突,可改爲*.action,Action默認的後綴都是.action。然後在瀏覽器輸入時,在最後添加.action
9.struts.xml中的action的配置信息是將url,action類,展示頁面三者聯繫起來。
url跟action的name相關聯
class指定了action類
result將action中返回的字符串(通過result的name屬性匹配,name如果不指定值,默認是"success")跟展示頁面(通過path或者result元素的文本值指定)映射起來。如
<action name="firstAction" class="com.bjsxt.action.FirstAction">
<result name="success">/success.jsp</result>
<!--可以有多個rsult元素-->
</action>
<result>元素告訴我們調用完action後下一步做什麼,映射到什麼地方。
<result>還有type屬性。默認的爲dispatcher(用來轉向jsp頁面),常用的有redirect(重定向到url),redirectAction(重定向到一個action)
<result name="getList" type="redirect">userAction!getList.action</result>
10.通過struts2實現增刪改查時,一般有三個頁面,save.jsp(保存用戶),view.jsp(展示結果),update.jsp(修改用戶信息)。保存(save)用戶後,需要重定向到展示(view)頁面來顯示增加用戶後的效果。而view()方法則把結果重定向到jsp頁面使結果顯示。
11.struts2的action爲多例模式,所以在預修改preUpdate()中的this.user與save()方法中的this.user不是同一個。因爲每一次請求都會new一個實例。同理,各個方法的this.user都不一樣。
12.怎麼通過在地址欄向action傳值?如
public class FirstAction {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public FirstAction() {
System.out.println("你好");
}
public String hh() throws Exception{
System.out.println(this.message);
if("aaa".equals(message)){
return "success";
}else{
return "failure";
}
}
}
需要在地址欄輸入:
http://localhost:8080/Struts_001_helloworld/firstAction!hh?message=aa
此時會return 到failure,只有?後邊的message=aaa才能return 到success.注意傳值必須寫出哪個屬性等於什麼值,必須有等號"=",否則值傳過去了,但無法識別。
若hh()改爲execute,則地址欄中無需加"!",因爲execute是struts2默認會執行的.即
http://localhost:8080/Struts_001_helloworld/firstAction?message=aa
即可。
13.
String a = null;
String c = "sss";
a.equals(c);//會報空指針異常
c.equals(a);//只是不相等,不會報任何異常。
這些和前邊提到的
String name = request.getParameter("name");
if("admin".equals(name)){
//方法內容
}
做了個深化理解。防止name爲null時出現空指針異常。因此不推薦下邊這種寫法,不嚴謹。String name = request.getParameter("name");
if(name.equals("admin")){
//方法內容
}