Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Form object strangely end up as a request parameter

  1. #1
    Join Date
    Aug 2004
    Location
    San Francisco, CA
    Posts
    66

    Default Form object strangely end up as a request parameter

    I have a FormAction which is cancellable. When the user cancels, a transition to the end-state occurs. This is all well and good. The end-state's view is a RedirectView, which works, but has the strange side effect of including a reference to the form object as part of the request.

    After the redirect I see this on the request url:

    Code:
    http://sw720usoi004t/rolbu/landing.html?%23formObject=com.foo.rol.billingutility.domain.ReportSource%401004e76
    &flowSequence=ReportSourceForm
    &source=com.foo.rol.billingutility.domain.ReportSource%401004e76
    &stepNumber=1
    &flowTimestamp=Wed+Aug+31+11%3A17%3A27+PDT+2005
    I really expected to only see:

    Code:
    http://sw720usoi004t/rolbu/landing.html
    The relavant spring web flow xml looks like this:

    Code:
    ...
    
    <view-state id="reportSourceForm" view="reportSourceFormPage">
        <entry>
            <action bean="reportSourceAction" method="referenceData" />
            <action bean="reportSourceAction" method="setupForm" />
        </entry>
        <transition on="submit" to="reportSourceSubmit">
            <action bean="reportSourceAction" method="bindAndValidate" />
        </transition>
        <transition on="cancel" to="finish" />
    </view-state>
    
    ...
    
    <end-state id="finish" view="landingRedirect" />
    And the redirect view is defined as:

    Code:
    landingRedirect.class=org.springframework.web.servlet.view.RedirectView
    landingRedirect.contextRelative=true
    landingRedirect.url=/landing.html
    How do I get rid of those request paremeters? I guess I'm asking, how do I clear the model so that it's not appended to the targetUrl?

    Thanks,
    Christian

  2. #2
    Join Date
    Dec 2004
    Location
    CA
    Posts
    208

    Default

    Redirecting should clear all your request parameters. Are you trying to redirect and at the same time store your form object within the request so it can be used in the view your are redirecting to? If you are , then you will get errors like what you are seeing. I suggest you refactor your lfow so that you don't need a redirect. I have pesonally ran into a lot of issues using redirects in my flows. Almost always, refactoring my flows not to use redirects resolved any wierd errors.

    Curtney
    Curtney Jacobs

  3. #3
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    By default the contents of the flow scope and request scope will be exposed to the view, even if that view is a RedirectView. The RedirectView will try to add all model attributes as request parameters in the redirect URL. That's what you're seeing and is standard Spring MVC behaviour.

    You can get 'controll' over this by using the 'redirect:' prefix in the end state itself:

    <end-state id="foo" view="redirect:bar?a=b&c=${flowScope.some.prop}"/>

    As you can see you can completely controll the URL that will be generated in the redirect.

    Erwin

  4. #4
    Join Date
    Aug 2004
    Location
    San Francisco, CA
    Posts
    66

    Default

    Three responses...

    Redirecting should clear all your request parameters. Are you trying to redirect and at the same time store your form object within the request so it can be used in the view your are redirecting to? If you are , then you will get errors like what you are seeing. I suggest you refactor your lfow so that you don't need a redirect. I have pesonally ran into a lot of issues using redirects in my flows. Almost always, refactoring my flows not to use redirects resolved any wierd errors.
    #1 There are valid use cases for redirects, and I believe mine is one of them. Whent he flow is over, I want to bring the user back to a home page, and as part of that, update the location in the browser accordingly.

    You can get 'controll' over this by using the 'redirect:' prefix in the end state itself:

    <end-state id="foo" view="redirect:bar?a=b&c=${flowScope.some.prop}"/>
    #2 I have tried all of these, and I get the same exception each time:

    Code:
    <end-state id="finish" view="redirect&#58;/landing.html" />
    <end-state id="finish" view="redirect&#58;landing.html" />
    <end-state id="finish" view="redirect&#58;landingPage" />
    <end-state id="finish" view="redirect&#58;landingRedirect" />
    Exception:

    Code:
    Could not resolve view with name 'redirect&#58;/landing.html' in servlet with name 'action'
    Note the 'redirect:landing.html' changes each time to reflect the url specified.

    For starters, I can't seem to get this to work period. I've checked the examples and it looks like I'm doing the same thing. Any ideas?

    Secondly, I really don't want to embedd a url in the flow definition xml, since *all* of my urls are captured in the views.properties file and my action-servlet.xml configuration. Is there an alternative?

    #3 Alternate Solution: I tried another solution, which was to add an action state that manually cleared out my flow scope. The problem is that two of the variables in the flow scope are used by my flow execution listener in the sessionEnded callback, so they can't be removed.

    Really, if I could get Erwin's redirect to work with a vew name (or even a URL if I had to), this wouldn't be important.

    My gut says this is odd because it's the end-state... and I would think that often you'd want to be able to redirect out of a flow at its end and not necessarily pass what's still in the flow scope. I must be missing something.

  5. #5
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    The simplest way is to create your own view which extends RedirectView and overrides (I think)
    Code:
    protected void appendQueryProperties&#40;StringBuffer targetUrl,
                                         Map model,
                                         String encodingScheme&#41;
                                  throws UnsupportedEncodingException
    Not the most elegant, but works for me.

    BTW, if you want the "redirect:someUrl" thing to work I expect you need to have a
    Code:
    UrlBasedViewResolver
    defined.

  6. #6
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    and I would think that often you'd want to be able to redirect out of a flow at its end and not necessarily pass what's still in the flow scope.
    Absolutely, and this is a very common use case. I'm doing exactly this in a flow on a project I'm doing. Here is what I use:

    <end-state id="endCancel" view="redirect:${flowScope.backUrl}"/>
    <end-state id="endOk" view="redirect:/showObjectDetails.do?id=${flowScope.object.id}"/>

    Make sure you have ognl.jar in your classpath so the expressions can be correctly evaluated.
    Also, as yatesco points out, in case of Spring MVC the "redirect:" prefix stuff is handled by the Spring MVC UrlBasedViewResolver, so you'll need that or one of its subclasses. (check FlowController.toModelAndView(ViewDescriptor))
    When using Struts, if you specify the "redirect:" prefix in your flow, the FlowAction will create an ActionForward with the redirect attribute set. (check FlowAction.toActionForward(ViewDescriptor, ActionMapping, HttpServletRequest))

    That being said, I suspect your problem to be the following: When you use the "redirect" prefix in your flow, SWF will create a ViewDescriptor with the redirect property set. This view descriptor will then be converted to a ModelAndView object by the FlowController.toModelAndView method. This method sees that the redirect property on the view discriptor is set and as a result prepends the "redirect:" prefix to the view name, basically assuming usage of the UrlBasedViewResolver. However, you seem to be using the ResourceBundleViewResolver which does not recognize (or need to recognize) the "redirect:" prefix so it tries to match the view name "redirect:/landing.html" as-is, which is not defined so it throws the exception that you see.

    One solution is to define a UrlBasedViewResolver in combination with the ResourceBundleViewResolver. Make sure the UrlBasedViewResolver is ordered after the other ones since it will resolve everything!

    Alternatively you could also use a 'custom' view descriptor creator, something like this:

    <end-state id="..." view="class:my.custom.MyViewDescriptorCreator"/>

    This is arguably a 'bug' in SWF, so you might want to report an issue in JIRA. Point to this thread for more info.

    Erwin

  7. #7
    Join Date
    Aug 2004
    Location
    San Francisco, CA
    Posts
    66

    Default

    Erwin and Yatesco,

    Thanks for the great responses...

    I decided to just subclass RedirectView to create a ParameterlessRedirectView which simply doesn't append the model. It was the easiest thing to do that did the trick. I may revisit at some point and try another, more correct, solution. What I've got is succinct, which makes me happy.

    My views.properties has this entry now:

    Code:
    landingRedirect.class=com.foo.rol.billingutility.web.view.ParameterlessRedirectView
    landingRedirect.contextRelative=true
    landingRedirect.url=/landing.html
    I'm not sure what exactly is a bug, so I'm not sure how to log a useful entry. I'll wing it... and reference this thread, as you recommend.

    Christian

  8. #8
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    The 'bug' is that the redirect support in SWF is kind of assuming you're using a UrlBasedViewResolver when using Spring MVC.

    Erwin

  9. #9
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Is it worth adding an enhancement to RedirectView to specify which parameters you want included/excluded?

    Almost every project I work on has it's own implementation of such a view

  10. #10
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    I guess that could be useful. Post a RFE for SpringMVC in JIRA.

    Erwin

Similar Threads

  1. Replies: 17
    Last Post: Jan 2nd, 2007, 01:43 PM
  2. Replies: 2
    Last Post: Oct 10th, 2005, 05:12 PM
  3. Loosing my SecureContext
    By sklakken in forum Security
    Replies: 3
    Last Post: Jul 21st, 2005, 01:44 PM
  4. Replies: 38
    Last Post: May 11th, 2005, 02:49 PM
  5. Transaction Management
    By caverns in forum Data
    Replies: 3
    Last Post: Mar 8th, 2005, 06:38 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •