Announcement Announcement Module
Collapse
No announcement yet.
RedirectView isEligibleValue exposing too much? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • RedirectView isEligibleValue exposing too much?

    Hi all,

    I guess it is by design, but I noticed a change in RedirectView between 2.5.x and 3.0.0.RELEASE which seems a bit unusual.

    In 2.5.x RedirectView only exposed primitives/wrappers in the url of the redirected view ala

    Code:
    protected boolean isEligibleProperty(String key, Object value) {
        return .... ClassUtils.isPrimitiveOrWrapper(value.getClass());
    }
    In 3.0.0.RELEASE, this has changed to

    Code:
    protected boolean isEligibleProperty(String key, Object value) {
        return .... BeanUtils.isSimpleValueType(value.getClass());
    }
    ... which includes things like enums, dates, uris, urls, locales, classes etc.

    I was wondering why this is now so? Under what circumstances would the default behaviour make sense?

    I ask because, typically we expose reference data like enums for a form via @ModelAttribute. eg

    Code:
    @ModelAttribute
    public Gender[] getGenders() {
        return Gender.values(); // Gender is an enum
    }
    When a form submission succeeds, we redirect to the success view. eg

    Code:
    @RequestMapping(...)
    public String saveCustomer(...) {
        ...
        return "redirect:/customers";
    }
    The RedirectView now generates urls like so:

    /customers?genders=MALE&genders=FEMALE

    Also, I'm using the RedirectView as part of the InternalResourceViewResolver, whose behaviour is from UrlBasedViewResolver#createView(...) and that doesn't expose any configurable attribute to:

    (a) create a subclass of RedirectView instead or
    (b) call RedirectView#setExposeModelAttributes(false)

    Can someone more familiar with the design of Spring MVC suggest why this new default behaviour makes sense? And how I can achieve what I want easily without sub-classing InternalResourceViewResolver and/or RedirectView or returning a View from my controller instead of a String.


    thanks,
    dave
    Last edited by davoz; Feb 21st, 2010, 04:50 PM.

  • #2
    Has nobody encountered this issue? Am I using Spring MVC 3.0 incorrectly?

    dave

    Comment


    • #3
      I ended up sub-classing InternalResourceViewResolver like so:

      Code:
      public class StrictInternalResourceViewResolver extends InternalResourceViewResolver {
      
          boolean exposeModelAttributes = false;
      
          @Override
          protected View createView(String viewName, Locale locale) throws Exception {
              View view = super.createView(viewName, locale);
              if (view instanceof RedirectView) {
                  ((RedirectView) view).setExposeModelAttributes(exposeModelAttributes);
              }
              return view;
          }
      
          public boolean isExposeModelAttributes() {
              return exposeModelAttributes;
          }
      
          public void setExposeModelAttributes(boolean exposeModelAttributes) {
              this.exposeModelAttributes = exposeModelAttributes;
          }
      
      }
      By default, it won't expose model attributes for RedirectViews. I then just need to ensure when constructing "redirect:/customers" that I explicitly include the request parameters. eg "redirect:/customers?lastName=Smith&offset=20" etc

      Comment


      • #4
        this looks good but, here is a problem as per other post: caching of the redirect view
        this is regarding you last comment, construction your own redirect parameters. Unless this is already fixed.


        http://forum.springsource.org/showthread.php?t=86633
        http://forum.springsource.org/showthread.php?t=75324



        This isn't a good sample imho (i'll register a JIRA issue for it) because now there are issues with the caching of the RedirectView, each redirect will now lead to a cached instance of RedirectView because the key is the URL and now it includes the id, if you put it in the model it would be simple /owners and spring would take care of the rest.
        Last edited by Goll97; Oct 30th, 2010, 02:27 PM.

        Comment

        Working...
        X