一 Servlet的API的訪問 1 完全解耦和的方式 完全看不到request、response、session。 (1)創建jsp界面 (2)編寫action (3)struts_xml 運行效果圖 調用put方法相當於往request域中存數據註意:這種方式只能獲得像 request sess ...
一 Servlet的API的訪問
1 完全解耦和的方式
完全看不到request、response、session。
(1)創建jsp界面
<h1>Struts2的servlet的API的訪問</h1> <h3>完全解耦和的方式,方式一</h3> <form method="post" action="${pageContext.request.contextPath}/requestAction.action" > 姓名:<input type="text" name="name"> 密碼:<input type="password" name="password"> <input type="submit" value="提交"> </form>
(2)編寫action
/** * 訪問servlet API的完全解耦和的方式一 */ public class requestAction extends ActionSupport { public requestAction() { System.out.println("Action對象被創建了"); } @Override public String execute() throws Exception { ActionContext actionContext=ActionContext.getContext(); Map<String, Object> map = actionContext.getParameters(); for (String key:map.keySet() ) { String[] values = (String[]) map.get(key); System.out.println(key +" "+Arrays.toString(values)); } //存值 actionContext.put("attName","attValue"); actionContext.getSession().put("sessName","sessValue"); actionContext.getApplication().put("appName","appValue"); return SUCCESS; } }
(3)struts_xml
<action name="requestAction" class="com.itheima.demo1.requestAction"> <result name="success" type="redirect">/demo1/demo2.jsp</result> </action>
運行效果圖
調用put方法相當於往request域中存數據
註意:這種方式只能獲得像 request session application集合中的值,不能操作對象的本身的方法
2 使用Servlet的API的原生方式(這種必須要會)
編寫jsp
<h3>使用原生的方式,方式二</h3> <form method="post" action="${pageContext.request.contextPath}/requestAction2.action" > 姓名:<input type="text" name="name"> 密碼:<input type="password" name="password"> <input type="submit" value="提交"> </form>
編寫action
public class requestAction2 extends ActionSupport { @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); Map<String, String[]> map = request.getParameterMap(); for (String key:map.keySet() ) { String[] values = map.get(key); System.out.println(key+" "+Arrays.toString(values)); } request.setAttribute("attName","attValue"); request.getSession().setAttribute("sessName","sessValue11"); ServletActionContext.getServletContext().setAttribute("appName","appValue11"); return SUCCESS; } }
運行效果圖
這種方式既可以操作域中的數據,也可以操作對象的方法
3 介面註入的方式(這種方式很少用,瞭解)
action類
public class requestAction3 extends ActionSupport implements ServletRequestAware,ServletContextAware { private HttpServletRequest request; private ServletContext context;//可以通過快捷鍵來生成 public requestAction3() { System.out.println("Action被創建了"); } @Override public String execute() throws Exception { Map<String, String[]> map = request.getParameterMap(); for (String key:map.keySet() ) { String[] values = map.get(key); System.out.println(key+""+Arrays.toString(values)); } request.setAttribute("attName","attValues111"); request.getSession().setAttribute("sessName","sessValues2"); context.setAttribute("appName","appValues3");//存到application中 return super.execute() ;//這裡是返回sucess,可以查看源代碼 } @Override public void setServletRequest(HttpServletRequest request) { this.request=request; } @Override public void setServletContext(ServletContext servletContext) { this.context=servletContext; } }
Servlet是單例的,只會創建一個對象。而action是多例的,每一次請求都會創建一個對象
action是線程安全的,action是多例的,在類中定義成員變數不會有線程安全的問題
二 配置結果頁面
1 全局結果頁面
全局結果頁面,指的是這個包底下的都有效
<global-results> <result name="success">/demo1/demo2.jsp</result>
</global-results>
2 局部結果頁面
局部結果頁面,針對當前的action有效
<action name="requestAction" class="com.itheima.demo1.requestAction"> <result name="success" type="redirect">/demo1/demo2.jsp</result> </action>
result就是用於配置頁面的跳轉的,裡面有兩個屬性 name type
name的預設值是success,假如返回值是success就不需要寫了
type屬性:頁面跳轉的類型,前兩種類型經常用,記住
dispacher 預設值,請求轉發,Action轉發jsp
redirect 重定向 Action重定向jsp
chain 轉發 ,Action轉發到Action
redirctAction 重定向,Action重定向Action (這個案例中就用到了這個)
stream struts2中提供文件下載的功能(瞭解)
三 數據封裝
1 方式一屬性驅動:提供set方法
提供屬性set方法的方式 (這種方式很少用,比如文件下載,傳過來個文件名)
jsp頁面
<h1>struts2的數據封裝</h1> <h3>方式一屬性驅動:提供set方法</h3> <form action="${pageContext.request.contextPath}/Action1" method="post"> <s:fielderror/> 用戶名:<input type="text" name="name"/><br> 密碼:<input type="text" name="password" /><br> 年齡:<input type="text" name="age"/><br> 生日:<input type="text" name="birthday"/><br> 工資:<input type="text" name="salary"/><br> <input type="submit" value="提交"> </form>
action類
/** * 方式一屬性驅動:提供set方法 */ public class Action1 extends ActionSupport { private String name; private String password; private Integer age; private Date birthday; private double salary;//工資 //需要提供set方法 public void setName(String name) { this.name = name; } public void setPassword(String password) { this.password = password; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } public void setSalary(double salary) { this.salary = salary; } @Override public String execute() throws Exception { System.out.println(name); System.out.println(password); System.out.println(age); System.out.println(birthday); System.out.println(salary); return NONE; } }
方式二屬性驅動:頁面中提供表達式(可以同時向多個對象中同時封裝數據)
在action中創建一個私有對象,提供get和set方法,一定要提供get方法
在頁面中用user.的方式
jsp界面
<h3>方式二:屬性驅動,提供頁面表達式</h3> <form action="${pageContext.request.contextPath}/Action2" method="post"> 用戶名:<input type="text" name="user.name"/><br> 密碼:<input type="text" name="user.password" /><br> 年齡:<input type="text" name="user.age"/><br> 生日:<input type="text" name="user.birthday"/><br> 工資:<input type="text" name="user.salary"/><br> <input type="submit" value="提交"> </form>
編寫action
/** * 二 屬性驅動:頁面中提供表達式 */ public class Action2 extends ActionSupport { //創建一個私有對象,提供get和set方法,一定要提供get方法 private User user; public User getUser() { //在攔截器中獲取到user對象 return user; } public void setUser(User user) { this.user = user; } @Override public String execute() throws Exception { System.out.println(user); return NONE; } }
方式三:採用模型驅動的方式(開發中最常用的方式)
模型驅動:只須實現一個介面,提供一個對象,頁面不用改
在action中實現模型驅動的介面(ModelDriven),後面跟上對象的泛型
使用的對象,必須手動提供對象的實例(new這個對象)
缺點:只能同時向一個對象中封裝數據(一般開發中都是同時向一個對象中封裝數據)
jsp界面
<h3>方式一:提供set方法</h3> <form action="${pageContext.request.contextPath}/Action3" method="post"> 用戶名:<input type="text" name="name"/><br> 密碼:<input type="text" name="password" /><br> 年齡:<input type="text" name="age"/><br> 生日:<input type="text" name="birthday"/><br> 工資:<input type="text" name="salary"/><br> <input type="submit" value="提交"> </form>
編寫action類
** * 方式三:採用模型驅動的方式 */ public class Action3 extends ActionSupport implements ModelDriven<User> { private User user=new User();//創建實例 @Override public User getModel() { //實例化對象 return user; } @Override public String execute() throws Exception { System.out.println(user); return NONE; } }
2 封裝複雜數據到List集合中
jsp界面
<h1>struts2封裝複雜數據</h1> <h3>封裝數據到List集合中</h3> <form action="${pageContext.request.contextPath}/productAction1.action" method="post"> 商品名稱:<input type="text" name="products[0].name"><br> 商品價格:<input type="text" name="products[0].price"><br> 商品名稱: <input type="text" name="products[1].name"><br> 商品價格: <input type="text" name="products[1].price"><br> 商品名稱: <input type="text" name="products[2].name"><br> 商品價格: <input type="text" name="products[2].price"><br> <input type="submit" value="提交數據">
</form>
編寫Action
/** * 封裝數據到List集合中 */ public class productAction1 extends ActionSupport { private List<Product> products; public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } @Override public String execute() throws Exception { System.out.println(products); return NONE; } }
3封裝複雜數據到map集合中
jsp界面
<h3>封裝數據到Map集合中</h3> <form action="${pageContext.request.contextPath}/productAction2.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集合中 */ public class productAction2 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 { //遍歷Map集合 for (String key :map.keySet() ) { Product product = map.get(key); System.out.println(key+" "+product); } return NONE; } }
4 寫程式時遇到的錯誤
(1)input視圖(報了input的異常,可以配一個input)
引入一個struts2的標簽庫
Invalid field value for field "age".
(2)jsp頁面中報element is not closed
兩個form表單寫到了一個表單中