Action

HTTP请求 提交 Struts2 StrutsPrepareAndExecuteFilter 核心控制器 ------ 请求分发给不同Action

Action书写的三种格式

第一种 Action可以是 POJO  ((PlainOldJavaObjects)简单的Java对象) ---- 不需要继承任何父类,实现任何接口

* struts2框架 读取struts.xml 获得 完整Action类名 

* obj = Class.forName("完整类名").newInstance();

    * Method m = Class.forName("完整类名").getMethod("execute");  m.invoke(obj); 通过反射 执行 execute方法

 

第二种 编写Action 实现Action接口 

Action接口中,定义默认五种 逻辑视图名称 

public static final String SUCCESS = "success";  // 数据处理成功 (成功页面)

public static final String NONE = "none";  // 页面不跳转  return null; 效果一样

public static final String ERROR = "error";  // 数据处理发送错误 (错误页面)

public static final StringS INPUT = "input"; // 用户输入数据有误,通常用于表单数据校验 (输入页面)

public static final String LOGIN = "login"; // 主要权限认证 (登陆页面)

 

五种逻辑视图,解决Action处理数据后,跳转页面 

 

第三种 编写Action  继承ActionSupport  (推荐)

   在Action中使用 表s单校验、错误信息设置、读取国际化信息 三个功能

Action的配置method(通配符)

1) 在配置 <action> 元素时,没有指定method属性, 默认执行 Action类中 execute方法

   <action name="request1" class="cn.wsjy.struts2.demo3.RequestAction1" />

2) 在<action> 元素内部 添加 method属性,指定执行Action中哪个方法 

   <action name="regist" class="cn.wsjy.struts2.demo4.RegistAction" method="regist"/> 执行 RegistAction regist方法

   * 将多个请求 业务方法 写入到一个Action 类中 

<action name="addBook" class="cn.wsjy.struts2.demo4.BookAction" method="addBook" ></action>

<action name="delBook" class="cn.wsjy.struts2.demo4.BookAction" method="delBook" ></action>   

 

3) 使用通配符,简化struts.xml配置

<a href="${pageContext.request.contextPath }/user/customer_add.action">添加客户</a>

<a href="${pageContext.request.contextPath }/user/customer_del.action">删除客户</a>

 

struts.xml

<action name="customer_*" class="cn.wsjy.struts2.demo4.CustomerAction" method="{1}"></action>   ---  {1}就是第一个匹配内容

动态方法调用

访问Action中指定方法,不进行配置 

   1) 在工程中使用 动态方法调用 ,必须保证 struts.enable.DynamicMethodInvocation = true 常量值 为true 

   2) 在action的访问路径 中 使用 "!方法名

页面

<a href="${pageContext.request.contextPath }/user/product!add.action">添加商品</a>

配置

<action name="product" class="cn.wsjy.struts2.demo4.ProductAction"></action>

执行 ProductAction 中的 add方法

Action访问Servlet

1、 在Action 中解耦合方式 间接访问 Servlet API  --------- 使用 ActionContext 对象

struts2 中 Action API 已经与 Servlet API 解耦合 (没有依赖关系 )

* Servlet API 常见操作 : 表单提交请求参数获取,向requestsessionapplication三个范围存取数据 

 

actionContext = ActionContext.getContext();

1) actionContext.getParameters(); 获得所有请求参数Map集合 

2) actionContext.put("company", "顽石教育"); / actionContext.get("company") request范围存取数据 

3) actionContext.getSession(); 获得session数据Map,对Session范围存取数据

4) actionContext.getApplication(); 获得ServletContext数据Map,对应用访问存取数据 

 

2、 使用接口注入的方式,操作Servlet API (耦合)

ServletContextAware : 注入ServletContext对象

ServletRequestAware :注入 request对象

ServletResponseAware : 注入response对象

 

程序要使用哪个Servlet的对象,实现对应接口 

 

3、 在Action中直接通过 ServletActionContext 获得Servlet API

ServletActionContext.getRequest() : 获得request对象 (session

ServletActionContext.getResponse() : 获得response 对象

ServletActionContext.getServletContext() : 获得ServletContext对象 

静态方法没有线程问题,ThreadLocal

Result结果类型

Action处理请求后, 返回字符串(逻辑视图名), 需要在struts.xml 提供 <result>元素定义结果页面 

1、 局部结果页面 和 全局结果页面 

<action name="result" class="cn.wsjy.struts2.demo6.ResultAction">

   <!-- 局部结果  当前Action使用 -->

  <result name="success">/demo6/result.jsp</result> 

</action>

 

<global-results>

<!-- 全局结果 当前包中 所有Action都可以用-->

<result name="success">/demo6/result.jsp</result>

</global-results>

 

2、 结果页面跳转类型 

struts-default.xml 定义了 一些结果页面类型 

使用默认type 是 dispatcher 转发 (request.getRequestDispatcher.forward

 

1)  dispatcher Action 转发给 JSP

2)  chain Action调用另一个Action (同一次请求)

<result name="success" type="chain">hello</result>  hello是一个Actionname 

3) redirect : Action重定向到 JSP

4) redirectAction Action重定向到另一个Action 

<result name="success" type="redirectAction">hello</result>

 

 

Action处理请求参数

struts2 和 MVC 定义关系 

StrutsPrepareAndExecuteFilter : 控制器

JSP : 视图

Action : 可以作为模型,也可以是控制器

 

struts2 Action 接受请求参数 :属性驱动 和 模型驱动

Action处理请求参数三种方式

第一种 :Action 本身作为model对象,通过成员setter封装 (属性驱动 )

页面:

用户名  <input type="text" name="username" /> <br/>

Action : 

public class RegistAction1 extends ActionSupport {

private String username;

public void setUsername(String username) {

this.username = username;

}

}

问题一: Action封装数据,会不会有线程问题 ? 

  * struts2 Action 是多实例 ,为了在Action封装数据  (struts1 Action 是单例的 )

问题二: 在使用第一种数据封装方式,数据封装到Action属性中,不可能将Action对象传递给 业务层 

  * 需要再定义单独JavaBean ,将Action属性封装到 JavaBean 

  

 

第二种 :创建独立model对象,页面通过ognl表达式封装 (属性驱动)

页面: 

用户名  <input type="text" name="user.username" /> <br/>  ----- 基于OGNL表达式的写法

Action

public class RegistAction2 extends ActionSupport {

private User user;

public void setUser(User user) {

this.user = user;

}

 

public User getUser() {

return user;

}

}

 

问题: 谁来完成的参数封装 

<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

 

第三种 :使用ModelDriven接口,对请求数据进行封装 (模型驱动 ) ----- 主流

页面:

用户名  <input type="text" name="username" /> <br/>  

Action 

public class RegistAction3 extends ActionSupport implements ModelDriven<User> {

private User user = new User(); // 必须手动实例化

public User getModel() {

return user;

}

}

* struts2 有很多围绕模型驱动的特性 

* <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> 为模型驱动提供了更多特性

 

对比第二种、第三种 : 第三种只能在Action中指定一个model对象,第二种可以在Action中定义多个model对象 

<input type="text" name="user.username" /> 

<input type="text" name="product.info" />

posted on 2017-02-21 16:44  马珂  阅读(312)  评论(0编辑  收藏  举报