In this blog I’m going to show the simplest possible DI used in servlet environment based on Spring 4. The blog is triggered from a question posted on SCN about how to bring Spring on HCP.

The sample will be using:

  • Java Web application runtime container
  • SDK for Java Web
  • Spring 4
  • Maven based java project.

The setup of JDK, Maven and the creation of developer account on SAP HANA Cloud Platform is not covered here, but it is required if you want to have the sample deployed in the cloud.

You can start with creating maven template project by using maven-archetype-webapp


mvn archetype:generate -DgroupId=examples -DartifactId=spring.web\
-DarchetypeArtifactId=maven-archetype-webapp




That will create the necessary project structure but it still needs two more step.

First there is no java source folder and one has to be created under src/main. It will host our servlet and spring service implementations.

My project structure looks like this.

ProjectStructure.jpg

Second the pom.xml needs to be updated with Spring Web and Servlet dependencies. Here is the complete pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  http://maven.apache.org/maven-v4_0_0.xsd">
            <modelVersion>4.0.0</modelVersion>
            <groupId>examples</groupId>
            <artifactId>spring.web</artifactId>
            <packaging>war</packaging>
            <version>0.0.1-SNAPSHOT</version>
            <name>spring.web Maven Webapp</name>
            <url>http://maven.apache.org</url>
  <build>
    <finalName>spring.web</finalName>
  </build>
  <dependencies>
            <dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>javax.servlet-api</artifactId>
 <version>3.0.1</version>
 <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
 <artifactId>spring-web</artifactId>
 <version>4.0.0.RELEASE</version>
</dependency>
  </dependencies>
</project>










Both dependencies are available on Maven Central. The servlet dependency is needed only for compiling the servlet code and is on Java Web runtime, therefore we use “provided” scope. The dependency on Spring Web is enough to bring everything we need for the sample. Actually it also brings Spring Core, Context etc, but for our case we don’t need to deal explicitly with those.

Once we have the pom.xml in place we can start with the Spring service implementation. For sample purpose we have a minimal echo service.

Note the @Service annotation, which is actually a designation that this class is a Spring component.


package examples.spring.service;
import org.springframework.stereotype.Service;
@Service
public class EchoService {
           
            public String echo(String msg){
                        return "echo: "+msg;
            }
}










Now our Spring service consumer is a Servlet, which gets a HTTP request parameter and feeds the service, returning the result back to the client


package examples.spring.web.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import examples.spring.service.EchoService;
@WebServlet(urlPatterns = "/echo")
public class EchoServlet extends HttpServlet {
            private static final long serialVersionUID = 1L;
            @Autowired
            EchoService echo;
            @Override
            public void init(ServletConfig config) throws ServletException {
                        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
                                                config.getServletContext());
                        super.init(config);
            }
            protected void doGet(HttpServletRequest request,
                                    HttpServletResponse response) throws ServletException, IOException {
                        response.getWriter().write(echo.echo(request.getParameter("msg")));
            }
}










We use WebServlet annotation with “urlPatterns” to define the servlet. Our Spring service is wired by the Spring framework. This to work, we need to engage the autowiring for the servlet in the servlet init method.

Before building and deploying the application we need to add Spring related configuration to the application deployment descriptor and create a Spring specific descriptor.

In web.xml we have following configurations:


<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_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<display-name>Sample Spring 4.0 Web Application</display-name>
<context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring.xml</param-value>
</context-param>
<listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
</web-app>










and in WEB-INF there is a new file spring.xml telling Spring on which packages to perform auto scan, detecting Spring components.


<?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:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
         http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="examples.spring"/>
</beans>










With this we have everything in place to build the application.

I added a simple index.jsp welcome file to forward to the “echo” servlet


<jsp:forward page="echo?msg=Hello Spring 4.0" />

To generate to sample app simply use “mvn package” to get everything build and final web archive generated.

Now let’s move to the Java Web SDK and deploy the application first locally and later on a trial account. If you don’t have a SDK you can get it from the Maven Central. Just search by group id for “com.sap.cloud” or search by artifact id for “a:neo-java-web-sdk” and get the Java Web SDK. Once downloaded and expanded open a command prompt and go to {SDK install}/tools folder. If you want to have Java Web runtime installed locally you can do this by running neo command line client with “install-local” parameter: neo install-local. That will generate a server folder with the  corresponding to the SDK runtime. In our case that will be Java Web runtime. It can be started with go.sh or go.bat depending on the environment. To deploy the application copy the web archive to the server pickup folder. Once deployed the application should be accessible on http://localhost:8080/spring.web

BrowserView.png

To deploy the same application on the cloud you can use neo command line tool again.


neo deploy -a {account_name} -b spring -s {webapp_path}\
 -h hanatrial.ondemand.com -u {user_name} -p {password} -j 7



You need to supply your account name, user name and password, application name which in the example above is “spring” and path to the web archive file. I also add –j 7 option which will use JRE 7 on the cloud to host the Java Web runtime. After deployment the application should be available under your account.

This sample illustrates a simple Spring based application hosted on SAP HANA Cloud Platform using Java Web runtime. There is another alternative to this approach and this is to use built-in CDI functionality available in Java EE 6 Web Profile runtime.

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. Vladimir Pavlov

    As a Java EE fan and EG member, I’m not a big fan of Spring, as you can imagine. 😉 But this is really a good step-by-step getting-started guide for folks that would like to use it on HCP. So I’m even gonna like it 😛

    (0) 
  2. Rodrigo Pinheiro

    Nice post. Can you indicate some good material on how about implement WebApplicationInitializer interface on the new Spring version instead of web.xml file?

    TY!

    (0) 

Leave a Reply