Perhaps I am missing something as there has been a great deal of
discussion about allowing an action to forward outside of the container
from an action in struts-config.xml.

My question is what business issue are you attempting to solve when this
is so easily handled in the html/jsp itself.  The only one I can imagine
is where you are triing to overlay a single struts application over
multiple physical servers.  If so isn't this better left to other
external methods of combining servers.

Anyway that is my $.02.

Edgar  


-----Original Message-----
From: David Graham [mailto:[EMAIL PROTECTED]] 
Sent: Monday, November 18, 2002 10:31 AM
To: [EMAIL PROTECTED]
Subject: Re: Forwards, Absolute URIs and Leading Slash [LONG]


Thanks for the explanation Ted.  What if I want to redirect to another 
server from an Action?  I need to return an ActionForward with 
redirect=true.  Will your solution handle absolute uris in that way?

Dave






>From: Ted Husted <[EMAIL PROTECTED]>
>Reply-To: "Struts Developers List" <[EMAIL PROTECTED]>
>To: Struts Developers List <[EMAIL PROTECTED]>
>Subject: Re: Forwards, Absolute URIs and Leading Slash [LONG]
>Date: Mon, 18 Nov 2002 08:13:05 -0500
>
>11/16/2002 9:19:51 PM, David Graham <[EMAIL PROTECTED]>
>wrote:
> >I was trying to fix
>http://nagoya.apache.org/bugzilla/show_bug.cgi?id=11021
> >but got rather confused along the way.  The problem seems to be
>that
> >RequestUtils.forwardURL() always prepends the context path even
>for absolute
> >urls.  The version comments seem to go back and forth on how to
>behave with
> >a leading / in the url.  Sometimes no leading / means don't
>prepend the
> >context, then that decision was reversed.
> >
> >Maybe I'm not the right person to fix this but we need to decide
>how to
> >determine if the user has entered an absolute url like 
> >http://www.google.com.
>
>
>
>OK, let's start with the 1.0 behavior.
>
>There are two ways to indicate a path, an ActionMapping.forward and an 
>ActionForward.
>
>In the case of an ActionMapping.forward, we did this
>
>* Get String (path) stored as the ActionMapping forward property.
>* Give it to the RequestDispatcher.
>
>which boils down to
>
>String forward = ActionMapping.getForward();
>// ... error checking
>RequestDispatcher rd =
>   getServletContext().getRequestDispatcher(forward);
>// ... error checking
>rd.forward(request, response);
>
>rd.forward allows you to forwards a request from a servlet to another 
>resource (servlet, JSP file, or HTML file) on the server. Since we 
>obtained it via getRequestDispatcher(), the ServletRequest object has 
>its path elements and parameters adjusted to match the path of the 
>target resource. So, all the references here will *always* be context 
>relative without our having to munge the path in any way.
>
>Also, this method does *not* support absolute URL with a schema 
>attached. It's meant to forward to another resource on the same server,

