struts中的action和Action类以及struts2中如何在Action类中获得servlet api的域对象

来源:互联网 发布:sql中不包含某字符串 编辑:程序博客网 时间:2024/05/16 07:00

1.Struts2的学习中大家都会遇到action和与action对应的Action类,那么什么是action什么是action对应的Action类呢?

例如struts.xml的配置文件如下:


action:代表一个struts2的请求,对应的是Action类的一个方法。

Action类:表示处理多个action请求的普通javabean。也就是配置文件中<action>节点中对应的class配置的类。

在Action定义中有如下注意点:

①属性的名字必须遵守JavaBean的属性命名规则。

②必须有一个不带参数的构造器,这样才能通过反射机制将请求的参数对应设置到Action的对象中去。

③在Action类中至少有一个处理action请求的方法。

④同一个Action类中可以有多个处理action请求的方法。

⑤struts2会为每一个Http请求创建一个Action实例,所以Action对象不是单例,是线程安全的。

2.既然Action类是处理action请求的那么难免在处理请求中需要调用Servlet API中的对象。那么我们如何在普通javabean中调用Servlet API 的对象呢?struts2框架提供了两种途径。

①和Servlet API解耦的方式获得Servlet API的对象,但是只能完成少部分的功能(例如获得请求参数,设置域对象的键值对和使域对象失效等)所以struts2框架为了和Servlet API解耦,方便Action单元测试,Struts2对HttpServletRequest,HttpSession,ServletContext做了封装,构造了三个与之对应的Map<String,Object>对象来保存和存储数据。通过解耦的方式获得Servlet API对象有两种途径。

1)通过ActionContext来获得Servlet API的对象。ActionContext称为Action上下文对象,通过这个对象可以获得Action类所需要的所有对象,例如parameters,request,session,application等所对应的map对象。

java例子如下图:

package com.yd.action;import java.util.Map;import org.apache.struts2.dispatcher.SessionMap;import com.opensymphony.xwork2.ActionContext;import com.sun.xml.internal.bind.v2.runtime.Name;public class TestActionContextAction {public String getServeltObject(){//获得ActionContext对象  该对象可以获得Action所需要的Servlet的原生域对象ActionContext actionContext=ActionContext.getContext();//1.获得HttpServletRequest对应的map 对其做操作并且进行存储   这个是获得是attribute中的值Map<String, Object> requestMap=(Map<String, Object>)actionContext.get("request");String name=(String) requestMap.get("name");System.out.println("name="+name);requestMap.put("cat", "My name is Tom");//2.获得HttpSession对应的Map  对该对象做操作  自动进行更行原生域对象Map<String, Object> sessionMap=actionContext.getSession();String price=(String) sessionMap.get("price");SessionMap<String, Object> sessionMap1=(SessionMap<String, Object>)sessionMap;//SessionMap其实就是session对应的map  调用其invalidate方法   即可以使session失效sessionMap1.invalidate();System.out.println("price="+price);sessionMap.put("dog", "I am a dog");//3.获得ServletContext  Map<String, Object> applicationMap=actionContext.getApplication();Integer age=(Integer) applicationMap.get("age");System.out.println("age="+age);applicationMap.put("person", "I have a lot of money");//4.获得paramtersMap<String, Object> parameterMap=actionContext.getParameters();String[] name1=(String[]) parameterMap.get("name");//System.out.println("name="+name1[0]);parameterMap.put("key", "value");return "success";}}
2)通过实现xxxAware接口实现获得Servlet API的一系列对象java代码如下:

package com.yd.action;import java.util.Map;import org.apache.struts2.interceptor.ApplicationAware;public class TestRealizeAware implements ApplicationAware{private Map<String, Object> application;public String getServletObject(){Integer age=(Integer)application.get("age");System.out.println("age="+age);application.put("key", "value");return "success";}//当创建该Action对象时  struts机制自动调用该方法    实现将值注入  @Overridepublic void setApplication(Map<String, Object> application) {this.application=application;}}
②通过和Servlet耦合的方式来获得Servlet API的对象,通过耦合的方式获得的对象则是原生的对象。当然通过Servlet耦合的方式获得Servlet API对象同样也有两种途径。

1)通过ServletActionContext对象获得Servlet API原生对象。

java案列如下:

package com.yd.action;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;//处理请求的Action类public class TestServletActionContext {/* * 通过耦合的方式获得Servlet API中的对象 * 1.这种方式是通过ServletActionContext获得 *  * */public String getObject(){HttpServletRequest request=ServletActionContext.getRequest();//获得session是通过request获得的HttpSession session=request.getSession();//获得上下文对象ServletContext context=ServletActionContext.getServletContext();System.out.println("request="+request+"    getObject");return "success";}}
2)通过实现ServletxxxAware接口来实现获得原生的Servelt API对象。

