27
votes

Why can't I get this to work in my Controller

@RequestMapping(method = RequestMethod.POST)
public String onSubmit(
    Model model,
    @ModelAttribute("form") Form form,
    BindingResult result, HttpServletRequest request)
    throws IOException, WriteException, BiffException {

    if (result.hasErrors()) {
        return "redirect:index.html";
    }

 }

I get:

javax.servlet.ServletException: Could not resolve view with name 'redirect:index.html' in servlet with name 'dispatcher'
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1042)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:390)

I've got this to work before. Why not now?

8
Does the exception occure, before or after the redirect is send to the browser?Ralph
It's also worth pointing out that BindingResult will not be persisted after the redirect. In other words if you redirect to your input form (in this example index.html) the errors will not show up as they are lost due to the redirect. I had to solve this just before using a HandlerInterceptor.garyj
@garyj Do you have an example of your HandlerInterceptor?blong824

8 Answers

58
votes

Try this, it should work if you have configured your view resolver properly

 return "redirect:/index.html";
25
votes

Also note that redirect: and forward: prefixes are handled by UrlBasedViewResolver, so you need to have at least one subclass of UrlBasedViewResolver among your view resolvers, such as InternalResourceViewResolver.

8
votes

For completing the answers, Spring MVC uses viewResolver(for example, as axtavt metionned, InternalResourceViewResolver) to get the specific view. Therefore the first step is making sure that a viewResolver is configured.

Secondly, you should pay attention to the url of redirection(redirect or forward). A url starting with "/" means that it's a url absolute in the application. As Jigar says,

return "redirect:/index.html";  

should work. If your view locates in the root of the application, Spring can find it. If a url without a "/", such as that in your question, it means a url relative. It explains why it worked before and don't work now. If your page calling "redirect" locates in the root by chance, it works. If not, Spring can't find the view and it doesn't work.

Here is the source code of the method of RedirectView of Spring

protected void renderMergedOutputModel(  
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)  
throws IOException {  
  // Prepare target URL.  
  StringBuilder targetUrl = new StringBuilder();  
  if (this.contextRelative && getUrl().startsWith("/")) {  
    // Do not apply context path to relative URLs.  
    targetUrl.append(request.getContextPath());  
  }  
  targetUrl.append(getUrl());  

  // ...  

  sendRedirect(request, response, targetUrl.toString(), this.http10Compatible);  
}  
4
votes

try to change this in your dispatcher-servlet.xml

<!-- Your View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
    <property name="basenames" value="views" />
    <property name="order" value="1" />
</bean>   
<!-- UrlBasedViewResolver to Handle Redirects & Forward -->
<bean id="urlViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
    <property name="order" value="2" />
</bean>        

What happens is clearly explained here http://projects.nigelsim.org/wiki/RedirectWithSpringWebMvc

4
votes

Try this

HttpServletResponse response;       
response.sendRedirect(".../webpage.xhtml");
2
votes

Axtavt answer is correct.

This is how your resolver should look like (annotations based):

    @Bean
UrlBasedViewResolver resolver(){
    UrlBasedViewResolver resolver = new UrlBasedViewResolver();

    resolver.setPrefix("/views/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);

    return resolver;
}

Obviously the name of your views directory should change based on your project.

-2
votes

It is possible to define a urlBasedViewResolver in your properties file:

excel.(class)=fi.utu.seurantaraporttisuodatin.service.Raportti  
index.(class)=org.springframework.web.servlet.view.urlBasedView  
index.viewClass =org.springframework.web.servlet.view.JstlView  
index.prefix = /WEB-INF/jsp/  
index.suffix =.jsp
-2
votes

i know this is late , but you should try redirecting to a path and not to a file ha ha