Uploaded image for project: 'Struts 2'
  1. Struts 2
  2. WW-292

ActionTag/ServletDispatcherResult - more comprehensive solution

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • WW 2.0-beta1
    • WW 2.0-beta2
    • None
    • None

    Description

      There is an issue with dispatching from JSPs. Try it for example in JBoss/Jetty. I'm not sure, but it could also affect Tomcat.

      The problem is that PageContext.include() that in theory is a convenience method, in fact works a little bit different than regular dispatcher. Specifically in many cases JSP page buffers/tag buffers are not synced to servlet buffers. In many cases it leads to unconsistent when you dispatch from JSP not using PageContext.include() method. Ot's only safe to call PageContext.include() if you want tag buffers etc to work. Otherwise you have to do pageContext.getOut().flush() least once before each RequestDispatcher.include(). If you don't, you will probably see your output disappearing.

      So - I patched ActionTag to pass PageContext in ServletActionContext. I also patched ServletDispatcherResult, to check for PageContext. If it's present - it uses it to dispatch.

      I also correct things like TLD etc, so this patch really makes ActionTag working.

      Index: ActionTag.java
      ===================================================================
      RCS file: /cvs/webwork/src/java/com/opensymphony/webwork/views/jsp/ActionTag.java,v
      retrieving revision 1.2
      diff -u -r1.2 ActionTag.java
      — ActionTag.java 3 Sep 2003 16:34:06 -0000 1.2
      +++ ActionTag.java 4 Sep 2003 23:18:26 -0000
      @@ -15,6 +15,8 @@
      import com.opensymphony.xwork.ActionInvocation;
      import com.opensymphony.xwork.ActionProxy;
      import com.opensymphony.xwork.ActionProxyFactory;
      +import com.opensymphony.xwork.Result;
      +import com.opensymphony.xwork.util.OgnlValueStack;

      import ognl.Ognl;

      @@ -100,7 +102,9 @@
      // execute the action and save the proxy (and the namespace) as instance variables
      executeAction();

      • pageContext.setAttribute(getId(), proxy.getAction());
        + String id = getId();
        + if( id != null)
        + pageContext.setAttribute(id, proxy.getAction());

      return EVAL_PAGE;
      }
      @@ -170,8 +174,9 @@
      Map extraContext = Ognl.createDefaultContext(this);

      // Leave the ValueStack out – We're not processing inside the tag

      • // OgnlValueStack vs = ActionContext.getContext().getValueStack();
      • // extraContext.put(ActionContext.VALUE_STACK, vs);
        + // But we ARE processing!
        + OgnlValueStack vs = ActionContext.getContext().getValueStack();
        + extraContext.put(ActionContext.VALUE_STACK, vs);
        Map parentParams = ActionContext.getContext().getParameters();
        Map newParams = (parentParams != null) ? new HashMap(parentParams) : new HashMap();

      @@ -187,6 +192,7 @@
      ServletContext servletContext = null;

      if (pageContext != null)

      { + extraContext.put("javax.servlet.jsp.PageContext", pageContext); request = (HttpServletRequest) pageContext.getRequest(); response = (HttpServletResponse) pageContext.getResponse(); servletConfig = pageContext.getServletConfig(); @@ -226,7 +232,19 @@ }

      catch (Exception e)

      { log.error("Could not execute action: " + namespace + "/" + name, e); }

      -

      • ActionContext.getContext().put(getId(), proxy.getAction());
        +
        + String id = getId();
        + if( id != null)
        + ActionContext.getContext().put(id, proxy.getAction());
        }
        +
        + private void executeResult() throws Exception { + ActionInvocation invocation = proxy.getInvocation(); + if( invocation == null) return; + Result invocationResult = invocation.getResult(); + if( invocationResult == null) return; + + invocationResult.execute(invocation); + }

        +
        }
        Index: ActionTagExtraInfo.java
        ===================================================================
        RCS file: ActionTagExtraInfo.java
        diff -N ActionTagExtraInfo.java

          • /dev/null 1 Jan 1970 00:00:00 -0000
            +++ ActionTagExtraInfo.java 4 Sep 2003 23:18:26 -0000
            @@ -0,0 +1,41 @@
            +/*
            + * Created on 2003-09-03
            + *
            + * To change the template for this generated file go to
            + * Window>Preferences>Java>Code Generation>Code and Comments
            + */
            +package com.opensymphony.webwork.views.jsp;
            +
            +import javax.servlet.jsp.tagext.TagData;
            +import javax.servlet.jsp.tagext.TagExtraInfo;
            +
            +/**
            + * @author mimo
            + *
            + * To change the template for this generated type comment go to
            + * Window>Preferences>Java>Code Generation>Code and Comments
            + */
            +public class ActionTagExtraInfo extends TagExtraInfo
            Unknown macro: {++ /**+ * + */+ public ActionTagExtraInfo() { + super(); + }++ /* (non-Javadoc)+ * @see javax.servlet.jsp.tagext.TagExtraInfo#isValid(javax.servlet.jsp.tagext.TagData)+ */+ public boolean isValid(TagData data) { + return + data.getAttribute("showResult") != null + || + data.getId() != null; + }++ /*+ * LATER}

            Index: ServletDispatcherResult.java
            ===================================================================
            RCS file: /cvs/webwork/src/java/com/opensymphony/webwork/dispatcher/ServletDispatcherResult.java,v
            retrieving revision 1.2
            diff -u -r1.2 ServletDispatcherResult.java

          • ServletDispatcherResult.java 13 Aug 2003 20:30:21 -0000 1.2
            +++ ServletDispatcherResult.java 4 Sep 2003 23:19:26 -0000
            @@ -16,6 +16,7 @@
            import javax.servlet.RequestDispatcher;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            +import javax.servlet.jsp.PageContext;

      /**
      @@ -51,17 +52,23 @@
      log.debug("Forwarding to location " + location);
      }

      • HttpServletRequest request = ServletActionContext.getRequest();
      • HttpServletResponse response = ServletActionContext.getResponse();
      • RequestDispatcher dispatcher = request.getRequestDispatcher(location);
        -
      • // If we're included, then include the view
      • // Otherwise do forward
      • // This allow the page to, for example, set content type
      • if (!response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) { - dispatcher.forward(request, response); - }

        else

        { - dispatcher.include(request, response); - }

        + PageContext pageContext = (PageContext) ServletActionContext.getContext().get("javax.servlet.jsp.PageContext");
        + if( pageContext != null)

        { + pageContext.include(location); + }

        else

        Unknown macro: {+ HttpServletRequest request = ServletActionContext.getRequest();+ HttpServletResponse response = ServletActionContext.getResponse();+ RequestDispatcher dispatcher = request.getRequestDispatcher(location);+ + // If we're included, then include the view+ // Otherwise do forward+ // This allow the page to, for example, set content type+ if (!response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) { + dispatcher.forward(request, response); + } else { + dispatcher.include(request, response); + }+ }

        +
        }
        }
        Index: taglib.tld
        ===================================================================
        RCS file: /cvs/webwork/src/etc/taglib.tld,v
        retrieving revision 1.3
        diff -u -r1.3 taglib.tld

          • taglib.tld 29 Aug 2003 19:49:12 -0000 1.3
            +++ taglib.tld 4 Sep 2003 23:38:20 -0000
            @@ -18,7 +18,12 @@
            </info>
            <attribute>
            <name>id</name>
      • <required>true</required>
        + <required>false</required>
        + <rtexprvalue>true</rtexprvalue>
        + </attribute>
        + <attribute>
        + <name>executeResult</name>
        + <required>false</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>

      Attachments

        Activity

          People

            plightbo@gmail.com Patrick Lightbody
            mrmimo Mike Mosiewicz
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: