So here is a pruned down verison of my ExtendedActionForward. Martin,
the request object constructor is there as a feature for when the
forward is a redirect, using this constructor builds a redirect which
also includes all the original parameters as well as those that were added.
-Mark
Mark R. Diggory wrote:
Not only that, I now understand that replace and remove can't be done
based on current RequestDispatcher behavior. This behavior is slightly
odd for RequestDispatcher though. Why if the "getQueryString()" is
completely replaced on forward, is not the parameter map? Or from the
opposit perspective, shouldn't the getQueryString also contain the
original parameters + new parameters after the forward??? Odd!
-Mark
Mark R. Diggory wrote:
Duh, I see it now, yes your right, Thats a totally stupid mistake in
my code, there are no problems with the forwarding behavior of Stuts...
Isn't that always the case...;-)
Mark
Martin Cooper wrote:
On Fri, 18 Jun 2004, Mark R. Diggory wrote:
Martin,
I looked into this a little deeper and I'm slightly baffled by
something.
javax.servlet.RequestDispatcher.forward(request,response);
This method pretty much manages the forwarding of requests, and is
what is used by the Servlet API and the JSP API's when doing
forwarding. If I understand correctly, its behavior is such that
when it is gotten from the servlet context using
context.getRequestDispatcher(uri);
if the uri has request parameters, then the Dispatcher manages to
overload the request parameters with those encoded in the uri.
It's not a question of overloading. If there are parameters in the
URI with the same names as parameters in the original request, then
*both* values will show up at the destination. You'll see this if
you try getParameterValues() instead of getParameter().
In this situation, what you get with getParameter() is the same as
what you get with getParameterValues()[0].
Hope this helps.
--
Martin Cooper
So I go to the Stuts code that facilitates forwarding
RequestProcessor.doForward(...)
and I find that it is (of course) using this facility properly
protected void doForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Unwrap the multipart request, if there is one.
if (request instanceof MultipartRequestWrapper) {
request = ((MultipartRequestWrapper)
request).getRequest();
}
RequestDispatcher rd =
getServletContext().getRequestDispatcher(uri);
if (rd == null) {
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("requestDispatcher", uri));
return;
}
rd.forward(request, response);
}
So this makes me suspect that Struts is actually unneccessarily
encoding the request parameters onto the "uri" (plusthe ones I add)
prior to making this call to doForward, but I havn't yet gotten
this deep.
Does this make sense? This is why I believe the parameters would be
duplicated in my code when I add them by appending them to the uri.
-Mark
Mark R. Diggory wrote:
Martin Cooper wrote:
On Thu, 17 Jun 2004, Mark R. Diggory wrote:
I just finally joined the dev list
Welcome!
, so pardon if this might be an old subject but...
It's been discussed a few times.
I came up with a simple Extension to ActionForward to manage the
addition of parameters in the forwards request and posted it on
the wiki. I have a version with even more functionality which
allows the replacing and removal of parameters and specific
values of a parameter. Is this something the project would have
an interest in?
What is the purpose of the constructor which takes a request?
Given that any request parameters will still exist as parameters
if the request is forwarded, I would expect the original
parameters to be duplicated if this constructor is used and the
request is forwarded. No?
Wow, I tested it, and your right. This will only work for a
redirect, otherwise it duplicates the parameters (logical, and an
oversight on my part).
--
Martin Cooper
I think the answer to what the behavior should be in this case,
and in the case of the feature request in bug tracking can be seen
in the basic behavior of the jsp taglibrary:
In the following case, the forward supplies only the "test2"
parameter. Whereas:
<jsp:forward page="Test2.jsp"> <jsp:param name="test2"
value="test2"/> </jsp:forward>
This forward supplies the parameters that were in the original
request.
<jsp:forward page="Test2.jsp"/>
So this sort of thing has been considered before, prior to
Struts... Its Apache code, or its probibly accessable in the JSP
spec if it is not?
-Mark
package edu.harvard.hmdc.curate.study;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForward;
public class ExtendedActionForward extends ActionForward {
private Map parameters = new Hashtable();
private HttpServletRequest request = null;
/**
* Construct a Forward for which any added parameters
* will be included
*
* If it is a redirect, none of the original parameters
* will be sent in the redirect request.
*
* @param forward Forward object used for forward path
*/
public ExtendedActionForward(ActionForward forward) {
super();
if(forward.getName() != null)
this.setName(forward.getName());
if(forward.getPath() != null)
this.setPath(forward.getPath());
this.setRedirect(forward.getRedirect());
this.setContextRelative(forward.getContextRelative());
}
/**
* Construct a Forward for which any added parameters
* will be included.
*
* If it is a redirect, all of the original parameters
* will be sent in the redirect request after those which
* were added.
*
* @param forward Forward object used for forward path
* @param request Request Object used for redirect params
*/
public ExtendedActionForward(ActionForward forward, HttpServletRequest request) {
super();
if(forward.getName() != null)
this.setName(forward.getName());
if(forward.getPath() != null)
this.setPath(forward.getPath());
this.setRedirect(forward.getRedirect());
this.setContextRelative(forward.getContextRelative());
this.request = request;
}
public void addParameter(String name, String value) {
String[] newValues = null;
String[] oldValues = (String[]) parameters.get(name);
if (oldValues == null) {
newValues = new String[1];
newValues[0] = value;
} else {
newValues = new String[oldValues.length + 1];
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
newValues[oldValues.length] = value;
}
parameters.put(name, newValues);
}
public String getPath() {
String result = super.getPath();
if(!parameters.isEmpty()){
if(result.indexOf("?") == -1)
result += "?";
else
result += "&";
for(Iterator iter = parameters.keySet().iterator();iter.hasNext();){
String next = (String)iter.next();
String[] vals = (String[])parameters.get(next);
for(int i = 0; i < vals.length;i++){
if(vals[i] != null){
result += next;
result += "=";
result += URLEncoder.encode(vals[i]);
if(i <= vals.length-2 && vals[i+1] != null)
result += "&";
}
}
if(iter.hasNext())
result += "&";
}
}
if(request != null && this.getRedirect()){
Map requestParams = request.getParameterMap();
if(!requestParams.isEmpty()){
if(result.indexOf("?") == -1)
result += "?";
else
result += "&";
for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
String next = (String)iter.next();
String[] vals = (String[])requestParams.get(next);
for(int i = 0; i < vals.length;i++){
if(vals[i] != null){
result += next;
result += "=";
result += URLEncoder.encode(vals[i]);
if(i <= vals.length-2 && vals[i+1] != null)
result += "&";
}
}
if(iter.hasNext())
result += "&";
}
}
}
return result;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]