6

I've written a really simple Spring MVC app. I apologise I'm rather new to Spring MVC so bear with me.

The web.xml is as follows

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

My first question is, I have a jsp page for login with the following code...

<form action="/login" method="post" >
Username : <input name="username" type="text" />
Password : <input name="password" type="password" />
<input type="submit" />
</form>

This gives a 404 but in my Controller, I've mapped the controller to /login with the code below...

@Controller
public class LoginController {

    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String home(Locale locale, Model model, String username, String password) {

        if(username.equalsIgnoreCase("david"))
        {
            logger.info("Welcome home! the client locale is "+ locale.toString());

            Date date = new Date();
            DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

            String formattedDate = dateFormat.format(date);

            model.addAttribute("serverTime", formattedDate );

            return "home";
        }
        else
        {
            return "void";
        }

    }

}

My understanding is the @requestmapping should do the servlet mapping rather than in the web.xml, is this correct? The value of /WEB-INF/spring/appServlet/servlet-context.xml is shown below also if needed.

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

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="org.david.myapp" />



</beans:beans>

So my first question is : is the servlet mapping done in the web.xml or at the @requestmapping in the controller class?

Second question : what's the best way to architect this to have more pages, should I keep appending to the webxml? Should I create a controller for every url? Should I create a servlet-context for every url?

Thanks for reading :)

2
  • I didnt check the whole thing you gave, but on a first view your request method on the controller is GET, where your form uses a POST method. Seems to be a mistake... Commented Jan 7, 2012 at 11:01
  • ah, thank you changed but still same issue, edited code above to reflect this. Commented Jan 7, 2012 at 11:33

1 Answer 1

8

You have defined <url-pattern> to be /, which means that your appServlet will only receive requests to the root url. By changing it to /* the appServlet will get all incoming requests. This will work, but you can also consider to create a specific loginServlet which could be mapped to url /login/*.

  1. You can have multiple servlets defined in a single web.xml. Which request will hit each servlet is specified by adding more <servlet-mapping> tags.
  2. A servlet may have many controllers. Typically, one controller serves a specific part of your domain, e.g. PersonController, AddressController, etc.
  3. Each controller usually handles several urls that are logically grouped together, e.g. /persons/{id}, /persons/search, /persons/add, etc.
Sign up to request clarification or add additional context in comments.

6 Comments

Ah ok, so if the servlet-mapping is done in the web.xml, what's the purpose of the @RequestMapping(value = "/login", method = RequestMethod.POST) in the controller class? Thank you :)
You can use @RequestMapping both on class level and method level to implement a fine grained control of how different requests will be handled. The different handling can be based on the url (c.f. item 3 above), HTTP method, and / or different request parameters. More information about request mapping can be found in the Spring manual
ok, sorry I've probably confused myself, but if I have /login in the web.xml mapped to a servlet-context and then /login in the @RequestMapping, does that then mean to reach this controller I have to go to /login/login ? Thanks for your help.
I understand this can be done at both class and method level but I still don't quite understand the purpose if I have to copy the same path servlet-mapping in the web.xml
It is not the same path. The <url-pattern> in the web.xml constitutes the logical mapping of different servlets, whereas @RequestMapping handles incoming requests for each controller respectively. If for example http://localhost:8080/example/login have a specific servlet mapping, say /example/*, then the request url will be /login. Alternatively, if the servlet mapping is /*, then the request url will be /example/login. If you are implementing only one servlet then you should use the "catch all" /* servlet mapping so that the servlet is hit by all incoming requests.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.