4

Below are my contoller , web xml and jsp page which uses spring form.

Controller

@Controller
@RequestMapping(value = {"/*", "/login"})
public class HelloWorldController {

    @RequestMapping(method = RequestMethod.GET)
    public String helloWorld(final Model model) {
        model.addAttribute("bodyPage", "body.jsp");
        User user = new User();
        Address address = new Address();

        user.setAddress(address);

        model.addAttribute("myUser", user);
        System.out.println("hello world");
        return "login";
    }


    @RequestMapping(value = "/submitDetails", method = RequestMethod.POST)
    public ModelAndView submitDetais(final Object command) {

        System.out.println("inside submitDetais ");
        User user = (User) command;
        return new ModelAndView("result", "user", user);
    }
}

Web Xml

<servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

Jsp Page

<form:form commandName="myUser" modelAttribute="myUser" method="POST" action="submitDetails.htm" >
    <table>
        <tr>
            <td>First Name:</td>
            <td><form:input path="firstName" /></td>
        </tr>
        <tr>
            <td>Last Name:</td>
            <td><form:input path="lastName" /></td>
        </tr>

        <tr>
            <td>Address 1:</td>
            <td><form:input path="address.address1"  /></td>
        </tr>

        <tr>
            <td>Address 2:</td>
            <td><form:input path="address.address2"  /></td>
        </tr>

        <tr>
            <td colspan="2"><input type="submit" value="Save Changes" /></td>
        </tr>
    </table>
</form:form>

Dispathcher servlet has only view resolver. Now as per the class level url pattern defined in Contoller if I navigate to the below url http://localhost:9080/ExampleSpring or http://localhost:9080/ExampleSpring/

controll is going to my jsp page and asking for details. After entering details if I submit the form with the form action as action="submitDetails.htm" as mentioned in action , its throwing 404 error. And the url in the address bar is coming as localhost:9080/submitDetails.htm which is missing the Context root for the project. My question is what am I doing wrong in the requehst mapping url section ?

As per my understanding

1.the form is submitted using post which mathes the pattern 2. /submitDetails.htm is matching the pattern /* in the class level url pattern mapping so the request should enter the controller, 3. and lastly the method level mapping in controller's method is having same url pattern amd request method as the action amd methood in jsp so it should enter the controllers method and print in the console--- which is not happeing.

Could anyone please help me understand this?

Sambuddha
  • 245
  • 5
  • 18

2 Answers2

5

From my understanding you are missing context path in your form's action attribute. Try to define it as following:

<form:form commandName="myUser" modelAttribute="myUser" method="POST" action="${pageContext.servletContext.contextPath}/submitDetails.htm" >
Stan
  • 1,410
  • 10
  • 14
  • but for servlet we dont need to specify the context path in action .. is this spefically for spring? Explicitly if we mention then it will work i guess. But is it a good practice to put context path in action ? – Sambuddha May 15 '15 at 07:33
  • Yes, it's normal practice to put context path in action of the form – Stan May 15 '15 at 07:50
2

Your problem solved after changing /* to / because, Every url contains two parts

1)Servlet Path

2)Path info

consider following code

<servlet-mapping>
    <servlet-name>ExactMatchServlet</servlet-name>
    <url-pattern>/abc</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>PathInfoServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LongPathInfoServlet</servlet-name>
    <url-pattern>/abc/*</url-pattern>
  </servlet-mapping>
</servlet-mapping>

here if you call url like

/abc then it will call ExactMatchServlet

Servlet Path -> /abc

Path info -> null

/abc/pqr it will call PathInfoServlet

Servlet Path -> /abc

Path info -> /pqr

/something/random it will call PathInfoServlet

Servlet Path -> null

path info -> /something/random

when you are replacing <url-pattern>/*</url-pattern> with

<url-pattern>/</url-pattern>

and call /something/random then

Servlet Path -> /something/random

path info -> null

So basically changing /* with / change mapping of your url parts(Servlet Path and path info)

For that region container can't find servlet for your url and it give 404 error.

Community
  • 1
  • 1
nilesh virkar
  • 429
  • 2
  • 12