java代码如下:

package com.yd.action;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.interceptor.ServletResponseAware;import org.apache.struts2.util.ServletContextAware;public class TestServletAware implements ServletRequestAware,ServletResponseAware,ServletContextAware{/* * 通过实现ServletxxxAware接口来实现  对象的注入 * */@Overridepublic void setServletContext(ServletContext context) {System.out.println(context);}@Overridepublic void setServletResponse(HttpServletResponse response) {System.out.println(response);}@Overridepublic void setServletRequest(HttpServletRequest request) {System.out.println(request);}public String getObject(){return "success";}}
那么通过Servle解耦和耦合Servlet方式获得Servlet API的对象有什么区别呢?

其实很容易理解,获得原生的Servlet API对象就需要在Servlet容器中运行,那么Action的单元测试就需要有Servlet容器的环境下才能进行测试,如果获得的是原生对象的Map<String,Object>就不要在Servlet容器的环境下进行测试。这就是通过耦合和解耦的方式获得Servelt API对象的区别。

那么通过ActionContext和ServeltActionContext获得对象和实现xxxAware接口和ServeltxxxAware接口获得对象的区别是什么呢?

其实最大的区别就是实现接口的方式获得Servlet API对象更容易,当Struts2框架创建Action对象的时候就直接帮你把这写对象创建好并通过方法注入到对象中去,而通过ActionContext和ServletActionContext的方式获得需要自己手动来获取对象。根据以上的实例可以很容易看的出来的。

以上还有几个注意点是需要注意的:

①通过ActionContext对象获得HttpServletRequest对象只能通过get("request")方法来获得,这里可以通过查看ActionContext的API来看到。

②通过SessionMap对象的invalidate()方法可以使session失效,那么我们通过解耦的方式获得sessionMap通过强制转换的方法即可实现session的实现,写法如下((SessionMap)sessionMap).invalidate()。

3.那么接下来说说配置文件中result节点的属性,以及详细的配置文件写法

①result是action节点的子节点

②result代表action请求处理方法执行后可能要去的目的地。

③一个action节点可以有多个result子节点,也代表了action请求处理方法返回值的不同,去往的目的地不同。

④result节点的name属性值代表了action请求对应的方法的一个返回值。

result节点还有一个非常重要的属性就是type属性,这个属性是设置响应到目的地的类型,其值如下,这个在struts2框架jar包中的struts-default.xml的struts-default的包中可以看的到,如图:


这里主要总结其中的四个:

①redirect:表示重定向到一个web资源。response对象的重定向方法效果一致,可以通过此方法重定向到一个action请求处理方法。

②dispatcher:转发,和request对象的转发效果一致,但是通过此方法是不能实现转发到一个action的。

③redirectAction:重定向到一个action。

④chain:转发到一个action。

配置文件的写法如下:


重定向和转发到一个action都需要配置两个参数一个是actionName和namespace这样才能准确的定位到action。



0 0
原创粉丝点击