ActionContext和ServletActionContext的区别

原创
2018/05/07 14:39
阅读数 169

什么是MVC
   1.Model模型
          模型的职责是负责业务逻辑,包含两部分:业务数据和业务处理逻辑.比如实体类,
DAO,Service都属于模型层
   2.View视图
          视图的职责是显示界面和用户交互(收集用户信息)。属于视图的类是不包含业务
逻辑和控制逻辑的JSP
   3.Controller控制器
          控制器是模型层和视图层之间的桥梁,用于流程控制。比如我们之前项目中的ActionServlet
 
 
写Struts2所需要的控制器配置文件struts.xml非常重要,该文件写请求与各个Action的对应关系,
前端控制器会根据配置信息调用对应的Action(Java类)去处理请求
注意事项:
 a.在编写struts.xml放在src目录中,而部署后该文件位于WEB-INF/classes中
 b.同样的,.properties文件也放在src下,部署后也在WEB-INF/classes/下
 c.程序一启动,struts.xml就会被加载到内存,并不是现读的
 d.程序一启动,struts.xml就会被加载到内存,并不是现读的.
 
Struts2提供的方便之处  
   1.数据的自动封装(输入属性)
      根据页面组件的name属性,自动给Action中的属性赋值
   2.数据的自动传递  
      Action中的属性在JSP页面可以直接用EL表达式拿到,即自动调用某属性的get方法
 
 
Struts2对EL表达式的支持
  EL表达式是默认访问page,request,session,application范围的数据
  在Strust2中也可以使用EL表达式访问Action对象的属性.访问顺序是page,request,
 root栈(action),session,appliction.当EL从request中获取不到信息后,会去
 ValueStack对象的root栈获取,原因是:Struts2重写了HttpServletReqeust的方法。
 
Struts2的工作流程:
  1.所有请求提交给前端控制器(FC)
  2.根据配置信息确定要调用的Action
  3.创建一个ValueStack对象(每个请求都有一个独立的VS对象)
  4.创建Action对象,把Action对象放在VS栈顶,将VS对象存到request中,存储的key为
  "struts.valueStack"
  5.控制器调用Action对象接收请求参数,并在方法根据输入属性算出输出属性
  6.在调用Action之前或之后调用一系列Interceptor
  7.根据Action返回的字符串确定Result(10种类型)
  8.调用Result对象,将VS中的数据按照特定的格式输出
  9.很多情况下,Result将转发JSP,JSP页面用Tags取出数据并显示
  10.请求处理完后,将ValueStack对象和Action对象销毁。
  
  
 在Action中访问Session和Application
 1)利用ActionContext,返回Map类型
   ActionContext context=ActionContext.getContext();
   Map<String,Object> session=context.getSession()
   session.put("usernmae":"chang");
   
   Map<String,Object> rquest=(Map)context.get("request");
   Map<String,Object> app=context.getApplication();
   
   注意事项 :不推荐使用ActionContext访问Session的方式,困为这种方式的
“侵入性”较强。ActionContext是Struts2的API,如果使用其他框架代替目前的Struts2
框架,而我们实际项目中的Action数量是非常大的,每个类修改的话,会非常麻烦。
推荐使用实现SessionAware接口的方式


  2)ServletActionContext返回的是Servlet使用类型
   HttpServletRequest httpreq=ServletActionContext.getRequest()
   HttpSession httpsession=httpreq.getSession();
   ServlerContext httpapp=ServletActionContext.getServletContext();
   
  3)由Action中实现Aware接口,由框架底层将对象注入给Action变量
    RequestAware:Map类型的request
SessionAware:Map类型的session
ApplicationAware:Map类型的application

ServletRequestAware:http 
  
  
ActionContext与ServletActionContext获取Session的异同
  1.ActionContext  
    我们在Action中取得request请求参数"username",
  ActionContext cont=ActionContext.getContext();
  Map params=cont.getParameters();
  String username=(String)params.get("username");
  
  static ThreadLocal actionContext=new ActionContextThreadLocal();
  ActionContextThreadLocal是实现ThreadLocal的一个内部类,ThreadLocal
