Question

I have a view 'hi.jsp' with user name and password text fields. I need to submit 'hi.jsp' to 'LoginController.java'. If there is any error in the data submitted then 'LoginController.java' must redirect the request back to 'hi.jsp' (with text fields retaning the entered data) with respective error messages. After changing data and re-submitting 'hi.jsp' I get 404 error.

So the first submission is successful however problem occurs during second submission. The source code of files is mentioned below:

hi.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  <%@ taglib uri="http://www.springframework.org/tags/form" prefix="s" %>
  <%@ page session="false" %>
  <html>
      <body>    
        <s:form method="POST" modelAttribute="loginObj" action="login/validatelogin">
           <label for="userName">UserName</label>
           <s:input path="userName" id="userName" size="15"/><br>
           <div style="{color:red}"> <s:errors path="userName"></s:errors></div>

           <label for="password">Password</label>
           <s:input path="password" id="password" size="15" /><br>
           <s:errors path="password"></s:errors>

           <input name="submit" type="submit" value="login"/>      
    </s:form>
   </body>
</html>

LoginController.java

package rajeev.spring.spitter.mvc.controller;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/login")
public class LoginController {

    @RequestMapping(value="/validatelogin", method=RequestMethod.POST)
    public String validateLogin(@Valid @ModelAttribute("loginObj") LoginBean loginObj, BindingResult bindingResult)
    {
        System.out.println(bindingResult.hasErrors());
        if(bindingResult.hasErrors())
        {
            return "hi";
        }
        return "home";
    }
}

spitter-servlet.xml (spring configuration)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <mvc:annotation-driven/>
    <context:component-scan base-package="rajeev.spring.spitter.mvc.controller"></context:component-scan>
     <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
  </bean>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>Spring Hello World</display-name>
    <welcome-file-list>
        <welcome-file>/</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>springDispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
      <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spitter-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springDispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

During the second submission of 'hi.jsp' tomcat log also displays a warning:

WARNING: No mapping found for HTTP request with URI [/SpringMVC/login/login/validatelogin] in DispatcherServlet with name 'springDispatcher'

It seems that during second submission of 'hi.jsp' an extra '/login' is getting appended to the submission path of the form.

Kindly suggest if something is wrong with above code or do I need to modify it to make it working.

Thanks for your help.

Was it helpful?

Solution

This is because the relative form post URL changed when you map your handler method into a different URL

<s:form method="POST" modelAttribute="loginObj" action="login/validatelogin">

Common solution to this problem is to use absolute path, but instead of hardcoding, lookup your context-path using

<c:set var="root" value="${pageContext.request.contextPath}"/>

Then on your form

<s:form method="POST" modelAttribute="loginObj" action="${root}/login/validatelogin"> 

Other option you might consider is to use Post-Redirect pattern in your controller handler method to avoid switching the URL

public String validateLogin(@Valid @ModelAttribute("loginObj") LoginBean loginObj, BindingResult bindingResult) {
  ....
  return "redirect:/login";
}

OTHER TIPS

Try this:

<c:url var="myAction" value="/login/validatelogin"/>
<s:form method="POST" modelAttribute="loginObj" action="${myAction}">
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top