1.訪問Servlet APIhtml
首先咱們瞭解什麼是Servlet API 前端
httpRequest、httpResponse、servletContext
3個api對應jsp面向對象:request、response、application
servlet中能夠直接調用servlet apijava
struts2 Action中execute沒有任何參數,也就是不存在servlet api web
Struts2框架底層是基本Servlet的,因此咱們確定要去訪問Servlet API,並且開發Web應用不去訪問Servlet API也是不可能的,apache
因此咱們Struts2框架提供了咱們去訪問Servlet API的方法; 後端
struts2 提供了3種方式訪問servlet api: api
①:使用ServletActionContext訪問Servlet API; ActionContext類 瀏覽器
②:使用ActionContext訪問ServletAPI; ServletActionCotext類mvc
③:使用一些接口 如 ServletRequestAwa...; 實現***Aware接口app
2.Action搜索順序
咱們來看一個路徑:
咱們這裏新建一個student.action 沒有命名空間那麼咱們訪問的路徑就是
http://localhost:8080/ProjectName(項目的名字)/student.action
那麼咱們改爲下面的路徑
http://localhost:8080/ProjectName(項目的名字)/path1/path2/path3/student.action
在瀏覽器中訪問也能訪問到正確的頁面
所以咱們能夠看出訪問的順序是從文件的上級 也就是最後一級包開始找
http://localhost:8080/ProjectName(項目的名字)/path1/path2/path3/student.action
http://localhost:8080/ProjectName(項目的名字)/path1/path2/student.action
http://localhost:8080/ProjectName(項目的名字)/path1/student.action
http://localhost:8080/ProjectName(項目的名字)/student.action
從path3 一直到path1都找不到 最後在根目錄下找到 若是找不到就會報錯了
這就是action的搜索順序!
3.動態方法調用
在.net MVC中 咱們在Controller中建立一個一個方法 只要在頁面中指定相應的mvc路徑 咱們視圖的一個url就能請求獲得
在struts中 咱們則須要手工進行配置 指定頁面和後臺方法的匹配
這裏的動態方法調用就是爲了解決一個Action對應多個請求得處理。以避免Action太多(像指定method屬性的配置方式 )
動態調用有三種方式 這裏指定method屬性和感嘆號方式(不推薦使用)再也不說明 咱們來講下經常使用的通配符方式:
首先在struts.xml配置咱們的參數
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" > <struts> <package name="default" namespace="/" extends="struts-default"> <action name="HelloWorld2" class="com.HelloWorldAction"> <result>/result.jsp</result> </action> <!-- name 表明咱們的action名也就是url裏面的名字 class是指定咱們的後臺類文件 method {1} 與name中的*對應 --> <action name="helloworld_*" method="{1}" class="com.HelloWorldAction"> <result >/result.jsp</result> <result name="add" >/add.jsp</result> <result name="update" >/update.jsp</result> </action> </package> </struts>
這裏咱們須要建立三個jsp文件 默認路徑的result.jsp 還有add方法的add.jsp update方法的update.jsp
頁面裏面咱們都用一句話簡單區分 這樣 啓動Debug as Server 而後在瀏覽器中訪問就能夠對應到相應的路徑了
這裏struts.xml文件result標籤值都改爲{1}.jsp 同樣的道理 這裏能夠隨意加參數進行配置
4.指定多個配置文件
若是項目比較大 則須要比較多的配置 咱們在入門(二)文件中看到註釋能夠用include來包含多個配置文件
<include file="***.xml"> </include> <constant name="struts.i18n.encoding" value="UTF-8"> </constant>
ps: 1.被include的標籤必定要符合struts的dtd規範。也就是說被include的xml文件的內部格式要符合struts的xml文件規範(跟struts.xml一摸同樣)。 2.xml文件的編碼格式要相同,若是是utf-8,那麼都是utf-8。
5.默認Action
默認action是爲了改善用戶體驗,當用戶輸入的URL找不到對應的action,就會使用默認Action
【找不到默認action的緣由和解決方法】
<default-action-ref name="index"></default-action-ref> <action name="index"> <result>/error.jsp</result> </action> <br> <action name="log_*" method="{1}" class="com.wayne.action.LoginAction"> <result name="login">/login.jsp</result> <result name="logout">/logout.jsp</result> </action>
將上面代碼放到package標籤中 這裏定義了一個index的默認標籤
通配符會覆蓋掉默認action,因此不能有【*_*】這樣子的action,要改爲【log_*_*】這類型的命名,
不然,【*_*】裏面的第一個*就包括了全部的字符,直接進入了這個action進行處理,沒法進入默認的action了。
6.Struts 後綴
三種方式:
1.struts.properties中:struts.action.extension=action,do,struts2
2.struts.xml中增長常量constant:
<constant name="struts.action.extension" value="action,do,struts2"></constant>
3.在web.xml過濾器中配置intt-param參數:
<init-param>
<param-name>struts.action.extension</param-name>
<param-value>do,action,strtus2</param-value>
</init-param>
7.接收參數
以前咱們說到struts項目中 咱們寫了前臺jsp頁面 寫了後臺action頁面 那麼要想二者進行關聯就須要在配置文件中配置關聯關係(真是麻煩。)
下面咱們用項目示例來講明下接收參數問題:
首先咱們創建一個login.jsp頁面
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <form action="LoginAction.action" method="post"> 11 用戶名:<input type="text" name="username" /> 12 密碼:<input type="password" name="password" /> 13 <input type="submit" value="提交"/> 14 </form> 15 </body> 16 </html>
而後咱們建立一個後臺Class LoginAction.java
package com; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { public String login(){ return SUCCESS; } }
而後咱們在struts.xml配置文件中配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" > <struts> <package name="default" namespace="/" extends="struts-default"> <action name="HelloWorld2" class="com.HelloWorldAction"> <result>/result.jsp</result> </action> <action name="LoginAction" method="login" class="com.LoginAction"> <result >/success.jsp</result> </action> </package> </struts>
這裏添加了一個過濾器 指定了訪問LoginAction的login方法
而後咱們如何經過action的屬性獲取form提交的值
第一種方式:直接在action類中實現--使用Action的屬性接收參數(不利於面向對象)
1 package com; 2 3 import com.opensymphony.xwork2.ActionSupport; 4 5 public class LoginAction extends ActionSupport { 6 //建立兩個屬性的get set方法 7 private String username; 8 private String password; 9 10 public String login(){ 11 System.out.println(username); 12 return SUCCESS; 13 } 14 15 public String getUsername() { 16 return username; 17 } 18 19 public void setUsername(String username) { 20 this.username = username; 21 } 22 23 public String getPassword() { 24 return password; 25 } 26 27 public void setPassword(String password) { 28 this.password = password; 29 } 30 31 32 }
而後訪問:http://localhost:8080/StrutsDemo/login.jsp 輸入用戶名密碼 提交 會發現控制檯中打印輸出了 用戶名
第二種方式:使用DomainModel接收參數
這裏要把第一種屬性聲明的方式 單獨放到一個類中去
創建一個User類
1 package com.po; 2 3 public class User { 4 //建立兩個屬性的get set方法 5 private String username; 6 private String password; 7 8 public String getUsername() { 9 return username; 10 } 11 12 public void setUsername(String username) { 13 this.username = username; 14 } 15 16 public String getPassword() { 17 return password; 18 } 19 20 public void setPassword(String password) { 21 this.password = password; 22 } 23 }
而後action中去掉屬性相關 聲明一個user類
package com; import com.opensymphony.xwork2.ActionSupport; import com.po.User; public class LoginAction extends ActionSupport { public User getUser() { return user; } public void setUser(User user) { this.user = user; } private User user; public String login(){ System.out.println(user.getUsername()); return SUCCESS; } }
login.jsp頁面中須要更改name的值
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form action="LoginAction.action" method="post"> 用戶名:<input type="text" name="user.username" /> 密碼:<input type="password" name="user.password" /> <input type="submit" value="提交"/> </form> </body> </html>
而後再次啓動下 訪問:http://localhost:8080/StrutsDemo/login.jsp 輸入用戶名密碼 提交 會發現控制檯中一樣打印輸出了 用戶名
第三種方式:使用ModelDriven接收參數(推薦方式)
這裏咱們須要實現ModelDriven接口
package com; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.po.User; public class LoginAction extends ActionSupport implements ModelDriven<User>{ private User user=new User(); //這裏須要實例化 去掉了 get set方法 實現了ModelDriven的方法 public String login(){ System.out.println(user.getUsername()); return SUCCESS; } @Override public User getModel() { // TODO Auto-generated method stub return user; } }
這裏咱們也再也不須要指定jsp中的name 對象 去掉user.
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form action="LoginAction.action" method="post"> 用戶名:<input type="text" name="username" /> 密碼:<input type="password" name="password" /> <input type="submit" value="提交"/> </form> </body> </html>
若是咱們傳遞一個List方式同樣的道理 在jsp中 咱們聲明
書籍1:<input type="text" name="BookList[0]"/>
書籍2:<input type="text" name="BookList[1]"/>
後臺User類中咱們建立List BookList對象
private List<String> BookList; public List<String> getBookList() { return BookList; } public void setBookList(List<String> bookList) { BookList = bookList; }
這裏咱們就簡單介紹這幾種方式 最後作一個總結:
1 接收參數 2 1,使用Action的屬性接受參數,在Action中定義須要接受的屬性,並寫它的set/get方法。 3 2,使用DomainModel接受參數,建立實體類定義須要接受的屬性,並set/get方法,在Action中建立實體類名屬性。並在界面進行指定。 4 3,使用ModelDriver接受參數,在Action中實現ModelDriver<實體類名>接口,並實現方法返回當前須要轉換的對象,刪除set/get方法,並對 對象 進行實例化,並取消指定。 5 4,request 6 5,獲取List集合中的參數。獲取多個參數。 7 8 第一種接收參數的方法:直接在action類中建立相應的屬性和getter和setter,和前端的name名字相同。eg:前端的username,在action類中就要創建一個private String username; Struts會自動映射爲這個屬性賦值 9 10 第二種接受參數的方法:使用DomainModel,將username 和password兩個屬性封裝爲一個類User(必須是標準的JavaBean),在action中聲明這個屬性:private User user; 同時爲user設置getter和setter;在前端中的name須要設置爲user.name和user.password,才能映射成功 11 12 第三種接收參數的方法:使用ModelDriven<T>接口,這個action必須實現這個接口的public T getModel()方法。此時聲明的屬性必須實例化,eg: private User user = new User(); 同時不須要getter和setter。前端的name也只須要寫username和password就能夠,不須要再加域了。這種方法時最推薦的方法,由於能夠減小先後端的耦合
8.處理結果類型
咱們來看一下struts.xml中過濾器的一句話
<result name="success">/result.jsp</result> 這句話等同於<result >/result.jsp</result> 說明name的默認值就是success
【Structs2處理流程】
用戶請求Structs框架控制器(Action)Structs框架視圖資源
返回String,提供代碼複用性,有利於框架分離。
【Action中五種內置屬性(com.opensymphony.xwork2.Action)】