action VS Action类
action:实际上一个action代表的是struts2的一个请求。
Action:能处理Struts2的请求的类,其中有若干方法去处理请求,通过struts.xml配置文件配置
<!--
配置一个 action: 一个 struts2 的请求就是一个 action
name: 对应一个 struts2 的请求的名字(或对一个servletPath, 但去除 / 和扩展名), 不包含扩展名,比如/productinput.action,此时name写product-input
class 的默认值为: com.opensymphony.xwork2.ActionSupport
method 的默认值为: execute
result: 结果.
-->
<action name="product-input"
class="com.opensymphony.xwork2.ActionSupport"
method="execute">
<!--
result: 结果. 表示 action 方法执行后可能返回的一个结果. 所以一个 action 节点可能会有多个 result 子节点.
多个 result 子节点使用 name 来区分
name: 标识一个 result. 和 action 方法的返回值对应. 默认值为 success
type: 表示结果的类型. 默认值为 dispatcher(转发到结果.)red
-->
<result name="success" type="dispatcher">/WEB-INF/pages/input.jsp</result>
</action>
上诉配置需要注意,class为全类名,说明struts2根据全类名通过反射机制去实例话这个类的。(基础重要)小编也是深受基础毒害,没学好。同样method也是根据反射机制调用class对应类中的方法。
下一段代码表明:当请求来时,调用Product类(Action类)中的save方法处理这个请求,该方法返回一个字符串,与配置文件中result的name若一致请求转发到/WEB-INF/pages/details.jsp页面。result中有属性type默认值为
dispatcher(redirect。。。)
public class Product {
private Integer productId;
private String productName;
private String productDesc;
private double productPrice;
。。。。。。
public String save(){
System.out.println("haha");
return "detais";
}
}
配置
<action name="product-save" class="com.struct.entity.Product"method="save">
<result name="details">/WEB-INF/pages/details.jsp</result>
</action>
- 注意pojo的属性struct自动获取请求参数的情况,需要input中name的值与对应类的set定义的值一致,同样转发显示时所用的$EL表达式中的表达式也是对应类的set定义变量。否则将获取不到哦。
<form action="product-save.action" method="post">
productname:<input type="text" name="productName"/>
productdesc:<input type="text" name="productDesc"/>
productprice:<input type="text" name="productPrice"/>
<input type="submit" value="提交">
</form>
setProductId(Integer productId)
setProductName(String productName)
setProductDesc(String productDesc)
setProductPrice(double productPrice)
PId:${productId}</br>
PName:${productName}</br>
PDesc:${productDesc}</br>
PPrice:${productPrice}</br>
上诉一一对应
- Action类需要有一个无参构造器,因为配置文件中设定的是全类名,struct2通过反射机制创建,无参数构造是反射机制所需要的。(默认无参构造有,若设置有参构造,需显示设置无参)
- Struct2会为每一个HTTP请求创建一个Action实例(通过在构造器中打印了解,每次请求该Action,会不会答应一句话),所以不是单例的,线程安全。
通过ActionContext对象获取WEB资源(Application,HttpSession,Request,parameters)
//0. 获取 ActionContext 对象
//ActionContext 是 Action 的上下文对象. 可以从中获取到当往 Action 需要的一切信息
ActionContext actionContext = ActionContext.getContext();
//1. 获取 application 对应的 Map, 并向其中添加一个属性
//通过调用 ActionContext 对象的 getApplication() 方法来获取 application 对象的 Map 对象
Map<String, Object> applicationMap = actionContext.getApplication();
//设置属性
applicationMap.put("applicationKey", "applicationValue");
//获取属性
Object date = applicationMap.get("date");
System.out.println("date: " + date);
//2. session
Map<String, Object> sessionMap = actionContext.getSession();
sessionMap.put("sessionKey", "sessionValue");
System.out.println(sessionMap.getClass());
if(sessionMap instanceof SessionMap){
SessionMap sm = (SessionMap) sessionMap;
sm.invalidate();
System.out.println("session 失效了. ");
}
//3. request*
//ActionContext 中并没有提供 getRequest 方法来获取 request 对应的 Map
//需要手工调用 get() 方法, 传入 request 字符串来获取.
Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
requestMap.put("requestKey", "requestValue");
//4. 获取请求参数对应的 Map, 并获取指定的参数值.
//键: 请求参数的名字, 值: 请求参数的值对应的字符串数组
//注意: 1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]>
// 2. parameters 这个 Map 只能读, 不能写入数据, 如果写入, 但不出错, 但也不起作用!
Map<String, Object> parameters = actionContext.getParameters();
System.out.println(((String[])parameters.get("name"))[0]);
parameters.put("age", 100);
return "success";
需要注意的是struts2中获取到的Application,HttpSession,Request,parameters都是Map对象,而其中Reques的map对象需要手工调用ActionContext对象的get方法,key=request,同时该对象不能写入,只能读,若使用put方法不报错,但也是无效的。
获取其他资源的流程(如getSession()):底层调用getSession()该方法调用Map对象context的get方法传入相应的key,这里列子key为常量SESSION;可以查看源代码。