>and since we were using getServletContext, to a resource in the same 
>application.
>
>In the case of an ActionForward, in 1.0 we handle it like this:
>
>* Retrieve the ActionForward bean
>* get the path property
>* if the ActionForward.redirect property is true and the path starts 
>with a slash, then we insert the context path before redirecting. If 
>the path does not start with a slash (e.g, it has a schema), we leave 
>it alone.
>* if ActionForward.redirect is false (the default), we handle it like 
>the ActionMapping.forward (getServletContext.getRequestDispatcher).
>
>       if (forward != null) {
>           String path = forward.getPath();
>           if (forward.getRedirect()) {
>               if (path.startsWith("/"))
>                     path = request.getContextPath() + path;
>               response.sendRedirect(response.encodeRedirectURL
>(path));
>           } else {
>               RequestDispatcher rd =
>                   getServletContext().getRequestDispatcher(path);
>                 if (rd == null) {
>                     response.sendError 
>(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
>                                        internal.getMessage 
>("requestDispatcher",
>                                                            path));
>                     return;
>                 }
>               rd.forward(request, response);
>           }
>
>So, to get to another server, we had to set redirect=true and use an 
>ActionForward.
>
>A third way to indicate a path was via the standard ForwardAction. In 
>1.0, the behavior of the ForwardAction and IncludeAction mimicks the 
>ActionMapping.forward and ActionMapping.include with any apparent value

>add. I don't remember why we did this. My guess is that we did the 
>Actions first and then extended the ActionMappings, leaving the Actions

>behind for backward compatability.
>
>So, in 1.0, the only place we needed to munge a path was when
>
>* We used an ActionForward (rather than ActionMapping.forward)
>* Redirect was true
>* The path started with a slash
>
>We only munge it here because we are going through the 
>response.sendRedirect. Response.sendDirect doesn't know anything about 
>the ServletContext, and so we provide this bit ourselves. In all other 
>cases, RequestDispatcher does all the dirty work fr us.
>
>In 1.1, we munge paths more often, since we need to inject the module 
>component. There are also times when we should not inject the module 
>component, so we added the contextRelative property to the 
>ActionForward.
>
>When contextRelative is false (the default), we are implying that the 
>path is instead module relative.
>
>In the case of a 1.1 ActionMapping.forward, we do this
>
>* Get String (path) stored as the ActionMapping forward property.
>* Inject the module prefix (which may be blank).
>* Give it to the RequestDispatcher.
>
>So, conceptually, this appears to be same behavior as 1.0. I can only 
>ActionMapping.forward (or include) to another resource in the current 
>application (or application module).
>
>In the case of an 1.1 ActionForward, we would want to
>
>* if contextRelative is false, insert the module prefix
>
>and then
>
>* if redirect is true and the path starts with a slash, insert the 
>context path.
>
>Right now in RequestUtils.forwardURL, we're forcing a leading slash if 
>context-relative is true.
>
>         // Handle a ForwardConfig marked as context relative
>         StringBuffer sb = new StringBuffer();
>         if (forward.getContextRelative()) {
>             if (!path.startsWith("/")) {
>                 sb.append("/");
>             }
>             sb.append(path);
>             return (sb.toString());
>         }
>
>Then in RequestProcess.processForwardConfig, we're prepending the 
>context on any redirect.
>
>         if (forward.getRedirect()) {
>             response.sendRedirect
>                 (response.encodeRedirectURL(request.getContextPath
>() + uri));
>
>I believe we that forwardURL is being "too helpful" and should just 
>return the original path when context-relative is true.
>
>         // Handle a ForwardConfig marked as context relative
>         if (forward.getContextRelative()) {
>             return path;
>         }
>
>To take up the slack, processForwardConfig then needs to be a bit more 
>helpful, and expressly cover the alternatives. Something like,
>
>         String uri = RequestUtils.forwardURL(request, forward);
>         if (forward.getRedirect()) {
>
>// -        response.sendRedirect
>// -            (response.encodeRedirectURL(request.getContextPath
>() + uri));
>
>               String path = null;
>               if (uri.startsWith("/")) path =
>request.getContextPath() + uri;
>               else path = uri;
>               response.sendRedirect(response.encodeRedirectURL
>(path));
>
>         } else {
>             doForward(uri, request, response);
>         }
>
>I don't have time to test the patch right now, but will take 
>responsibilty for trying this by the middle of week (if no one has any 
>input).
>
>To make it easier to hook up with another server, like 
>http://google.com, I suggest we add a RedirectAction, which would work 
>the same as ForwardAction, but also set redirect=true.
>
>So, to link to another server (like http://google.com/), you would use 
>the RedirectAction (or equivalent).
>
>//...
>
>type="org.apache.struts.actions.RedirectAction"
>parameter="http://google.com";
>
>//...
>
>To include or forward to another servlet, you use the IncludeAction or 
>ForwardAction
>
>type="org.apache.struts.actions.ForwardAction"
>parameter="/myOtherServlet.whatever"
>
>To forward *within* the same application/module (say to front a JSP), 
>you use the ActionMapping.forward property.
>
><action path="/whatever" forward="/pages/whatever.jsp" />
>
>[where whatever.jsp is stored at $MODULE/pages]
>
>I will also take responsibility for clarifying that throughout the 
>documentation this week.
>
>When this shows up in the archive, I'll also add a link to Bugzilla 
>ticket, so there is a running record.
>
>-Ted.
>
>
>
>
>--
>To unsubscribe, e-mail:   
><mailto:[EMAIL PROTECTED]>
>For additional commands, e-mail:
><mailto:[EMAIL PROTECTED]>


_________________________________________________________________
The new MSN 8: advanced junk mail protection and 2 months FREE* 
http://join.msn.com/?page=features/junkmail


--
To unsubscribe, e-mail:
<mailto:[EMAIL PROTECTED]>
For additional commands, e-mail:
<mailto:[EMAIL PROTECTED]>


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to