action vs Action

action:代表一个Struts2的请求

Action类:能够处理Struts2请求的类

         属性的名字必须遵守与JavaBeans属性名相同的命名规则,

         属性的类型是任意类型。从字符串到非字符串(基本数据类型)之间的数据转换可以自动发生

        

         必须有一个供Struts在执行这个action时调用的方法

         因为在Struts.xml配置文件中<action>中class中设置的是Action类的全类名,所以是通过反射机制来创建action的实例的,得有无参的构造方法才可。

 

         至少有一个供struts在执行这个action时调用的方法

 

         同一个Action 类可以应答多个Action请求 即:可以包含多个action方法

 

         Struts2 会为每一个Http 请求创建一个新的Action 实例,即 Action 不是单例的,是线程安全的。

 

 

 

         在Action中访问WEB资源:

1)  什么是WEB 资源?

HttpServletRequest  ,  HttpSession , ServletContext 等原生的 Servlet API

2)  为什么要访问 WEB资源

B/S应用的Controller中 必然需要访问 WEB资源:向域对象中读写属性 ,读写cookie

获取realPath等

3)  如何访问?

①   、和servlet API解耦的方式:能访问有限的Servlet API对象 ,且只能访问其有限的方法(读取请求参数,读写域兑现的属性,使session失效等等)

1、使用ActionContext(Action的上下文)

2、实现 XxxAware 接口

选用的建议:  若使用ActionContext 来获取各种Map,我们是在方法里面一个一个获取 ,如果其他方法也要用到Map的话 还要再获取一遍,如果有多个方法 ,可能会获取多次域Map对象 或 parameters,如果实现Aware接口,只需要定义成员变量,注入一个就可以了,其他的Action方法如果想用该Map对象 ,则直接使用即可。

 

②   、和Servlet API 耦合的方式:可以访问更多的Servlet API对象 ,且可以调用其原生的方法。

使用 ServletActionContext 类,

实现 ServletXxxAware 接口。

 

 

Struts.xml

<package name="default" namespace="/" extends = "struts-default">

       <action name="TestActionContext" class="com.atguigu.struts2.action.TestActionContextAction">

           <result>/test-actionContext.jsp</result>

       </action>

      

       <action name="TestAware" class="com.atguigu.struts2.action.TestAwareAction">

           <result>/test-aware.jsp</result>

       </action>

    </package>

 

Action:

package com.atguigu.struts2.action;

 

import java.util.Map;

 

import org.apache.struts2.dispatcher.SessionMap;

 

import com.opensymphony.xwork2.ActionContext;

 

public class TestActionContextAction {

   

    public String execute(){

       //0.获取ActionContext对象

       //ActionContext是Action的上下文对象,可以从中获取当前Action需要的一切信息

       ActionContext actionContext = ActionContext.getContext();

      

       //1.获取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,并向其中添加一个属性。

       Map<String , Object > sessionMap = actionContext.getSession();

       sessionMap.put("sessionKey", "sessionValue");

      

       System.out.println(sessionMap.getClass());

       //session 对应的Map实际上使SessionMap类型的  强转后 若调用其invalidate()方法

       //,可使其失效

       if(sessionMap instanceof SessionMap){

           SessionMap sm = (SessionMap)sessionMap;

           sm.invalidate();

           System.out.println("session 失效了。");

       }

       //3.获取request 对应的map,并向其中添加一个属性。

      

       //ActionContext中,并没有提供getRequest 方法来获取 request 对应的Map

       //需要手工调用get() 方法,传入request 字符串来获取

       //因为上面调用getSession getApplication方法时其实现参数是内部传递 的 ,调用时不需要传递参数,

       //而获取request对象的时候,它没有进行实现 ,所以要手动添加一个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]);

       //[Ljava.lang.String;@151bd96返回的是一个String 类型的数组对应的HttpServletRequest的

       //getParameterMap方法

       parameters.put("age", 100);

       return "success";

    }

}

 

package com.atguigu.struts2.action;

 

import java.util.Map;

 

import org.apache.struts2.interceptor.ApplicationAware;

import org.apache.struts2.interceptor.ParameterAware;

import org.apache.struts2.interceptor.RequestAware;

import org.apache.struts2.interceptor.SessionAware;

 

public class TestAwareAction implements ApplicationAware,SessionAware,RequestAware,

ParameterAware{

    public String execute(){

      

       //1.向application 中加入一个属性 : applicationKey2 - applicationValue2

       application.put("applicationKey2", "applicationValue");

       //2. 从application 中读取一个属性 date 并打印

       System.out.println(application.get("date"));

      

       return "success";

    }

    Map<String ,Object> application ;

   

    public void setApplication(Map<String, Object> application) {

       this.application = application;

    }

 

    public void setSession(Map<String, Object> arg0) {

       // TODO Auto-generated method stub

      

    }

 

    public void setRequest(Map<String, Object> arg0) {

       // TODO Auto-generated method stub

      

    }

   

    public void setParameters(Map<String, String[]> arg0) {

       // TODO Auto-generated method stub

      

    }

   

}

 

Index.jsp

  <body>

    <a href ="TestActionContext.action?name=atguigu">Test ActionContext</a>

    <br/>

    <br/>

    <a href ="TestAware.action?name=atguigu">Test Aware</a>

   

    <%

    if(application.getAttribute("date") == null)

       application.setAttribute("date",new Date());

   

    request.setAttribute("req","reqvalue");

    %>

   

  </body>

</html>

 

 

Test-actionContext.jsp

<body>

   <h4>Test ActionContext Page</h4>

  

   application  :  ${applicationScope.applicationKey }

   <br/>

   <br/>

  

   session  :  ${sessionScope.sessionKey }

    <br/>

    <br/>

   

    request  :  ${requestScope.requestKey }    

    <br/><br/>

   

    age  :  ${parameters.age }

    <br><br/>

    name  :  ${parameters.name }

  </body>

 

Test-aware.jsp

<body>

    <h4>Test Aware Action</h4>

     

     application : ${applicationScope.applicationKey2 }

</body>