我们知道,struts2获取request的方法有两种,一种是通过ServerletActionContext.getRequest方法来获取,另一种是继续接口ServletResponseAware。
先来讨论第一种:是通过ServerletActionContext.getRequest方法来获取
1.首先ServerletActioncontext继承ActionContext,有一个getRequest的静态方法。2.在ServerletActioncontext的静态方法getRequest中调用ActionContext的静态方法getContext然后再get(get(HTTP_REQUEST)),getContext会返回当前线程的ActionContext对象。3.ActionContext类里有一个Map,Map里保存了java容器传输过来的request,response等4.第2完成后,ActionContext.getContext().get(HTTP_REQUEST)中的get(HTTP_REQUEST)会去调用ActionContext(这个ActionContext已经是当前的ActionContext)的getMap方法,最终把request对象获取出来。第二种我就不明白了,只是简单的继承ServletResponseAware接口,接口里只定义了一个方法
public void setServletResponse(HttpServletResponse response);然后在bean里对接口进行实现,这样我就不明白了,为什么只要继承了这个接口就能获取request对象?如果我不继承接口,通过以下方法就不能获取对象public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request = request;
}
这样的一个方法跟用上面代码去实现接口从功能上看没什么区别,但为什么不实现接口就获取不了request对象,而实现接口就可以获取request对象?忘高手赐教

解决方案 »

  1.   

    我觉得每次容器加载的时候都会注册(怀疑是通过反射)实现了ServletRequestAware接口的类,然后再调用他们的setServletRequest(HttpServletRequest request)方法,将request传进去。不从这个接口继承就不会被注册,也就不会调用set方法,所以得不到request
      

  2.   

    和SPRING的机制应该是类似的
    容器在生成ACTION实例后,会通过类似的这样ServletRequestAware.class.isInstance(new Action())
    如果是则调用其setServletRequest(HttpServletRequest request) 将request注入成为其属性
    如果不是由不予以处理
      

  3.   

    你如果没有实现ServletResponseAware的话,你的Action自然不能转成接口来使用了,例如这样的代码就不能通过了。
    ServletResponseAware action = new YourAction();
    action.setServletRequest(request);
      

  4.   

    在Struts2创建你的Action,并准备调用Action中的方法前,它会先判断
    if(action instanceof ServletResponseAware) {
    ((ServletResponseAware)action).setServletRequest(request);
    }
    所以你必须实现了ServletResponseAware,Struts2才会知道你需要调用setRequest方法
      

  5.   

    其实五楼跟我想的比较接近,ServletResponseAware接口只是一个标记,是对struts2声明,我要调用request对象,然后struts才会注入request对象。