`

Creating RESTful Urls with Spring MVC 3.1 Part One: default-servlet-handler

阅读更多
Creating RESTful Urls with Spring MVC 3.1 Part One: default-servlet-handler
from http://www.petrikainulainen.net/programming/tips-and-tricks/creating-restful-urls-with-spring-mvc-3-1-part-one-default-servlet-handler/


This blog entry describes how you can create a web application which has restful url addresses by using Spring MVC 3.1 and the default-servlet-handler element of MVC XML namespace. The requirements for RESTful urls are given in following:

An url address must no have suffix in it (in other words, an url address most not contain a suffix like ‘.action’).
The context path of the web application must not start with a prefix like ‘app’.
I have figured out three alternative solutions to this problem and first of them is described in following:

First, you have to configure the application context of your application. This step consists of three smaller steps:

Configure the location of static resources such as css files.
Ensure that static resources are served by the container’s default servlet
Create an application context configuration class.
The first two steps can be implemented by creating an application context configuration file which content is given in following:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    <!--
       Configures the location of static resources such as css files.
       Requires Spring Framework 3.0 or higher.
    -->
    <mvc:resources mapping="/static/**" location="/static/"/>

    <!--
       Ensures that dispatcher servlet can be mapped to '/' and that static resources 
       are still served by the containers default servlet. Requires Spring Framework
       3.0 or higher.
    -->
    <mvc:default-servlet-handler/>
</beans>

The third step of the application context configuration can be implemented by using a simple Java configuration class which enables the Spring MVC support, imports the application context configuration file, sets the component scan base package and configures a view resolver bean. The source code of this configuration class is given in following:
/**
 * An application context Java configuration class. The usage of Java configuration
 * requires Spring Framework 3.0 or higher with following exceptions:
 * <ul>
 *     <li>@EnableWebMvc annotation requires Spring Framework 3.1</li>
 * </ul>
 * @author Petri Kainulainen
 */
@Configuration
@ComponentScan(basePackages = {"net.petrikainulainen.spring.restful.controller"})
@EnableWebMvc
@ImportResource("classpath:applicationContext.xml")
public class ApplicationContext {
    
    private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
    private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
    
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
        viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);

        return viewResolver;
    }
}

Second, you must configure your web application and map the dispatcher servlet to url pattern ‘/’. This example configures the web application by using Java configuration which was introduced by the Servlet 3.0 API. However, it should be fairly easy to create a web.xml configuration file based on this example if you cannot use Spring Framework 3.1 and Servlet 3.0. Configuring a web application by using Java is easy. All you have to do is to implement the WebApplicationInitializer interface. My implementation of that interface is described in following:
/**
 * Web application Java configuration class. The usage of web application
 * initializer requires Spring Framework 3.1 and Servlet 3.0.
 * @author Petri Kainulainen
 */
public class RestfulInitializer implements WebApplicationInitializer {
    
    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";
    
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationContext.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);

        servletContext.addListener(new ContextLoaderListener(rootContext));
    }
}

I have now described to you how you can configure your web application to use RESTful url addresses. This solution seems pretty clean but for some reason I was unable to get it to work with Jetty 8.1.0.RC0. This seems pretty weird to me because the mvc:default-servlet-handler Subsection of Spring Framework 3.1 reference documentation states that:

The caveat to overriding the “/” Servlet mapping is that the RequestDispatcher for the default Servlet must be retrieved by name rather than by path. The DefaultServletHttpRequestHandler will attempt to auto-detect the default Servlet for the container at startup time, using a list of known names for most of the major Servlet containers (including Tomcat, Jetty, Glassfish, JBoss, Resin, WebLogic, and WebSphere).

Since I was able to run my example application without any problems with Tomcat 7.0.23, I am wondering if the problem is somehow related to my configuration. At the moment I am suspecting that the problem is related to the default servlet name of Jetty 8.1.0.RC0 because the Spring Framework’s reference documentation also states that:

If the default Servlet has been custom configured with a different name, or if a different Servlet container is being used where the default Servlet name is unknown, then the default Servlet’s name must be explicitly provided

I decided to publish blog entry anyway because I feel that this might be valuable to someone. I had also a selfish motive since I love to use Jetty during development phase and I am hoping that someone can help to find a solution to my problem. I am going to offer you one in the next part of this series but I am not totally satisfied with it. It just does not feel right.

P.S. I have also created an example application which you can use to test the advice given in this blog entry. The source of this application is available at GitHub,https://github.com/pkainulainen/Examples/tree/master/Spring/mvc-restful-urls. If you have any advice concerning the problem I am having with Jetty 8.1.0.RC0, I be would interested to hear it out.
--------------------------------------------------------------
Creating RESTful Urls with Spring MVC 3.1 Part Two: Dispatcher Servlet Url Mappings

This blog entry describes how you can create a web application which has restful url addresses by using Spring MVC 3.1 and the default-servlet-handler element of MVC XML namespace. The requirements for RESTful urls are given in following:

An url address must no have suffix in it (in other words, an url address most not contain a suffix like ‘.action’).
The context path of the web application must not start with a prefix like ‘app’.
I have figured out three alternative solutions to this problem and first of them is described in following:

First, you have to configure the application context of your application. This step consists of three smaller steps:

Configure the location of static resources such as css files.
Ensure that static resources are served by the container’s default servlet
Create an application context configuration class.
The first two steps can be implemented by creating an application context configuration file which content is given in following:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    <!--
       Configures the location of static resources such as css files.
       Requires Spring Framework 3.0 or higher.
    -->
    <mvc:resources mapping="/static/**" location="/static/"/>

    <!--
       Ensures that dispatcher servlet can be mapped to '/' and that static resources 
       are still served by the containers default servlet. Requires Spring Framework
       3.0 or higher.
    -->
    <mvc:default-servlet-handler/>
</beans>

The third step of the application context configuration can be implemented by using a simple Java configuration class which enables the Spring MVC support, imports the application context configuration file, sets the component scan base package and configures a view resolver bean. The source code of this configuration class is given in following:
/**
 * An application context Java configuration class. The usage of Java configuration
 * requires Spring Framework 3.0 or higher with following exceptions:
 * <ul>
 *     <li>@EnableWebMvc annotation requires Spring Framework 3.1</li>
 * </ul>
 * @author Petri Kainulainen
 */
@Configuration
@ComponentScan(basePackages = {"net.petrikainulainen.spring.restful.controller"})
@EnableWebMvc
@ImportResource("classpath:applicationContext.xml")
public class ApplicationContext {
    
    private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
    private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
    
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
        viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);

        return viewResolver;
    }
}

Second, you must configure your web application and map the dispatcher servlet to url pattern ‘/’. This example configures the web application by using Java configuration which was introduced by the Servlet 3.0 API. However, it should be fairly easy to create a web.xml configuration file based on this example if you cannot use Spring Framework 3.1 and Servlet 3.0. Configuring a web application by using Java is easy. All you have to do is to implement the WebApplicationInitializer interface. My implementation of that interface is described in following:
/**
 * Web application Java configuration class. The usage of web application
 * initializer requires Spring Framework 3.1 and Servlet 3.0.
 * @author Petri Kainulainen
 */
public class RestfulInitializer implements WebApplicationInitializer {
    
    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";
    
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ApplicationContext.class);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);

        servletContext.addListener(new ContextLoaderListener(rootContext));
    }
}

I have now described to you how you can configure your web application to use RESTful url addresses. This solution seems pretty clean but for some reason I was unable to get it to work with Jetty 8.1.0.RC0. This seems pretty weird to me because the mvc:default-servlet-handler Subsection of Spring Framework 3.1 reference documentation states that:

The caveat to overriding the “/” Servlet mapping is that the RequestDispatcher for the default Servlet must be retrieved by name rather than by path. The DefaultServletHttpRequestHandler will attempt to auto-detect the default Servlet for the container at startup time, using a list of known names for most of the major Servlet containers (including Tomcat, Jetty, Glassfish, JBoss, Resin, WebLogic, and WebSphere).

Since I was able to run my example application without any problems with Tomcat 7.0.23, I am wondering if the problem is somehow related to my configuration. At the moment I am suspecting that the problem is related to the default servlet name of Jetty 8.1.0.RC0 because the Spring Framework’s reference documentation also states that:

If the default Servlet has been custom configured with a different name, or if a different Servlet container is being used where the default Servlet name is unknown, then the default Servlet’s name must be explicitly provided

I decided to publish blog entry anyway because I feel that this might be valuable to someone. I had also a selfish motive since I love to use Jetty during development phase and I am hoping that someone can help to find a solution to my problem. I am going to offer you one in the next part of this series but I am not totally satisfied with it. It just does not feel right.

P.S. I have also created an example application which you can use to test the advice given in this blog entry. The source of this application is available at GitHub,https://github.com/pkainulainen/Examples/tree/master/Spring/mvc-restful-urls. If you have any advice concerning the problem I am having with Jetty 8.1.0.RC0, I be would interested to hear it out.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics