Thursday, February 26, 2015

Converting Spring boot standalone application to a web application

In the "Producing a SOAP web service" chapter of the "Getting Started" Guide from Spring, one creates a web service, which eventually runs as a standalone application. In the section Make the application executable, one reads:

"Although it is possible to package this service as a traditional WAR file for deployment to an external application server, the simpler approach demonstrated below creates a standalone application."

This blog is about the necessary changes actually needed to make the referred to web service available in a application server.

A good starting point, is to use maven archetype for a web application. This will provide the necessary structure needed for a web  application i.e. WEB-INF folder.

First add a ContextLoaderListener to your web.xml in the WEB-INF folder in order to instantiated a Spring container which will be shared by all Servlets and Filters. Because it was desirable to use an annotation style of configurations, an AnnotationConfigurationWebApplicationContext was instantiated (see contextClass context-param below) instead of the default XmlWebApplicationContext.

<web-app ..>

 <context-param>
     <param-name>contextClass</param-name>
     <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  </param-value>
 </context-param>
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>hello</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>
   <!-- take especial notice of the name of this servlet -->
    <servlet>
        <servlet-name>webservice</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
     <init-param>
       <param-name>transformWsdlLocations</param-name>
       <param-value>true</param-value>
     </init-param> 
    </servlet>

    <servlet-mapping>
        <servlet-name>webservice</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

For the webservice, a MessageDispatcherServlet was also configured in the web.xml file as shown above. Make sure that the "transformWsdlLocations" attribute of the web service Servlet is set to true during instantiation.

The MessageDispatcherServlet, because it has not been otherwise indicated in the web.xml file, expects a  configuration file called  "webservice-servlet.xml" (servlet-name plus "-servlet"), which should be located in the WEB-INF folder. The contents of the file are shown below.

<beans>
  <sws:annotation-driven/>

   <sws:dynamic-wsdl id="countries" portTypeName="CountriesPort"locationUri="/ws/countries">
       <sws:xsd location="/WEB-INF/classes/countries.xsd" />
   </sws:dynamic-wsdl>

</beans>

With those changes done, it's now time to change our focus to the WebServiceConfig.java class also described in the guide. Here, the method for the bean definition "messageDispatcherServlet" should commented out as it's no longer needed. Everything else can stay the same.

The last thing that is needed is to add the countries.xsd file, as created in the "Getting Started Guide", to the application as a resource so that it can be found by the "countriesSchema" bean, which is instantiated in the WebServiceConfig class.

Once these steps have been completed, it should possible to deploy the war to an application server like Tomcat or run it using the maven "tomcat6-maven-plugin" plugin.

The code is available here as a zip.

Good luck.

No comments:

Post a Comment