1.2 知識點 1.2.1 Struts2的Servlet的API的訪問 1.2.1.1 方式一 : 通過ActionContext實現 頁面: <h1>Servlet的API的訪問方式一:解耦合的方式</h1> <form action="${ pageContext.request.contex... ...
1.2 知識點 1.2.1 Struts2的Servlet的API的訪問 1.2.1.1 方式一 : 通過ActionContext實現 頁面: <h1>Servlet的API的訪問方式一:解耦合的方式</h1> <form action="${ pageContext.request.contextPath }/requestDemo1.action" method="post"> 姓名:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"><br/> <input type="submit" value="提交"> </form> 編寫Action /** * Servlet的API的訪問方式一:解耦合的方式 * * 只能用於接收參數 和 操作域中的數據 * @author jt */ public class RequestDemo1Action extends ActionSupport{ @Override public String execute() throws Exception { // 接收數據: /** * 在ActionContext中提供了一些方法:操作域對象的數據 * * Map<String,Object> getParameters(); * * Map<String,Object> getSession(); * * Map<String,Object> getApplication(); */ // 接收參數: ActionContext actionContext = ActionContext.getContext(); Map<String,Object> map = actionContext.getParameters(); for (String key : map.keySet()) { String[] arrs = (String[]) map.get(key); System.out.println(key+" "+Arrays.toString(arrs)); } // 向request域中存值: actionContext.put("reqName", "req如花"); // 向session域中存值: actionContext.getSession().put("sessName", "sess鳳姐"); // 向application域中存值: actionContext.getApplication().put("appName","app石榴"); return SUCCESS; } } 1.2.1.2 方式二: 實現特定介面的方式實現: 在struts中提供了一些介面 : ServletRequestAware,ServletResponseAware,ServletContextAware; 頁面: <h1>Servlet的API的訪問方式二:實現特定介面的方式</h1> <form action="${ pageContext.request.contextPath }/requestDemo2.action" method="post"> 姓名:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"><br/> <input type="submit" value="提交"> </form> 編寫Action: /** * Servlet的API的訪問方式二: * @author jt * */ public class RequestDemo2Action extends ActionSupport implements ServletRequestAware,ServletContextAware{ private HttpServletRequest request; private ServletContext application; @Override public String execute() throws Exception { // 接收數據:使用request對象。 Map<String, String[]> parameterMap = request.getParameterMap(); for (String key : parameterMap.keySet()) { String[] arrs = parameterMap.get(key); System.out.println(key+" "+Arrays.toString(arrs)); } // 向域中保存數據; // 向request域中保存數據 request.setAttribute("reqName", "r郝三"); // 向session域中保存數據 request.getSession().setAttribute("sessName", "s李四"); // 向application域中保存數據 application.setAttribute("appName", "a王五"); return NONE; } @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } @Override public void setServletContext(ServletContext application) { this.application = application; } } 1.2.1.3方式 : 通過ServletActionContext對象的靜態方法實現 : 頁面: <h1>Servlet的API的訪問方式三:通過ServletActionContext對象靜態方法獲取</h1> <form action="${ pageContext.request.contextPath }/requestDemo3.action" method="post"> 姓名:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"><br/> <input type="submit" value="提交"> </form> 編寫Action: /** * Servlet的API訪問方式三:通過ServletActionContext的靜態方法訪問 * @author jt * */ public class RequestDemo3Action extends ActionSupport { public String execute() throws Exception { //接收參數: /* ServletActionContext 在struts2的API中的 : HttpServletRequest getRequest(); HttpServletResponse getResponse(); ServletContext getServletContext(); */ HttpServletRequest request = ServletActionContext.getRequest(); Map<String,String[]> parameterMap = request.getParameterMap(); for(String key : parameterMap.get()) { String[] value = parameterMap.get(Key); System.out.println(key + " " + Arrays.toString(value)); } //向域中存值 : request.setAttribute("reqName" , "用request向域中存數據"); request.getSession.setAttribute("session","向session域中存數據"); ServletActionContext.getServletContext().setAttribute("ServletContext","向ServletContext域中存儲數據"); return super.execute(); } } 1.2.2.1 :結果頁面的分類 : 全局結果頁面 : 針對一個包下所有的action都生效的一個頁面. <!--全局結果頁面--> <global-results> <result>/jsp/1.jsp</result> </global-results> 局部結果頁面 : 針對某一個action生效的一個頁面 : <action name="requestDemo1" class="com.baidu.struts2.demo1.ActionDemo1"> <result>/jsp/1.jsp</result> </action> 1.2.2.2 配置結果頁面 : <result>標簽配置: name : 邏輯視圖的名稱.預設值是success. type : dispatcher : 預設值,轉發.(轉發到jsp的頁面) redirect : 重定向.(重定向到JSP的頁面),被跳轉的頁面中丟失傳遞的信息. chain : 轉發到另一個Action. redirectAction : 重定向到另一個Action.跳轉的頁面中丟失傳遞的信息 stream : 文件的下載 1.2.2.3 Struts2的多例性 : 原來的Servlet是單例存在,多次請求,請求都是同一個Servlet的實例.Struts2中Action是多實例的.有異常請求就會有一個Action的實例. 現在可以在Action中定義成員屬性了. 大部分我們會優先使用模型驅動的方式,因為Struts2內部有很多結果是圍繞模型驅動設計的。但如果頁面向多個對象中封裝,那麼就需要使用屬性驅動的方式二了。 這些都是像某個對象中封裝數據, 1.2.3 Struts2的數據封裝 : 1.2.3.1 Struts2中的數據封裝-屬性驅動 : 提供對應屬性的set方法的方式 : 頁面: <h3>數據封裝的方式一:提供屬性的set方法的方式</h3> <form action="${ pageContext.request.contextPath }/employee1Action.action" method="post"> 姓名:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"/><br/> 性別:<input type="text" name="sex"/><br/> 工資:<input type="text" name="salary"/><br/> <input type="submit" value="提交"/> </form> 編寫Action: /** * 數據封裝的方式一:提供set方法的方式 * @author jt * */ public class Employee1Action extends ActionSupport{ private String name; private Integer age; private String sex; private Double salary; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setSex(String sex) { this.sex = sex; } public void setSalary(Double salary) { this.salary = salary; } @Override public String execute() throws Exception { System.out.println("員工姓名:"+name); System.out.println("員工年齡:"+age); System.out.println("員工性別:"+sex); System.out.println("員工工資:"+salary); // 手動封裝數據: Employee employee = new Employee(); employee.setName(name); employee.setAge(age); employee.setSex(sex); employee.setSalary(salary); return NONE; } } 這種方式不是特別常用,因為需要手動封裝數據,而且如果屬性很多,提供很多的set方法,導致Action類易讀性變差 頁面中提供表達式的方式: 頁面: <h3>數據封裝的方式二:頁面提供OGNL表達式的寫法</h3> <form action="${ pageContext.request.contextPath }/employee2Action.action" method="post"> 姓名:<input type="text" name="employee.name"/><br/> 年齡:<input type="text" name="employee.age"/><br/> 性別:<input type="text" name="employee.sex"/><br/> 工資:<input type="text" name="employee.salary"/><br/> <input type="submit" value="提交"/> </form> 編寫Action: /** * 數據封裝的方式二:頁面提供表達式的方式 * @author jt * */ public class Employee2Action extends ActionSupport{ // 提供成員的屬性employee,必須提供屬性的get和set方法 private Employee employee; public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } @Override public String execute() throws Exception { System.out.println(employee); return NONE; } } 1.2.3.2 Struts2 中的數據封裝-模型驅動 : 採用模型驅動完成數據封裝(推薦) 頁面: <h3>數據封裝的方式三:採用模型驅動的方式</h3> <form action="${ pageContext.request.contextPath }/employee3Action.action" method="post"> 姓名:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"/><br/> 性別:<input type="text" name="sex"/><br/> 工資:<input type="text" name="salary"/><br/> <input type="submit" value="提交"/> </form> 編寫Action: /** * 數據封裝的方式三:採用模型驅動的方式 * @author jt * */ public class Employee3Action extends ActionSupport implements ModelDriven<Employee>{ // 模型驅動使用的對象:必須手動構建對象的實例。 private Employee employee = new Employee(); @Override public Employee getModel() { return employee; } @Override public String execute() throws Exception { System.out.println(employee); return NONE; } } ***** 模型驅動只能向一個實體中封裝數據,如果需要向多個實體封裝數據優先採用第二種方式。 1.2.4 Struts2 的複雜數據的封裝 : 1.2.4.1 封裝到List集合 : 頁面: <form action="${ pageContext.request.contextPath }/product1Action.action" method="post"> 商品名稱:<input type="text" name="list[0].name"/><br/> 商品價格:<input type="text" name="list[0].price"/><br/> 商品名稱:<input type="text" name="list[1].name"/><br/> 商品價格:<input type="text" name="list[1].price"/><br/> 商品名稱:<input type="text" name="list[2].name"/><br/> 商品價格:<input type="text" name="list[2].price"/><br/> <input type="submit" value="批量導入"/> </form> Action: /** * 封裝複雜的數據到List集合中。 * @author jt * */ public class Product1Action extends ActionSupport{ private List<Product> list; public List<Product> getList() { return list; } public void setList(List<Product> list) { this.list = list; } @Override public String execute() throws Exception { for (Product product : list) { System.out.println(product); } return NONE; } } 1.2.4.2 封裝到Map集合 頁面: <h1>批量插入商品:封裝到Map集合</h1> <form action="${ pageContext.request.contextPath }/product2Action.action" method="post"> 商品名稱:<input type="text" name="map['one'].name"/><br/> 商品價格:<input type="text" name="map['one'].price"/><br/> 商品名稱:<input type="text" name="map['two'].name"/><br/> 商品價格:<input type="text" name="map['two'].price"/><br/> 商品名稱:<input type="text" name="map['three'].name"/><br/> 商品價格:<input type="text" name="map['three'].price"/><br/> <input type="submit" value="批量導入"/> </form> Action: /** * 複雜類型數據封裝:封裝到Map集合 * @author jt * */ public class Product2Action extends ActionSupport { private Map<String,Product> map; public Map<String, Product> getMap() { return map; } public void setMap(Map<String, Product> map) { this.map = map; } @Override public String execute() throws Exception { for (String key : map.keySet()) { Product product = map.get(key); System.out.println(key+" "+product); } return NONE; } } 隨堂筆記 : 1 strtus2對servlet API的訪問 1 使用ServletActionContext類的靜態方法(重要) 2 使用ActionContext對象的方法(理解)往域中存儲數據,到頁面展示(ps:這個對象獲取不到域對象,只能操作域中的數據) 靜態方法getContext()獲取ActionContext對象 特點: 只能接受頁面的數據,以及對域中數據的進行操作 獲取不response對象做不了響應,也獲取不到域對象 使用ActionContext對象的方法(理解) // getContext() --獲取ActionContext對象 // Map<String,Object> ----- getParameters() 獲取頁面的所有數據 // Map<String,Object> ------getSession() 獲取session域中的數據 // Map<String,Object> -------getApplication() 獲取servletContext域中的數據 3 實現特定的介面來獲取的方法(瞭解) 證明Action是單實例還是多實例? servlet是單實例 成員屬性有線程危機 Action是多實例 成員屬性沒有線程危機 2 結果頁面的邏輯視圖配置 分類: 全局配置 針對一個包下所有的action都生效的一個頁面 局部配置 針對某一個action生效的一個頁面 註意:如果全局配置和局部配置都配置了,局部配置的優先順序大於全局配置 result標簽: 對返回的邏輯視圖進行匹配 name: 邏輯視圖的名稱。預設值是success。 type: dispatcher 預設 請求轉發(用於轉發到jsp頁面) redirect 重定向(用於重定向到jsp頁面) chain 請求轉發(用於轉發到action) redirectAction 重定向(用於重定向到action) stream 用於下載的(CRM3天案例) 3 struts2對頁面數據的封裝(模型驅動,屬性驅動) 1 屬性驅動---set屬性方式(例如:分頁玩法) (重點) 條件: 1 需要在action的成員位置提供屬性,並且要有set()方法 2 屬性驅動---頁面表達式的方式 (理解) 條件: 1 需要在action的成員位置上申明javabean對象,且提供get/set方法 例如: private User user; get()/set() 2 在頁面上的參數name屬性需要: name=javabean對象.屬性 例如: user.username; uiser.age; 3 模型驅動(單一的對象) (掌握) 條件: 1 讓action實現一個介面: ModelDriven 2 需要在action的成員位置上申明javabean對象,並且這個對象得實例化 private User user=new User; 3 需要 ModelDriven 這個介面中的getModel()方法 4 需要在getModel()方法裡面將我們的javabean對象以返回值的形式返回回去 主頁:頁面還是正常的寫法 4 批量方式(針對的是多個對象數據的封裝) 條件: 需要在action中提供集合,且提供get()/set()方法 list封裝: 在action中集合名稱: ll 在頁面需要: ll[0].username ll[0].age ll[1].usrname ll[1].age map封裝: 在action中集合名稱: mm 在頁面需要: mm[鍵名].屬性 總結: 1 struts2怎麼樣獲取到servlet的API(request,response,session,ServletContext,以及接受頁面的數據) 1 通過ServletActionContext類的靜態方法 2 通過ActionContext對象的方法(理解) getActionContext()--對象的獲取 註意:只能接受操作頁面參數,以及操作域中的數據 不能獲取到域對象,也不能做響應(response對象也獲取不到) 3 通過特定的介面來實現 ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware 2 結果邏輯視圖的配置 全局配置 針對的是一個包下的所有action 局部配置 針對的是指定的action 2個都存在的情況下優先順序:局部>全局 result標簽: name: 邏輯視圖的名稱。預設值是success。 type: dispatcher :預設值,請求轉發。(請求轉發到JSP的頁面) redirect :重定向。(重定向到JSP的頁面) chain :轉發到另一個Action。 redirectAction:重定向到另一個Action。 stream :文件的下載。 3 struts2對頁面數據封裝的方式: 4種 ps:action多實例的,每訪問一次就創建一個action對象,所以它成員位置的屬性不存線上程危機 1 屬性驅動---set方式 條件: action提供相應的成員屬性,必須得有set方法 2 屬性驅動---頁面表達式的方式 條件: 1 需要在action的成員位置上申明javabean對象,且提供get/set方法 2 在頁面上的參數name屬性需要: name=javabean對象.屬性 例如: user.username; uiser.age; 3 模型驅動 條件: 1 讓action實現一個介面: ModelDriven 2 需要在action的成員位置上申明javabean對象,並且這個對象得實例化 private User user=new User; 3 需要 ModelDriven 這個介面中的getModel()方法 4 需要在getModel()方法裡面將我們的javabean對象以返回值的形式返回回去 主頁:頁面還是正常的寫法 4 批量封裝 條件: 提供集合且提供set/get方法 list: 在action中: ll 在頁面: ll[索引].屬性 map: 在action中: mm 在頁面: mm['鍵名'].屬性