## Struts2的第二天 ##
----------
**课程回顾:Struts2框架第一天**
1. Struts2框架的概述,前端控制器的模式,核心的过滤器
2. 入门,编写struts.xml配置文件
3. 配置文件
* 配置文件的加载
4. Action类的编写和访问
----------
**Struts2的第二天的内容**
1. Struts2框架中的Servlet的API的使用
2. Struts2中Action接收请求参数
3. Struts2中自定义拦截器
----------
**技术分析之在Struts2框架中使用Servlet的API**
1. 在Action类中也可以获取到Servlet一些常用的API
* 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的页面上。
* 提供JSP注册的页面,演示下面这三种方式jie
<h3>注册页面</h3>
<form action="${ pageContext.request.contextPath }/xxx.action" method="post">
姓名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="注册" />
</form>
2. 完全解耦合的方式
* 如果使用该种方式,Struts2框架中提供了一个类,ActionContext类,该类中提供一些方法,通过方法获取Servlet的API
* 一些常用的方法如下
public String execute() throws Exception {//1 获得ActionContext(request域)ActionContext ac = ActionContext.getContext();//2 获得解耦API//application域Map<String, Object> applicationScope = ac.getApplication();//session域Map<String, Object> sessionScope = ac.getSession();//request域//Map<String, Object> requestScope =(Map<String, Object>) ac.get("request");//struts2官方不推荐使用原生request域.//struts2推荐将键值对放入ActionContext来代替request域.//3 测试使用applicationScope.put("name", "applicationTom");sessionScope.put("name", "sessionTom");ac.put("name", "requestTom");return SUCCESS;jsp获取:
application域中:${applicationScope.name } <br> //都是struts封装好的session域中:${sessionScope.name }<br>request域中:${requestScope.name }<br>
3. 使用原生Servlet的API的方式
* Struts2框架提供了一个类,ServletActionContext,该类中提供了一些静态的方法
* 具体的方法如下
* getPageContext()
* getRequest()
* getResponse()
* getServletContext()
代码如下:
public String execute() throws Exception {//获得原生requestHttpServletRequest request = ServletActionContext.getRequest();//获得原生responseHttpServletResponse response = ServletActionContext.getResponse();//获得原生sessionHttpSession session = request.getSession();//获得原生servletContextServletContext sc = ServletActionContext.getServletContext();//---------------------------------------------------------------------sc.setAttribute("name", "applicationJerry");session.setAttribute("name", "sessionJerry");request.setAttribute("name", "requestJerry");return SUCCESS;
jsp获取:
application域中:${applicationScope.name } <br> //都是struts封装好的session域中:${sessionScope.name }<br>request域中:${requestScope.name }<br>
----------
**技术分析之结果页面的跳转**
1. 结果页面存在两种方式
* 全局结果页面
> 条件:如果<package>包中的一些action都返回success,并且返回的页面都是同一个JSP页面,这样就可以配置全局的结果页面。
> 全局结果页面针对的当前的包中的所有的Action,但是如果局部还有结果页面,会优先局部的。使用的标签是
<global-results>
<result>/demo3/suc.jsp</result>
</global-results>
* 局部结果页面
<result>/demo3/suc.jsp</result>
2. 结果页面的类型
* 结果页面使用<result>标签进行配置,包含两个属性
> name
-- 逻辑视图的名称
> type
-- 跳转的类型,值一些,需要掌握一些常用的类型。常见的结果类型去struts-default.xml中查找。
* dispatcher
-- 转发.type的默认值.Action--->JSP
* redirect
-- 重定向.
Action--->JSP
* chain
-- 多个action之间跳转.从一个Action转发到另一个Action.
Action---Action
* redirectAction
-- 多个action之间跳转.从一个Action重定向到另一个Action.
Action---Action
* stream
-- 文件下载时候使用的
----------
![](./图片/01-拦截器.bmp)
**技术分析之Struts2框架的数据封装**
1. 为什么要使用数据的封装呢?
* 作为MVC框架,必须要负责解析HTTP请求参数,并将其封装到Model对象中
* 封装数据为开发提供了很多方便
* Struts2框架提供了很强大的数据封装的功能,不再需要使用Servlet的API完成手动封装了!!
2. Struts2中提供了两类数据封装的方式?
* 第一种方式:属性驱动
> 提供对应属性的set方法进行数据的封装。
* 表单的哪些属性需要封装数据,那么在对应的Action类中提供该属性的set方法即可。
* 表单中的数据提交,最终找到Action类中的setXxx的方法,最后赋值给全局变量。
* 注意0:Struts2的框架采用的拦截器完成数据的封装。
* 注意1:这种方式不是特别好:因为属性特别多,提供多的set方法,
特别
而且还需要手动将数据存入到对象中.
* 注意2:这种情况下,Action类就相当于一个JavaBean,就没有体现出MVC的思想,Action类又封装数据,又接收请求处理,耦合性较高。
> 在页面上,使用OGNL表达式进行数据封装。(不建议使用这种模式)
* 在页面中使用OGNL表达式进行数据的封装,就可以直接把属性封装到某一个JavaBean的对象中。
* 在页面中定义一个JavaBean,并且提供set方法:例如:private User user;
* 页面中的编写发生了变化,需要使用OGNL的方式,表单中的写法:<input type="text" name="user.username">
* 注意:只提供一个set方法还不够,必须还需要提供user属性的get和set方法!!!
> 先调用get方法,判断一下是否有user对象的实例对象,如果没有,调用set方法把拦截器创建的对象注入进来,
![](index_files/53b77af9-3477-490f-b113-9dfd8b033694.png)
JSP页面如下
![](index_files/81b8beea-e73b-4930-b033-651969127298.png)
* 第二种方式:模型驱动
> 使用模型驱动的方式,也可以把表单中的数据直接封装到一个JavaBean的对象中,并且表单的写法和之前的写法没有区别!
> 编写的页面不需要任何变化,正常编写name属性的值
> 模型驱动的编写步骤:
* 手动实例化JavaBean,即:private User user = new User();
* 必须实现ModelDriven<T>接口,实现getModel()的方法,在getModel()方法中返回user即可!!
代码如下:
![](index_files/ee941bc3-9ba0-41df-92e4-a0ca97521abc.png)
----------
**技术分析之Struts2把数据封装到集合中**
1. 封装复杂类型的参数(集合类型 Collection 、Map接口等)
2. 需求:页面中有可能想批量添加一些数据,那么现在就可以使用上述的技术了。把数据封装到集合中
3. 把数据封装到Collection中
* 因为Collection接口都会有下标值,所有页面的写法会有一些区别,注意:
> <input type="text" name="products[0].name" />
* 在Action中的写法,需要提供products的集合,并且提供get和set方法。
4. 把数据封装到Map中
* Map集合是键值对的形式,页面的写法
> <input type="text" name="map['one'].name" />
* Action中提供map集合,并且提供get和set方法
代码如下:
![](index_files/672cde1d-f276-4c3c-addb-91a3c5b27b1c.png)
![](index_files/bb51db00-095b-434c-bd16-5c78d4b8c7cd.png)
jsp页面如下:
![](index_files/1c80a1f1-3d93-4dcc-8760-f2d81df3966d.png)
----------
----------