Spring Boot and RESTful API(1)Prepare ENV and Web Layer
SpringBootandRESTfulAPI(1)PrepareENVandWebLayer
Followthisdocument
https://spring.io/guides/gs/actuator-service/
https://spring.io/guides/gs/consuming-rest-restjs/
SomeInformationEndpoint
http://localhost:8080/application/health
http://localhost:8080/application/info
http://localhost:8080/application/metrics
http://localhost:8080/application/trace
http://localhost:8080/api/books/1
ListoftheSQL
http://localhost:8080/application/flyway
ConsoleofH2
http://localhost:8080/h2-console
MavenFlywayPlugin
https://flywaydb.org/getstarted/firststeps/maven
http://qinghua.github.io/flyway/
webfluxcassandra
https://github.com/bijukunjummen/sample-webflux-annot-cassandra
https://dzone.com/articles/spring-webflux-first-steps
PreparetheENVgradle
http://wiki.jikexueyuan.com/project/gradle/java-quickstart.html
installgradle
https://gradle.org/install#manually
IchosetoInstallthatmanually
>wgethttps://downloads.gradle.org/distributions/gradle-3.5-bin.zip
DirectlyUnzipthefileandplaceintheworkingarea,addthebintothePATH
>gradle--version
------------------------------------------------------------
Gradle3.5
------------------------------------------------------------
Buildtime:2017-04-1013:37:25UTC
Revision:b762622a185d59ce0cfc9cbc6ab5dd22469e18a6
Groovy:2.4.10
Ant:ApacheAnt(TM)version1.9.6compiledonJune292015
JVM:1.8.0_121(OracleCorporation25.121-b13)
OS:MacOSX10.12.5x86_64
>gradlebuild
ReactorIntroduction
https://www.ibm.com/developerworks/cn/java/j-cn-with-reactor-response-encode/index.html
Flux-0-Nsequenceofitems.sequenceofitems,sequenceendsandsequenceerror.
Ifmessageproduce,subscribewillbecalledwiththesemethodsonNext(),onComplete(),onError()
Mono-0-1Ifweput2MonoSequencetogether,thatisFlux.
CreateFluxStaticMethod
just()
fromArray()
fromInterable()
fromStream
empty()
error(Throwableerror)
CreateMonoStaticMethod
just()
empty()
error()
ImportantOperation
filter
Flux.range(1,10).filter(i->i%2==0).subscribe(System.out::println);
window-buffer
Flux.range(1,100).window(20).subscribe(System.out::println):
Flux.intervalMillis(100).windowMillis(1001).take(2).toStream().forEach(System.out::println);
zipWithtakereducereduceWithmergemergeSequentialflatMapflatMapSequentialconcatMapcombineLatest
Inputer1——event—>ServiceHandler—>Dispatch—>RequestHandler1
—>Dispatch—>RequestHandler2
Inputer2——event—>—>Dispatch—>RequestHandler3
SetUptheWebFluxonHTTPRESTLayer
WecanhavereactorintheDAOlayeraswellbythesupportingfromlatestspring.Butitisfine.Itiseasytousethatonlyontopofthecontrollerlayer.
Mypom.xmlisasfollow:
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.j2c</groupId>
<artifactId>jobs-monitor-api</artifactId>
<version>1.0.0</version>
<name>JobsMonitorAPI</name>
<description>springboot/cassandra/solr/webflux</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M1</version>
<relativePath/><!--lookupparentfromrepository-->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--spring-boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--tools-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--Test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
ApplicationClasstostarttheWebJobsMonitorAPIApplication.java
packagecom.sillycat.jobsmonitorapi;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
publicclassJobsMonitorAPIApplication{
publicstaticvoidmain(String[]args)throwsException{
SpringApplication.run(JobsMonitorAPIApplication.class);
}
}
SampleControllerJobsController.java
packagecom.sillycat.jobsmonitorapi.web;
importjava.util.ArrayList;
importjava.util.List;
importorg.springframework.http.HttpStatus;
importorg.springframework.http.ResponseEntity;
importorg.springframework.web.bind.annotation.DeleteMapping;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.PathVariable;
importorg.springframework.web.bind.annotation.PostMapping;
importorg.springframework.web.bind.annotation.PutMapping;
importorg.springframework.web.bind.annotation.RequestBody;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;
importcom.j2c.jobsmonitorapi.dto.JobDto;
importreactor.core.publisher.Flux;
importreactor.core.publisher.Mono;
@RestController
@RequestMapping("/api1.0/jobs")
publicclassJobController{
@GetMapping(path="/{id}",produces=MediaTypes.JSON_UTF_8)
publicMono<JobDto>get(@PathVariable("id")Longid){
JobDtodto=newJobDto();
dto.id=1l;
dto.description="java,scala,python,groovy,golang";
dto.status="LIVE";
dto.title="fullstack";
dto.url="sillycat.ddns.net";
returnMono.just(dto);
}
@PostMapping(produces=MediaTypes.JSON_UTF_8)
publicMono<ResponseEntity<JobDto>>save(@RequestBodyJobDtodto){
returnMono.just(newResponseEntity<>(dto,HttpStatus.CREATED));
}
@PutMapping(path="/{id}",produces=MediaTypes.JSON_UTF_8)
publicMono<ResponseEntity<JobDto>>update(@PathVariable("id")Longid,@RequestBodyJobDtodto){
if(id==0){
returnMono.just(newResponseEntity<>(HttpStatus.NOT_FOUND));
}else{
returnMono.just(newResponseEntity<>(dto,HttpStatus.CREATED));
}
}
@DeleteMapping(path="/{id}",produces=MediaTypes.JSON_UTF_8)
publicMono<ResponseEntity<String>>delete(@PathVariable("id")Longid){
returnMono.just(newResponseEntity<>(HttpStatus.ACCEPTED));
}
@GetMapping(produces=MediaTypes.JSON_UTF_8)
publicFlux<JobDto>load(){
JobDtodto1=newJobDto();
dto1.id=1l;
dto1.description="java,scala,python,groovy,golang";
dto1.status="LIVE";
dto1.title="fullstack";
dto1.url="sillycat.ddns.net";
JobDtodto2=newJobDto();
dto2.id=2l;
dto2.description="java,scala,python,groovy,golang";
dto2.status="LIVE";
dto2.title="fullstack";
dto2.url="sillycat.ddns.net";
List<JobDto>list=newArrayList<JobDto>();
list.add(dto1);
list.add(dto2);
//returnFlux.just(list.toArray(newJobDto[list.size()]));
returnFlux.fromArray(list.toArray(newJobDto[list.size()]));
}
}
References:
http://docs.spring.io/spring-boot/docs/1.5.2.RELEASE/reference/htmlsingle/#getting-started-first-application
bunchofsamples
https://github.com/spring-projects/spring-boot/tree/v2.0.0.M1/spring-boot-samples
beanmapping
http://orika-mapper.github.io/orika-docs/intro.html
pomversion
https://github.com/spring-projects/spring-boot/blob/d21a5076feb1ba24da3a6e2a0c72c8003cf3701f/spring-boot-dependencies/pom.xml
https://github.com/springside/springside4/wiki/Tutorial