<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=kdonald" rel="nofollow">Keith Donald</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-7539?redirect=false" rel="nofollow">SPR-7539</a></strong> and commented</p>
<p dir="auto">The following lifecycle is extremely common in web apps:</p>
<ol dir="auto">
<li>bind request input to a backing bean</li>
<li>validate the bean</li>
<li>if there are bind/validation errors, re-render the form so the user can retry their submission</li>
</ol>
<p dir="auto">Steps 1 and 2 are currently handled by the <code class="notranslate">@MVC</code> framework, via JavaBean <code class="notranslate">@Controller</code> method arguments annotated with the <code class="notranslate">@Valid</code> annotation.  However, the 3rd step must always be performed manually by the developer.  This leads to duplication across <code class="notranslate">@Controllers</code>.</p>
<p dir="auto">An example of this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@RequestMapping(value=&quot;/apps&quot;, method=RequestMethod.POST)
public String createApp(Account account, @Valid AppForm form, BindingResult bindingResult) {
   // duplicated
   if (bindingResult.hasErrors()) {
       return &quot;apps/new&quot;;
   }
   return &quot;redirect:/develop/apps/&quot; + appRepository.createApp(account.getId(), form);
}

@RequestMapping(value=&quot;/apps/edit/{slug}&quot;, method=RequestMethod.POST)
public String updateApp(Account account, @PathVariable String slug, @Valid AppForm form, BindingResult bindingResult) {
    // duplicated
    if (bindingResult.hasErrors()) {
        return &quot;apps/edit&quot;;
    }
    return &quot;redirect:/develop/apps/&quot; + appRepository.updateApp(account.getId(), slug, form);
}"><pre class="notranslate"><code class="notranslate">@RequestMapping(value="/apps", method=RequestMethod.POST)
public String createApp(Account account, @Valid AppForm form, BindingResult bindingResult) {
   // duplicated
   if (bindingResult.hasErrors()) {
       return "apps/new";
   }
   return "redirect:/develop/apps/" + appRepository.createApp(account.getId(), form);
}

@RequestMapping(value="/apps/edit/{slug}", method=RequestMethod.POST)
public String updateApp(Account account, @PathVariable String slug, @Valid AppForm form, BindingResult bindingResult) {
    // duplicated
    if (bindingResult.hasErrors()) {
        return "apps/edit";
    }
    return "redirect:/develop/apps/" + appRepository.updateApp(account.getId(), slug, form);
}
</code></pre></div>
<p dir="auto">The duplicated code takes more than half of the method body.  Imagine an app with hundreds of form controllers--the duplication adds up.</p>
<p dir="auto">Something like the following would be ideal:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@RequestMapping(value=&quot;/apps&quot;, method=RequestMethod.POST)
public String createApp(Account account, @Valid AppForm form, BindingResult bindingResult) {
   return &quot;redirect:/develop/apps/&quot; + appRepository.createApp(account.getId(), form);
}

@RequestMapping(value=&quot;/apps/edit/{slug}&quot;, method=RequestMethod.POST)
public String updateApp(Account account, @PathVariable String slug, @Valid AppForm form, BindingResult bindingResult) {
    return &quot;redirect:/develop/apps/&quot; + appRepository.updateApp(account.getId(), slug, form);
}"><pre class="notranslate"><code class="notranslate">@RequestMapping(value="/apps", method=RequestMethod.POST)
public String createApp(Account account, @Valid AppForm form, BindingResult bindingResult) {
   return "redirect:/develop/apps/" + appRepository.createApp(account.getId(), form);
}

@RequestMapping(value="/apps/edit/{slug}", method=RequestMethod.POST)
public String updateApp(Account account, @PathVariable String slug, @Valid AppForm form, BindingResult bindingResult) {
    return "redirect:/develop/apps/" + appRepository.updateApp(account.getId(), slug, form);
}
</code></pre></div>
<p dir="auto">But the question is how can we get to something that is as simple as the above?  In some cases, we can rely on RequestToViewNameTranslation.  In other cases, additional metadata will be needed to tell Spring MVC which view to render on bind/validation errors.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0.4</p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398104718" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/11788" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/11788/hovercard" href="https://github.com/spring-projects/spring-framework/issues/11788">#11788</a> HandlerExceptionResolver for <code class="notranslate">@Valid</code></li>
</ul>
<p dir="auto">1 votes, 3 watchers</p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=evgenyg" rel="nofollow">Evgeny Goldin</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-7817?redirect=false" rel="nofollow">SPR-7817</a></strong> and commented</p>
<p dir="auto">Today, I can't write</p>
<p dir="auto">String s = Assert.hasText( o.getSomeText())</p>
<p dir="auto">because Assert usually returns void. If it returns value checked then I can use Assert calls in the way shown above.<br>
I wrote about this trick at <a href="http://evgeny-goldin.com/blog/return-something-not-void/" rel="nofollow">http://evgeny-goldin.com/blog/return-something-not-void/</a>.</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0.5</p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398153641" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/14461" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/14461/hovercard" href="https://github.com/spring-projects/spring-framework/issues/14461">#14461</a> Modify org.springframework.util.Assert.* methods so that they will return checked values (<em><strong>"duplicates"</strong></em>)</li>
</ul>