class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ ### Java - Web # Spring Boot + JHipster ### [Eueung Mulyana](https://github.com/eueung) ### http://eueung.github.io/java/springboot #### Java CodeLabs | [Attribution-ShareAlike CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/) #### ]] ]] --- class: column_t1 middle .fonth3[ .tab1.fullwidth[ | Agenda | |:-------------:| | Spring Boot| | JHipster| ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Spring Boot #1 ### [Spring Boot](http://projects.spring.io/spring-boot/) @ spring.io ]] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ```xml
4.0.0
*
com.example
*
myproject
*
0.0.1-SNAPSHOT
*
org.springframework.boot
spring-boot-starter-parent
1.3.1.RELEASE
*
*
*
org.springframework.boot
*
spring-boot-starter-web
*
``` .center[pom.xml] ]] .column_t1[.vmiddle[ # Example #1 ### Maven ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #1 ]] .column_t2[.vmiddle[ ``` import org.springframework.boot.*; import org.springframework.boot.autoconfigure.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; *@Controller *@EnableAutoConfiguration public class SampleController { * @RequestMapping("/") * @ResponseBody String home() { return "Hello World!"; } public static void main(String[] args) throws Exception { * SpringApplication.run(SampleController.class, args); } } ``` .center[src/main/java/**SampleController.java**] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` import org.springframework.boot.*; import org.springframework.boot.autoconfigure.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*; *@RestController @EnableAutoConfiguration public class Example { @RequestMapping("/") String home() { return "Hello World!"; } public static void main(String[] args) throws Exception { SpringApplication.run(Example.class, args); } } ``` ]] .column_t1[.vmiddle[ # Example #1 ### .yellow[Alternative] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ # Example #1 ### Maven ```bash *$> mvn spring-boot:run ``` ]] .column_t1[.vmiddle[ .figstyle1[  ] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #1 ### .bluelight[Gradle] ```bash $> gradle build *$> gradle bootRun ``` ]] .column_t2[.vmiddle[ ``` *buildscript { ext { springBootVersion = '1.3.1.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } *} apply plugin: 'java' apply plugin: 'spring-boot' jar { baseName = 'demo' version = '0.0.1-SNAPSHOT' } sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { * compile('org.springframework.boot:spring-boot-starter-web') } ``` .center[build.gradle] ]] --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Spring Boot #2 ### [Building an Application with Spring Boot](http://spring.io/guides/gs/spring-boot/) ]] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` *package hello; import java.util.Arrays; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; *@SpringBootApplication public class Application { public static void main(String[] args) { * ApplicationContext ctx = SpringApplication.run(Application.class, args); * System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { * System.out.println(beanName); } } } ``` .center[src/main/java/**hello**/**Application.java**] ]] .column_t1[.vmiddle[ # Example #2 ### gs-spring-boot ``` *package hello; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; *@RestController public class HelloController { * @RequestMapping("/") public String index() { return "Greetings from Spring Boot!"; } } ``` .center[src/main/java/**hello**/**HelloController.java**] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #2 ### Maven ```xml
org.springframework.boot
*
spring-boot-maven-plugin
*
maven-failsafe-plugin
*
integration-test
*
verify
``` .center[pom.xml] ]] .column_t2[.vmiddle[ ```xml
4.0.0
org.springframework
gs-spring-boot
0.1.0
*
org.springframework.boot
*
spring-boot-starter-parent
1.3.1.RELEASE
*
*
org.springframework.boot
*
spring-boot-starter-web
org.springframework.boot
*
spring-boot-starter-actuator
org.springframework.boot
*
spring-boot-starter-test
test
*
1.8
*
...
``` ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ```bash *$> mvn package && java -jar target/gs-spring-boot-0.1.0.jar ... Let's inspect the beans provided by Spring Boot: application ... viewControllerHandlerMapping *$> curl localhost:8080 Greetings from Spring Boot! ``` .figstyle1[  ] ]] .column_t1[.vmiddle[ # Example #2 ### Maven #### ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #2 ### .bluelight[Gradle] ```bash *$> gradle wrapper *$> ./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar ``` ]] .column_t2[.vmiddle[ ``` buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE") } } apply plugin: 'java' apply plugin: 'spring-boot' jar { baseName = 'gs-spring-boot' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { compile("org.springframework.boot:spring-boot-starter-web") * compile("org.springframework.boot:spring-boot-starter-actuator") * testCompile("org.springframework.boot:spring-boot-starter-test") } *task wrapper(type: Wrapper) { * gradleVersion = '2.10' *} ``` ]] --- class: split-50 nopadding .column_t2[.vmiddle[ # Example #2 ### Unit Tests ``` package hello; import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.mock.web.MockServletContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; ``` ]] .column_t1[.vmiddle[ ``` @RunWith(SpringJUnit4ClassRunner.class) *@SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration public class HelloControllerTest { * private MockMvc mvc; @Before public void setUp() throws Exception { * mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); } @Test public void getHello() throws Exception { * mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)) * .andExpect(status().isOk()) * .andExpect(content().string(equalTo("Greetings from Spring Boot!"))); } } ``` .center[src/**test**/java/hello/**HelloControllerTest.java**] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #2 ### Integration Test ``` package hello; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import java.net.URL; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.TestRestTemplate; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.client.RestTemplate; ``` ]] .column_t2[.vmiddle[ ``` @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration *@IntegrationTest({"server.port=0"}) public class HelloControllerIT { * @Value("${local.server.port}") private int port; * private URL base; * private RestTemplate template; @Before public void setUp() throws Exception { * this.base = new URL("http://localhost:" + port + "/"); * template = new TestRestTemplate(); } @Test public void getHello() throws Exception { * ResponseEntity
response = template.getForEntity(base.toString(), String.class); * assertThat(response.getBody(), equalTo("Greetings from Spring Boot!")); } } ``` .center[src/**test**/java/hello/**HelloControllerIT.java**] ]] --- class: column_t1 # Refs/Notes 1. [Getting Started · Building an Application with Spring Boot](http://spring.io/guides/gs/spring-boot/) 1. [spring-guides/gs-spring-boot](https://github.com/spring-guides/gs-spring-boot) --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # Spring Boot #3 ### [Building a RESTful Web Service](http://spring.io/guides/gs/rest-service/) ]] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` 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, %s!"; private final AtomicLong counter = new AtomicLong(); * @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } } ``` .center[src/**main**/java/hello/**GreetingController.java**] ]] .column_t1[.vmiddle[ # Example #3 ### gs-rest-service ``` 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; } } ``` .center[src/**main**/java/hello/**Greeting.java**] ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #3 #### .figstyle1[  ] .figstyle1[  ] ]] .column_t2[.vmiddle[ ``` package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; *@SpringBootApplication public class Application { public static void main(String[] args) { * SpringApplication.run(Application.class, args); } } ``` .center[src/**main**/java/hello/**Application.java**] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ```xml
4.0.0
org.springframework
gs-rest-service
0.1.0
org.springframework.boot
*
spring-boot-starter-parent
1.3.1.RELEASE
org.springframework.boot
*
spring-boot-starter-web
1.8
*
...
*
...
*
...
``` .center[**pom.xml**] ]] .column_t1[.vmiddle[ # Example #3 ### Maven ```xml *
org.springframework.boot
*
spring-boot-maven-plugin
*
*
spring-releases
https://repo.spring.io/libs-release
*
*
spring-releases
https://repo.spring.io/libs-release
*
``` ]] --- class: split-50 nopadding .column_t1[.vmiddle[ # Example #3 ### Maven ```bash *$> mvn clean package $> java -jar target/gs-rest-service-0.1.0.jar # or *$> mvn spring-boot:run ``` ]] .column_t2[.vmiddle[ ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ``` buildscript { repositories { mavenCentral() } dependencies { * classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE") } } apply plugin: 'java' apply plugin: 'spring-boot' jar { baseName = 'gs-rest-service' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { * compile("org.springframework.boot:spring-boot-starter-web") testCompile("junit:junit") } task wrapper(type: Wrapper) { gradleVersion = '2.10' } ``` .center[**build.gradle**] ]] .column_t1[.vmiddle[ # Example #3 ### .bluelight[Gradle] ```bash *$> gradle build *$> java -jar build/libs/gs-rest-service-0.1.0.jar # or local $> gradle wrapper $> gradlew build $> java -jar build/libs/gs-rest-service-0.1.0.jar ``` ]] --- class: column_t1 # Refs/Notes 1. [Getting Started · Building a RESTful Web Service](http://spring.io/guides/gs/rest-service/) 1. [spring-guides/gs-rest-service](https://github.com/spring-guides/gs-rest-service) --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # JHipster ### [JHipster](http://jhipster.github.io/) Yeoman Generator ]] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ ```bash *$> yo jhipster ``` .figstyle1[  ] ]] .column_t1[.vmiddle[ # Example #4 ### Scaffolding via JHipster ```bash npm install -g yo npm install -g bower npm install -g grunt-cli *npm install -g generator-jhipster ``` ]] --- class: split-50 nopadding .column_t1[.vmiddle[ ## Notes ### For Win7 x64 Machine #### Only with Stock MSVS 2013 Community Version ```bash *npm install node-gyp -g # perhaps unnecessary *npm config set msvs_version 2013 --global npm get msvs_version npm config list ``` ``` set PYTHON=f:\prog\py27\python.exe *set GYP_MSVS_VERSION=2013 ``` .center[nodevars] ]] .column_t2[.vmiddle[ ``` { ... * 'target_defaults': { ... * 'configurations': { ... * 'Release': { * 'conditions': | |'target_arch=="x64"', { 'msvs_configuration_platform': 'x64', * 'msbuild_toolset': 'v120_xp' }|, } } } } ``` .center[~/.node-gyp/5.2.0/include/node/**common.gypi**] .center[ Ref: [NPM native builds ... @ Stack Overflow](http://stackoverflow.com/questions/20051318/npm-native-builds-with-only-visual-studio-2013-installed) ] ]] --- class: split-50 nopadding .column_t2[.vmiddle[ .figstyle1[  ] ]] .column_t1[.vmiddle[ # Example #4 ### Maven ```bash # if something wrong happens npm install && bower install # equivalent for mvn spring-boot:run *$> mvn # localhost:8080 ``` ]] --- class: column_t1 middle .figstyle1[  ] .center[Sign-In | Public] --- class: column_t1 middle .figstyle1[  ] .center[Landing | User: admin] --- class: column_t1 middle .figstyle1[  ] .center[User Management] --- class: column_t1 middle .figstyle1[  ] .center[Metrics] --- class: column_t1 middle .figstyle1[  ] .center[Configuration] --- class: column_t1 middle .figstyle1[  ] .center[API] --- class: split-70 nopadding .column_t1[.vmiddle[ .figstyle1[  ] ]] .column_t2[.vmiddle[ ## Database (H2) ]] --- # References 1. [Spring Boot](http://projects.spring.io/spring-boot/) 1. [Spring Guides](https://github.com/spring-guides) 1. [spring-boot/spring-boot-samples](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples) 1. [Getting Started · Building Java Projects with **Maven**](http://spring.io/guides/gs/maven/) 1. [Getting Started · Building Java Projects with **Gradle**](http://spring.io/guides/gs/gradle/) 1. [The JHipster Mini-Book - infoq](http://www.infoq.com/minibooks/jhipster-mini-book) 1. [The JHipster Mini-Book - Site](http://www.jhipster-book.com/) 1. [Starting a modern Java project with JHipster](https://www.drissamri.be/blog/technology/starting-modern-java-project-with-jhipster/) 1. [Getting Started with JHipster, AngularJS and Paymill](http://www.indivon.de/blog/getting-started-jhipster-spring-boot-angularjs-paymill/) --- class: split-30 nopadding background-image: url(https://cloud.githubusercontent.com/assets/4231611/11022953/9d608066-869e-11e5-846e-d6a8febc17dd.jpg) .column_t2.center[.vmiddle[ .fgtransparent[ # .fa-2x[
] ] ]] .column_t2[.vmiddle.nopadding[ .shadelight[.boxtitle1[ # END ### [Eueung Mulyana](https://github.com/eueung) ### http://eueung.github.io/java/springboot #### Java CodeLabs | [Attribution-ShareAlike CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0/) #### ]] ]]