## page was renamed from Spring = Spring = Spring helps development teams everywhere build simple, portable, fast and flexible JVM-based systems and applications. http://spring.io/guides http://spring.io/guides/gs/serving-web-content/ http://spring.io/guides/gs/convert-jar-to-war-maven/ == REST service == spring.io/guides/gs/rest-service/ === Structure === {{{ . |-- pom.xml |-- src | `-- main | `-- java | `-- hello | |-- Application.java | |-- Greeting.java | `-- GreetingController.java }}} === Steps === {{{#!highlight sh mkdir -p /tmp/greetingSpring mkdir -p /tmp/greetingSpring/src/main/java/hello mkdir -p /tmp/greetingSpring/target cd /tmp/greetingSpring }}} pom.xml {{{#!highlight xml 4.0.0 org.springframework gs-rest-service 0.1.0 org.springframework.boot spring-boot-starter-parent 1.1.5.RELEASE org.springframework.boot spring-boot-starter-web hello.Application maven-compiler-plugin 2.3.2 org.springframework.boot spring-boot-maven-plugin spring-releases http://repo.spring.io/libs-release spring-releases http://repo.spring.io/libs-release }}} src/main/java/hello/Application.java {{{#!highlight java package hello; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } }}} src/main/java/hello/Greeting.java {{{#!highlight java package hello; public class Greeting { private final long id; private final String content; public Greeting(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } } }}} src/main/java/hello/GreetingController.java {{{#!highlight java package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @RestController public class GreetingController { private ExecutorService es = Executors.newFixedThreadPool(50); public class MyCall implements Runnable { private DeferredResult df; private String template; private String name; private AtomicLong counter; public MyCall(DeferredResult df, String template, String name, AtomicLong counter){ this.df = df; this.template=template; this.name=name; this.counter = counter; } @Override public void run(){ Greeting g = new Greeting(this.counter.incrementAndGet(), String.format(this.template, this.name)); this.df.setResult(g); } } private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", required=false, defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } @RequestMapping("/greetingdf") public DeferredResult greetingdf(@RequestParam(value="name", required=false, defaultValue="World") String name) { DeferredResult deferredResult = new DeferredResult(); MyCall mc = new MyCall( deferredResult , template,name,counter ); es.execute(mc); return deferredResult; } } }}} Build with * mvn clean compile package Run with: * jar -tf target/gs-rest-service-0.1.0.jar # check JAR contents * java -jar target/gs-rest-service-0.1.0.jar * open URL http://localhost:8080/greeting == Tomcat REST service == Structure {{{ . |-- pom.xml |-- src `-- main `-- java `-- hello |-- Application.java |-- Greeting.java `-- GreetingController.java }}} '''pom.xml''' {{{#!highlight xml 4.0.0 org.springframework gs-rest-service-tomcat 0.1.0 war org.springframework.boot spring-boot-starter-parent 1.1.5.RELEASE org.springframework.boot spring-boot-starter-web compile hello.Application maven-compiler-plugin 2.3.2 spring-releases http://repo.spring.io/libs-release spring-releases http://repo.spring.io/libs-release }}} '''src/main/java/hello/Application.java''' {{{#!highlight java package hello; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.Configuration; @ComponentScan @EnableAutoConfiguration @Configuration public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(appClass, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(appClass); } private static Class appClass = Application.class; } }}} '''src/main/java/hello/Greeting.java''' {{{#!highlight java package hello; public class Greeting { private final long id; private final String content; public Greeting(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } } }}} '''src/main/java/hello/GreetingController.java''' {{{#!highlight java package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { private static final String template = "Hello Tomcat, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greetingTomcat") public Greeting greeting(@RequestParam(value="name", required=false, defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } } }}} === Build and deploy === * mvn clean compile package install * cp target/gs-rest-service-tomcat-0.1.0.war /usr/local/tomcat/webapps/ * cp target/gs-rest-service-tomcat-0.1.0.war /opt/apache-tomcat-7.0.53/webapps/ # in alternative * catalina.sh start * tail -f catalina.out * Open http://localhost:8080/gs-rest-service-tomcat-0.1.0/greetingTomcat == Spring MVC == '''Structure:''' {{{ . |-- pom.xml |-- src `-- main |-- java | `-- hello | |-- Application.java | `-- GreetingController.java `-- resources `-- templates `-- greeting.html }}} * mkdir -p src/main/java/hello * mkdir -p src/main/resources/templates/ * nano pom.xml {{{#!highlight xml 4.0.0 org.springframework gs-serving-web-content 0.1.0 org.springframework.boot spring-boot-starter-parent 1.1.8.RELEASE org.springframework.boot spring-boot-starter-thymeleaf hello.Application org.springframework.boot spring-boot-maven-plugin spring-milestone http://repo.spring.io/libs-release spring-milestone http://repo.spring.io/libs-release }}} * nano src/main/java/hello/GreetingController.java {{{#!highlight java package hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class GreetingController { @RequestMapping("/greeting") public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); return "greeting"; } } }}} * nano src/main/resources/templates/greeting.html {{{#!highlight html Getting Started: Serving Web Content }}} * nano src/main/java/hello/Application.java {{{#!highlight java package hello; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } }}} * mvn clean compile package install * java -jar target/gs-serving-web-content-0.1.0.jar * Open http://localhost:8080/greeting?name=Yooo == testSpringMVCJSP == Structure Maven: {{{ . |-- pom.xml |-- src | `-- main | |-- java | | `-- org | | `-- allowed | | `-- bitarus | | `-- hello | | `-- HelloController.java | `-- webapp | `-- WEB-INF | |-- mvc-dispatcher-servlet.xml | |-- pages | | `-- greeting.jsp | `-- web.xml }}} pom.xml {{{#!highlight xml 4.0.0 org.allowed.bitarus testSpringMVCJSP 0.1.0 war org.springframework spring-core 4.1.4.RELEASE org.springframework spring-web 4.1.4.RELEASE org.springframework spring-webmvc 4.1.4.RELEASE }}} HelloController.java {{{#!highlight java package org.allowed.bitarus.hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class HelloController { @RequestMapping("/hello") public String hellox(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); return "greeting"; } } }}} mvc-dispatcher-servlet.xml {{{#!highlight xml /WEB-INF/pages/ .jsp }}} greeting.jsp {{{#!highlight xml Getting Started: Serving Web Content Hello ${name} }}} web.xml {{{#!highlight xml Spring MVC Application + JSP mvc-dispatcher org.springframework.web.servlet.DispatcherServlet 1 mvc-dispatcher / contextConfigLocation /WEB-INF/mvc-dispatcher-servlet.xml org.springframework.web.context.ContextLoaderListener }}} * mvn clean compile package * Access in Tomcat http://localhost:8081/testSpringMVCJSP-0.1.0/hello?name=asd == testSpringThymeleaf ( Spring MVC + Thymeleaf + Bootstrap + JQuery + Tomcat ) == '''Maven Structure''' {{{ . |-- pom.xml |-- src | `-- main | |-- java | | `-- org | | `-- allowed | | `-- bitarus | | `-- hello | | `-- HelloController.java | `-- webapp | |-- WEB-INF | | |-- mvc-dispatcher-servlet.xml | | |-- pages | | | |-- greeting.html | | |-- web.xml | |-- css | | `-- bootstrap-3.3.2.min.css | `-- js | |-- bootstrap-3.3.2.min.js | |-- greeting.js | `-- jquery-1.11.2.min.js }}} '''pom.xml''' {{{#!highlight xml 4.0.0 org.allowed.bitarus testSpringMVCThymeleaf 0.1.0 war org.springframework spring-core 4.1.4.RELEASE org.springframework spring-web 4.1.4.RELEASE org.springframework spring-webmvc 4.1.4.RELEASE org.thymeleaf thymeleaf-spring4 2.1.4.RELEASE org.slf4j slf4j-api 1.7.10 org.slf4j slf4j-log4j12 1.7.10 }}} '''HelloController.java''' {{{#!highlight java package org.allowed.bitarus.hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class HelloController { @RequestMapping("/hello") public String hellox(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); return "greeting"; } } }}} '''mvc-dispatcher-servlet.xml''' {{{#!highlight xml }}} '''greeting.html''' {{{#!highlight html Getting Started: Serving Web Content Link (current) Link Dropdown Action Another action My First Bootstrap Page This part is inside a .container class. The .container class provides a responsive fixed width container. .col-sm-4 .col-sm-4 .col-sm-4 .col-md-4 .col-md-4 .col-md-4 Home Profile Messages Panel home This is a Basic panel home Email address: Password: Remember me Click to show modal Panel profile Panel messages × Confirmation Do you want to save changes you made to document before closing? If you don't save, your changes will be lost. }}} '''web.xml''' {{{#!highlight xml Spring MVC Application + Thymeleaf mvc-dispatcher org.springframework.web.servlet.DispatcherServlet 1 mvc-dispatcher / contextConfigLocation /WEB-INF/mvc-dispatcher-servlet.xml }}} '''greeting.js''' {{{#!highlight java $(document).ready(greetingReady); function greetingReady(){ console.log("greeting ready !!!!"); $('.tabHome').click(homeClicked); $('.tabProfile').click(profileClicked); $('.tabMessages').click(messagesClicked); $('.tabHome').addClass('active'); $('.panelHome').show(); $('.panelProfile').hide(); $('.panelMessages').hide(); $('.panel-heading').click(headingClicked); $('#submitButton').click(submitClicked); } function submitClicked(event){ $('#myModal').modal('show'); } function headingClicked(){ $('.panel-body').toggle(); } function homeClicked(event){ event.preventDefault(); event.stopPropagation(); $('.panelHome').show(); $('.panelProfile').hide(); $('.panelMessages').hide(); $('.tabHome').addClass('active'); $('.tabProfile').removeClass('active'); $('.tabMessages').removeClass('active'); } function profileClicked(event){ event.preventDefault(); event.stopPropagation(); $('.panelHome').hide(); $('.panelProfile').show(); $('.panelMessages').hide(); $('.tabHome').removeClass('active'); $('.tabProfile').addClass('active'); $('.tabMessages').removeClass('active'); } function messagesClicked(event){ event.preventDefault(); event.stopPropagation(); $('.panelHome').hide(); $('.panelProfile').hide(); $('.panelMessages').show(); $('.tabHome').removeClass('active'); $('.tabProfile').removeClass('active'); $('.tabMessages').addClass('active'); } }}} * mvn clean compile package * Deploy in Tomcat listening in 8081. Access in Tomcat http://localhost:8081/testSpringMVCThymeleaf-0.1.0/hello?name=agh == spring-mvc-html == Project structure: {{{ . |-- pom.xml |-- src | `-- main | |-- java | | `-- org | | `-- allowed | | `-- bitarus | | `-- spring | | `-- mvc | | `-- html | | |-- ConfigX.java | | |-- ContextServletListener.java | | |-- HelloController.java | | |-- TestDAO.java | | `-- ThreadTimer.java | |-- resources | | |-- log4j.properties | | `-- test.sql | `-- webapp | `-- WEB-INF | |-- applicationContext.xml | |-- mvc-dispatcher-servlet.xml | |-- pages | | `-- greeting.jsp | `-- web.xml }}} Uses Spring 4, Tomcat 7.0.X, commons-dbcp, MariaDB, Gson and log4j. === pom.xml === {{{#!highlight xml 4.0.0 org.allowed.bitarus spring-mvc-html 0.1.0 war org.springframework spring-core 4.1.4.RELEASE org.springframework spring-web 4.1.4.RELEASE org.springframework spring-webmvc 4.1.4.RELEASE org.springframework spring-jdbc 4.1.4.RELEASE com.google.code.gson gson 2.5 org.mariadb.jdbc mariadb-java-client 1.4.4 log4j log4j 1.2.17 javax.servlet javax.servlet-api 3.1.0 provided commons-dbcp commons-dbcp 1.4 }}} === web.xml === {{{#!highlight xml Spring MVC- HTML mvc-dispatcher org.springframework.web.servlet.DispatcherServlet 1 mvc-dispatcher / org.springframework.web.context.ContextLoaderListener }}} === applicationContext.xml === {{{#!highlight xml }}} === mvc-dispatcher-servlet.xml === {{{#!highlight xml /WEB-INF/pages/ .jsp greeting }}} === log4j.properties === {{{#!highlught bash log4j.rootLogger = ALL, rootLogger log4j.appender.rootLogger=org.apache.log4j.FileAppender log4j.appender.rootLogger.File=/tmp/testlog.out log4j.appender.rootLogger.layout=org.apache.log4j.PatternLayout log4j.appender.rootLogger.layout.ConversionPattern=%d{ISO8601}|%p|%c|%t|%m%n #log4j.appender.rootLogger.Threshold=ALL log4j.appender.rootLogger.Threshold=INFO log4j.logger.org.allowed.bitarus.spring.mvc.html.HelloController=ALL,helloConsConsole log4j.appender.helloConsConsole=org.apache.log4j.ConsoleAppender log4j.appender.helloConsConsole.layout=org.apache.log4j.PatternLayout log4j.appender.helloConsConsole.layout.ConversionPattern=%d{ISO8601}|%p|%c|%t|%m%n #log4j.appender.helloConsConsole.Threshold=DEBUG log4j.appender.helloConsConsole.Threshold=INFO log4j.logger.org.allowed.bitarus.spring.mvc.html.ThreadTimer=ALL,threadTimerConsole log4j.appender.threadTimerConsole=org.apache.log4j.ConsoleAppender log4j.appender.threadTimerConsole.layout=org.apache.log4j.PatternLayout log4j.appender.threadTimerConsole.layout.ConversionPattern=%d{ISO8601}|%p|%c|%t|%m%n #log4j.appender.threadTimerConsole.Threshold=DEBUG log4j.appender.threadTimerConsole.Threshold=INFO log4j.logger.org.allowed.bitarus.spring.mvc.html.TestDAO=ALL,testDAOConsole log4j.appender.testDAOConsole=org.apache.log4j.ConsoleAppender log4j.appender.testDAOConsole.layout=org.apache.log4j.PatternLayout log4j.appender.testDAOConsole.layout.ConversionPattern=%d{ISO8601}|%p|%c|%t|%m%n #log4j.appender.testDAOConsole.Threshold=DEBUG log4j.appender.testDAOConsole.Threshold=INFO log4j.logger.org.allowed.bitarus.spring.mvc.html.ConfigX=ALL,configXConsole log4j.appender.configXConsole=org.apache.log4j.ConsoleAppender log4j.appender.configXConsole.layout=org.apache.log4j.PatternLayout log4j.appender.configXConsole.layout.ConversionPattern=%d{ISO8601}|%p|%c|%t|%m%n #log4j.appender.configXConsole.Threshold=DEBUG log4j.appender.configXConsole.Threshold=INFO }}} === test.sql === {{{#!highlight sql --JDBC URL: jdbc:mariadb://localhost:3306/springmvchtml create database springmvchtml; create user 'usertest'@'%' identified by '????????'; create user 'usertest'@'localhost' identified by '????????'; grant all on springmvchtml.* to 'usertest'@'%'; grant all on springmvchtml.* to 'usertest'@'localhost'; show grants for 'usertest'@'%'; show grants for 'usertest'@'localhost'; create table springmvchtml.dummy (name varchar(255) ) ; insert into springmvchtml.dummy (name) values('aaaa'); insert into springmvchtml.dummy (name) values('bbbb'); commit; }}} === TestDAO.java === {{{#!highlight java package org.allowed.bitarus.spring.mvc.html; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; public class TestDAO { @Autowired @Qualifier("testJdbcTemplate") private JdbcTemplate jdbcTemplate; private Logger logger; public TestDAO() { this.logger = Logger.getLogger(TestDAO.class); logger.info("Created " + this.getClass().getSimpleName()); } public String getNameFromDummy() { return this.jdbcTemplate.queryForObject("select name from dummy limit 1", String.class); } } }}} === ThreadTimer.java === {{{#!highlight java package org.allowed.bitarus.spring.mvc.html; import java.text.MessageFormat; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; public class ThreadTimer extends Thread { private int delaySeconds; private Logger logger; private boolean running; @Autowired TestDAO testDAO; public ThreadTimer(int delaySeconds) { this.logger = Logger.getLogger(ThreadTimer.class); logger.info("Created instance of " + this.getClass().getSimpleName()); this.running = true; this.delaySeconds = delaySeconds; this.setName(this.getClass().getSimpleName() + "_" + this.getName()); } public void run() { while (running) { try { Thread.sleep(this.delaySeconds); logger.info("Delay " + this.getClass().getSimpleName()); if (testDAO != null) { logger.info(MessageFormat.format("{0}", testDAO.getNameFromDummy())); } } catch (InterruptedException e) { logger.info("ThreadTimer interrupted exception:" + e.getMessage() ); } catch (Exception e) { logger.info("ThreadTimer exception:" + e.getMessage() ); stopRunning(); } } logger.info("Exited " + this.getClass().getSimpleName()); } public void startRunning() { this.running = true; } public void stopRunning() { this.running = false; } public void destroy(){ logger.info("Called destroy"); this.stopRunning(); this.interrupt(); } } }}} === ConfigX.java === {{{#!highlight java package org.allowed.bitarus.spring.mvc.html; import java.util.List; import org.apache.log4j.Logger; public class ConfigX { private Logger logger; private List viewList; public ConfigX() { this.logger = Logger.getLogger(ConfigX.class); this.logger.info("Created instance of ConfigX"); } public List getViewList() { return viewList; } public void setViewList(List viewList) { this.viewList = viewList; } } }}} === ContextServletListener.java === {{{#!highlight java package org.allowed.bitarus.spring.mvc.html; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener; import java.sql.Driver; import java.sql.DriverManager; @WebListener public class ContextServletListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce){ System.out.println("ContextServletListener init"); } public void contextDestroyed(ServletContextEvent sce) { //export JAVA_OPTS=-DspringJdbcUrl=jdbc:mariadb://localhost:3306/springmvchtml System.out.println("ContextServletListener destroyed"); try { //Driver mySqlDriver = DriverManager.getDriver("jdbc:mariadb://localhost:3306/springmvchtml"); Driver mySqlDriver = DriverManager.getDriver( System.getProperty("springJdbcUrl") ); DriverManager.deregisterDriver(mySqlDriver); } catch(Exception ex){ System.out.println(ex.getMessage()); } } } }}} === HelloController.java === {{{#!highlight java package org.allowed.bitarus.spring.mvc.html; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.google.gson.Gson; @Controller public class HelloController { protected class JsonObj { private String fieldX; public String getFieldX() { return fieldX; } public void setFieldX(String fieldX) { this.fieldX = fieldX; } } @Autowired @Qualifier("configx") private ConfigX configx; private Logger logger; public HelloController() { this.logger = Logger.getLogger(HelloController.class); logger.info("Created " + this.getClass().getSimpleName()); } @RequestMapping("/helloVal/{name}") public String helloVal(@PathVariable(value = "name") String name, Model model) { // http://localhost:8081/spring-mvc-html-0.1.0/helloVal/asd logger.info("helloVal with " + name); model.addAttribute("name", name); // set data in model return configx.getViewList().get(0); // view JSP } @RequestMapping(value = "/hello", produces = "application/json") @ResponseBody public String hellox(@RequestParam(value = "name", required = false, defaultValue = "World") String name) { // http://localhost:8081/spring-mvc-html-0.1.0/hello?name=asdkkk logger.info("hellox with " + name); JsonObj jo = new JsonObj(); jo.setFieldX(name); return new Gson().toJson(jo); } } }}} === greeting.jsp === {{{#!highlight html Getting Started: Serving Web Content Hello ${name} }}}
Hello ${name}
This part is inside a .container class.
The .container class provides a responsive fixed width container.
Do you want to save changes you made to document before closing?
If you don't save, your changes will be lost.