可以命名为"线程局部变量",它为每一个使用该变量的线程提供一个变量值的
副本,使每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本
冲突,这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,
从而保证它是线程安全的.
通过ActionContext取得HttpSession: Map session=ActionContext.getContext().getSession();


  2.ServletActionContext
    ServletActionContext,这个类直接继承了我们上面介绍的ActionContext,它提供了直接
与Servlet相关对象访问的功能,它可以取得的对象有 :
     1)javax.servlet.http.HttpServletRequest:HTTPservlet请求对象
2)javax.servlet.http.HttpServletResponse:HTTPservelt响应对象
3)javax.servlet.ServletContext:Servlet上下文信息
4)javax.servlet.ServletConfig:Servlet配置对象
5)javax.servlet.jsp.PageContext:Http页面上下文
 
如何从ServletActionContext里取得Servlet相关对象
 a.取得HttpServletRequest对象
     HttpServletRequeste request=ServletActionContext.getRequest();
 b.取得HttpSession对象:
     HttpSession session=ServletActionContext.getRequeset.getSession();
 
  3.ServletActionContext和ActionContext联系
     ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该
如何抉择呢?
    如果ActionContext能够实现我们的功能,那最好不要使用ServletActionContext,让我们的
Action尽量不要直接去访问Servlet的相关对象
    注意:在使用ActionContext时有一点要注意:不要在Action的构造函数里使用ActionContext.getContext,
因为这个时候ActionContext里的一些值也许没有设置,这里通过ActionContext取得的值也许是
null,同样,HttpServletRequest req=ServletActionContext.getRequest()也不要放在构造
函数中,至于原因,因为前面讲到的static ThreadLocal actionContext=new 
ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的。而ServletActionContext
继承自ActionContext,所以ServletActionContext也线程安全,...


  4.struts2中获得request,response和session
    a.非IOc方式
  1.使用org.apache.struts2.ActionContext类,通过它的静态方法getContext()获取当前
Action的上下文对象
       ActionContext ctx=ActionContext.getContext();
  ctx.put("he":"li");//request.setAttribute("he":"li");
  Map session=ctx.getSession()
  
HttpServletRequeset request=ctx.get(org.apache.struts2.StrutsStatic.HTTP_REQUEST);
HttpServletResponse response=ctx.get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);
这里的session是Map对象,在Struts2中底层的session都被封装成了Map类型,我们可以直接操作
这个Map对象进行对session的写入和读写操作,而不用直接操作HttpSession对象


2.使用org.apache.struts2.ServletActionContext类

    b.IOC方式(即使用Struts2 Aware拦截器)
要使用IOC方式,我们首先告诉IOC容器(Container)想取得某个对象的意愿,通过实现相应的接口
做到这点
    public class UserAction extends ActionSupport implements SessionAware,ServletRequestAware,
ServletResponseAware
{
private HttpServletRequeset request;
private HttpServletResponse response;

public void setServletRequest(HttpServletRequest request)
{

}
}
    

用LoginAction继承BaseAction
public BaseAction implements SessionAware{
protected Map<String,Object> session;

public void setSession(Map<String,Object> session)
{
this.session=session;
}
}
该类实现了SessinoAware接口,表示Struts2在启动BaseAction时,首先,创建出
该Action的对象,放入"栈顶",后调用BaseAction的setSession方法,把session传入
给BaseAction对象(注意:如果是普通的Action,Struts2在启动时仅创建出该Action的对象,
然后放入“栈顶”),由此,我们定义了session属性,以便在之后其他的方法中使用,为了让
子类也能使用,所以访问控制符为protected.


按照这样的机制,我们可以让所有的Action( 如LoginAction)继承实现了SessinAware接口
的BaseActino,当需要更换Struts2框架为其他框架时,只需要修改BaseAction即可(另外的框架
只要提供一个类似SessionAware接口的接口,由BaseAction继承)


Action属性注入
  在<action>配置中,为Action组件的属性指针一个初始值,该值在创建Action对象时注入,
可以将一些变化的参数值,利用该方法指定。
例如:pageSize,password,dir存储路径等
public class ParamAction{
private String param1;
private String param2;

...各自的get/set方法


}
<action name="param" class="com.isoftstone.ParamAction">
<param name="param1">abc</param>
<param name="param2">10</param>
</action>

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部