Sunday, 18 June 2017

Spring with Embedded Tomcat without Spring Boot


Because of service-oriented architecture style, instead of a monolithic application , you may have several independent applications can run on their own.Let's see how to have a Spring powered standalone application with embedded Tomcat without Spring boot.





Step 1 : Add Related Dependencies to POM

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.junjun.spring.util</groupId>
<artifactId>embedded-tomcat-with-spring</artifactId>
<version>1.0.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.version>4.3.7.RELEASE</spring.version>
<tomcat.version>8.5.2</tomcat.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-log4j</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>org.junjun.util.spring.AppLauncher</mainClass>
</manifest>
<manifestEntries>
<Class-Path>conf/</Class-Path>
</manifestEntries>
</archive>
<includes>
<include>**/*.class</include>
<include>*.properties.not.configurable</include>
</includes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>build-distribution</id>
<phase>verify</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/assembly/dist-build.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
view raw pom.xml hosted with ❤ by GitHub






Step 2 : Define A Class Which Would Create , Start and Stop Tomcat Server


package org.junjun.util.spring.server;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.log4j.Logger;
import org.junjun.util.spring.AppLauncher;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class EmbeddedTomcat {
private static final Logger log = org.apache.log4j.Logger.getLogger(EmbeddedTomcat.class);
@Value("${tomcat.web.content.folder.path:src/main/webapp/}")
private String webContentFolder;
@Value("${tomcat.web.base.folder.path:target/}")
private String webBaseFolder;
@Value("${tomcat.port:7070}")
private String port;
private Tomcat tomcat = new Tomcat();
@PostConstruct
public void start() throws Exception {
System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
tomcat.setPort(Integer.valueOf(port));
tomcat.setBaseDir(webBaseFolder);
StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder);
ctx.setParentClassLoader(AppLauncher.class.getClassLoader());
tomcat.start();
log.info("Tomcat Server Started at " + new Date());
tomcat.getServer().await();
}
@PreDestroy
public void stop() throws LifecycleException {
tomcat.stop();
}
}





Step 3 : Define Class Which Would Launch The Application and Initialize The Embedded Tomcat Server.

package org.junjun.util.spring;
import org.apache.log4j.Logger;
import org.junjun.util.spring.server.ServerConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AppLauncher {
private static final Logger log = Logger.getLogger(AppLauncher.class);
public static void main(String[] ars) {
AnnotationConfigApplicationContext ctx = null;
try {
ctx = new AnnotationConfigApplicationContext();
ctx.register(ServerConfig.class);
ctx.refresh();
ctx.start();
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
package org.junjun.util.spring.server;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan(basePackages = { "org.junjun.util.spring.server"})
@PropertySource("classpath:server.properties")
public class ServerConfig {
}






Step 4 : Define Web Application Initializer And Enable Spring MVC Configuration


package org.junjun.util.spring.server;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.junjun.util.spring.config.AppConfig;
import org.junjun.util.spring.config.WebConfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebInit implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
ContextLoaderListener contextLoaderListener = new ContextLoaderListener(rootContext);
container.addListener(contextLoaderListener);
AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext();
servletContext.register(WebConfig.class);
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher",
new DispatcherServlet(servletContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
view raw WebInit.java hosted with ❤ by GitHub
package org.junjun.util.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = { "org.junjun.util.spring.service"})
public class AppConfig {
}
view raw AppConfig.java hosted with ❤ by GitHub
package org.junjun.util.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@ComponentScan(basePackages = { "org.junjun.util.spring.controller" })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/view/");
bean.setSuffix(".jsp");
return bean;
}
}
view raw WebConfig.java hosted with ❤ by GitHub






Step 5 : Define Controller and Service Layer

package org.junjun.util.spring.controller;
import org.junjun.util.spring.service.EchoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
@Controller
public class WelcomeController {
@Autowired
private EchoService echoService;
@RequestMapping(value = "/echo")
public String test(WebRequest request, Model model) {
model.addAttribute("message", echoService.execute("ECHO"));
return "welcome";
}
}
package org.junjun.util.spring.service;
public interface EchoService {
String execute(String message);
}
package org.junjun.util.spring.service;
import org.springframework.stereotype.Component;
@Component
public class EchoServiceImpl implements EchoService {
@Override
public String execute(String message) {
return message + " Powered By Embeded Tomcat !";
}
}






Step 6: Define Web Page

<div id="div-msg" width="100%"
style="font-family: Verdana, Geneva, sans-serif; font-size: 30px; text-align: center; padding-top: 100px;">
${message}</div>
view raw welcome.jsp hosted with ❤ by GitHub





Step 7 : Run Class ApplicationLauncher and Check Web Page at http://localhost:6060/echo






Step 8 : Or "java -jar embedded-tomcat-with-spring-1.0.0.jar" from embedded-tomcat-with-spring-1.0.0.tar.gz by "mvn clean install"







You may refer to source code here :
https://github.com/junjun-dachi/spring-util/tree/master/embedded-tomcat-with-spring

JOB DONE








6 comments:

  1. Hii,

    I am trying to develop a standalone rest api with embedded tomcat in the same manner you are doing, only difference is that I have a restcontroller with no jsp to render the output. I want to invoke a api on controller and it should return the output as a json or a string. How to bypass the model and view here.

    ReplyDelete
  2. I appreciate that you produced this wonderful article to help us get more knowledge about this topic.
    I know, it is not an easy task to write such a big article in one day, I've tried that and I've failed. But, here you are, trying the big task and finishing it off and getting good comments and ratings. That is one hell of a job done!
    angular js training in chennai

    angular js training in omr

    full stack training in chennai

    full stack training in omr

    php training in chennai

    php training in omr

    photoshop training in chennai

    photoshop training in omr


    ReplyDelete
  3. Thanks for any other wonderful post. Where else may just anyone get that type of info in such a perfect means of writing? I’ve a presentation next week, and I am on the look for such information.


    sap training in chennai

    sap training in velachery

    azure training in chennai

    azure training in velachery

    cyber security course in chennai

    cyber security course in velachery

    ethical hacking course in chennai

    ethical hacking course in velachery

    ReplyDelete
  4. Hi. Here you are pretending the 'EmbededServer' as a Spring component (therefore as a part of application context). Is it possible to run the embedded tomcat server separately from Spring application context but still use the Spring DispatcherServlet?

    ReplyDelete

Flag Counter