Struts2 ActionContext和用于链接操作的响应

时间:2013-05-04 10:17:54

标签: struts2 include action httpresponse actioncontext

关于struts2链接操作我有一个相当复杂的问题,提前感谢您耐心阅读我的问题。我会尽力清楚地描述它。

下面是我的struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.enable.SlashesInActionNames" value="true" />
    <constant name="struts.devMode" value="false" />


    <package name="default" extends="struts-default" namespace="/">
        <action name="test" class="com.bv.test.TestAction1" >
            <result name="success" type="chain">y</result>
        </action>

        <action name="x">
            <result name="success">/index.jsp</result>
        </action>

        <action name="y" class="com.bv.test.TestAction2">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

我的逻辑是这样的: 访问/ myapp / test时,TestAction1将处理请求; 在TestAction1中,我“包含”动作x(我的配置中的第二个动作),如下所示:

ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
rd.include(request, myResponse); 

重要的是我在使用“x.action”时使用自定义的ResponseIml。

包括之后,我返回“成功”,所以结果链到行动y(我的配置中的第3个动作);
最后,TestAction2继续处理请求,它将转到成功结果,并且应该呈现jsp,但是我看到的是一个空白页

jsp文件非常简单: index.jsp的

<h1>Test!</h1>

我的疑问/难题是:

  1. 在TestAction1中,如果我从ServletActionContext获得响应,我 包括之前和之后我会得到不同的;之前 包括是默认的响应,但包括我得到了 我定制的ResponseImpl的实例;我希望得到同样的结果 一:即:默认响应;
  2. 在TestAction2中,我从ServletActionContext获得响应,我得到了什么 是我自定义的ResponseIml的实例。这是我最重要的事情,我想我应该在这里得到一个默认的响应实例,即:org.apache.catalina.connector.Response,我在JBoss上运行;
  3. 我在TestAction2中获得了一个不同的ActionContext(与之相比) 我在TestAction1中获得的ActionContext。
  4. 这个问题确实让我感到困惑,我花了几天时间 任何建议将不胜感激! 太感谢了!!

    我的代码:

    TestAction1:

    public class TestAction1 {
      public String execute() {
        ActionContext ac = ActionContext.getContext();
        System.out.println("Before including: the action context is : " + ac);
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        System.out.println("Before including: the response is : " + response);
    
        ResponseImpl myResponse = new ResponseImpl(response);
        RequestDispatcher rd = request.getRequestDispatcher("/x.action");
        try {
          rd.include(request, myResponse); 
          String s = myResponse.getOutput();  
          System.out.println("get from response: " + s);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
    
        ac = ActionContext.getContext();
        System.out.println("After including : the action context is : " + ac);
        response = ServletActionContext.getResponse();
        System.out.println("After including : the response is : " + response);
        return "success";
      }
    }
    

    ResponseImpl:

    import java.util.Locale;
    import java.io.StringWriter;
    import java.io.PrintWriter;
    import java.io.OutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    import javax.servlet.http.Cookie;
    import javax.servlet.jsp.JspWriter;
    
    /**
     * 
     * 
     */
    public class ResponseImpl extends HttpServletResponseWrapper  {
    
      //=========================================================
      // Private fields.
      //=========================================================
    
      private ServletOutputStream outputStream = null;
    
      private ByteArrayOutputStream byteArrayOutputStream = null;
    
      private StringWriter stringWriter = null;
    
      private PrintWriter printWriter = null;
    
      private HttpServletResponse _response = null;
    
      private String contentType= "text/html";
    
      private String encoding = "UTF-8";
    
      /**
       *
       */
      class ServletOutputStream extends javax.servlet.ServletOutputStream {
    
        private OutputStream outputStream = null;
    
        /**
         *
         */
        ServletOutputStream(ByteArrayOutputStream outputStream) {
          super();
          this.outputStream = outputStream;
        }
    
        /**
         *
         */
        public void write(int b) throws IOException {
          this.outputStream.write(b);
        }
      }
    
      //=========================================================
      // Public constructors and methods.
      //=========================================================
    
      /**
       *
       */
      public ResponseImpl(HttpServletResponse response) {
        super(response);
        this._response = response;
      }
    
      /**
       *
       */
      public String getOutput() {
        if (this.stringWriter != null) {
          return this.stringWriter.toString();
        }
    
        if (this.byteArrayOutputStream != null) {
          try {
            return this.byteArrayOutputStream.toString(this.encoding);
          }
          catch (UnsupportedEncodingException e) {
          }
          return this.byteArrayOutputStream.toString();
        }
    
        return null;
      }
    
      //=========================================================
      // Implements HttpServletResponse interface.
      //=========================================================
    
      public void addCookie(Cookie cookie) {
      }
    
      public void addDateHeader(String name, long date) {
      }
    
      public void addHeader(String name, String value) {
      }
    
      public void addIntHeader(String name, int value) {
      }
    
      public boolean containsHeader(String name) {
        return false;
      }
    
      public String encodeRedirectURL(String url) {
        if (null != this._response) {
          url = this._response.encodeRedirectURL(url);
        }
        return url;
      }
    
      public String encodeURL(String url) {
        if (null != this._response) {
          url = this._response.encodeURL(url);
        }
        return url;
      }
    
      public void sendError(int sc) {
      }
    
      public void sendError(int sc, String msg) {
      }
    
      public void sendRedirect(String location) {
      }
    
      public void setDateHeader(String name, long date) {
      }
    
      public void setHeader(String name, String value) {
      }
    
      public void setIntHeader(String name, int value) {
      }
    
      public void setStatus(int sc) {
      }
    
      public void resetBuffer() {
      }
    
      //=========================================================
      // Implements deprecated HttpServletResponse methods.
      //=========================================================
    
      public void setStatus(int sc, String sm) {
      }
    
      //=========================================================
      // Implements deprecated HttpServletResponse methods.
      //=========================================================
    
      public String encodeRedirectUrl(String url) {
        return encodeRedirectURL(url);
      }
    
      public String encodeUrl(String url) {
        return encodeURL(url);
      }
    
      //=========================================================
      // Implements ServletResponse interface.
      //=========================================================
    
      public void flushBuffer() {
      }
    
      public int getBufferSize() {
        return 0;
      }
    
      public String getCharacterEncoding() {
        return this.encoding;
      }
    
      public String getContentType() {
        return this.contentType;
      }
    
      public Locale getLocale() {
        return null;
      }
    
      public javax.servlet.ServletOutputStream getOutputStream() {
        if (this.outputStream == null) {
          this.byteArrayOutputStream = new ByteArrayOutputStream();
          this.outputStream =
            new ServletOutputStream(this.byteArrayOutputStream);
        }
        return this.outputStream;
      }
    
      public PrintWriter getWriter() {
        if (this.printWriter == null) {
          this.stringWriter = new StringWriter();
          this.printWriter = new PrintWriter(this.stringWriter);
        }
        return this.printWriter;
      }
    
      public boolean isCommitted() {
        return true;
      }
    
      public void reset() {
      }
    
      public void setBufferSize(int size) {
      }
    
      public void setCharacterEncoding(String charset) {
      }
    
      public void setContentLength(int len) {
      }
    
      public void setContentType(String type) {
        int needle = type.indexOf(";");
        if (-1 == needle) {
          this.contentType = type;
        }
        else {
          this.contentType = type.substring(0, needle);
          String pattern = "charset=";
          int index = type.indexOf(pattern, needle);
          if (-1 != index) {
            this.encoding = type.substring(index + pattern.length());
          }
        }
      }
    
      public void setLocale(Locale locale) {
      }
    }
    

    TestAction2:

    public class TestAction2 {
    
      public String execute() {
        ActionContext ac = ActionContext.getContext();
        System.out.println("In TestAction 2 : the action context is : " + ac);
    
        HttpServletResponse response = ServletActionContext.getResponse();
        System.out.println("In TestAction 2 : the response is : " + response);
        return "success";
      }
    }
    

    的web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
        <display-name>Struts2 Application</display-name>
    
         <filter>
            <filter-name>struts2</filter-name>
            <filter-class>
                org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
            </filter-class>
        </filter>
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>INCLUDE</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>REQUEST</dispatcher>
        </filter-mapping>
    </web-app>
    

    这是我的调试信息。

    • 在包括之前:行动背景是 :com.opensymphony.xwork2的 ActionContext中@ c639ce
    • 之前包括:回复是: org.apache.catalina.connector.ResponseFacade@8b677f
    • 来自回复:<h1>Test!</h1>
    • 包括:行动背景是: com.opensymphony.xwork2。的 ActionContext中@ 2445d7
    • 包括:回复是:com.bv.test.ResponseImpl@165547d
    • 在TestAction 2中:操作上下文是 :com.opensymphony.xwork2的 ActionContext中@ 19478c7
    • 在TestAction 2中:回复为:com.bv.test.ResponseImpl@165547d

    所以,我在包含!!之前和之后都有不同的ActionContext实例。

2 个答案:

答案 0 :(得分:1)

当您执行rd.include时,会在Web服务器内部触发另一个请求。因此,从struts的角度来看,它会看到一个全新的请求,并且会创建一个新的操作上下文。 (这就是为什么你需要在struts2过滤器上包含'INCLUDE'的东西..所以它也看到包含的请求)。可能因为线程局部变量用于跟踪操作上下文,所以当您执行ActionContext.getContext()时,将检索与新请求相关的上下文(与include相关)。

您是否尝试将响应重置为finally块中的初始响应,如下所示

try {
      rd.include(request, myResponse); 
      String s = myResponse.getOutput();  
      System.out.println("get from response: " + s);
    }
    catch (Exception e) {
      e.printStackTrace();
    } finally {
       ServletActionContext.setResponse(response);
    }

如果这解决了响应问题..您可以将字符串's'作为变量存储在操作上下文中并在Action2中检索它

答案 1 :(得分:0)

您也可以尝试以下操作。而不是在您的TestAction1中使用链接..包括具有原始响应的TestAction2。从操作返回'none'作为返回值。

public class TestAction1 {
  public String execute() {
    ActionContext ac = ActionContext.getContext();
    System.out.println("Before including: the action context is : " + ac);
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpServletResponse response = ServletActionContext.getResponse();
    System.out.println("Before including: the response is : " + response);

    ResponseImpl myResponse = new ResponseImpl(response);
    RequestDispatcher rd = request.getRequestDispatcher("/x.action");
    try {
      rd.include(request, myResponse); 
      String s = myResponse.getOutput();  
      System.out.println("get from response: " + s);
    }
    catch (Exception e) {
      e.printStackTrace();
    }



      RequestDispatcher rd = request.getRequestDispatcher("/y.action");
        try {
          rd.include(request, response); 
        }
        catch (Exception e) {
          e.printStackTrace();
        } finally {
          return "none";
        }
      }
    }