Repository: JeffLi1993/springboot-learning-example Branch: master Commit: 077329583043 Files: 312 Total size: 312.8 KB Directory structure: gitextract_8i_wvbh2/ ├── .gitignore ├── 2-x-spring-boot-groovy/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── filter/ │ │ │ └── RouteRuleFilter.java │ │ └── web/ │ │ └── GroovyScriptController.java │ └── resources/ │ └── application.properties ├── 2-x-spring-boot-webflux-handling-errors/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── error/ │ │ │ ├── GlobalErrorAttributes.java │ │ │ ├── GlobalErrorWebExceptionHandler.java │ │ │ └── GlobalException.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── router/ │ │ └── CityRouter.java │ └── resources/ │ └── application.properties ├── LICENSE ├── README.md ├── chapter-1-spring-boot-quickstart/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── demo/ │ │ │ └── springboot/ │ │ │ ├── QuickStartApplication.java │ │ │ └── web/ │ │ │ ├── HelloBookController.java │ │ │ └── HelloController.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ ├── java/ │ │ └── demo/ │ │ └── springboot/ │ │ └── QuickStartApplicationTests.java │ └── resources/ │ └── application.properties ├── chapter-2-spring-boot-config/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── demo/ │ │ │ └── springboot/ │ │ │ ├── ConfigApplication.java │ │ │ ├── config/ │ │ │ │ ├── BookComponent.java │ │ │ │ └── BookProperties.java │ │ │ └── web/ │ │ │ └── HelloBookController.java │ │ └── resources/ │ │ ├── application-dev.properties │ │ ├── application-prod.properties │ │ ├── application.properties │ │ └── application.yml │ └── test/ │ └── java/ │ └── demo/ │ └── springboot/ │ └── ConfigApplicationTests.java ├── chapter-3-spring-boot-web/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── demo/ │ │ │ └── springboot/ │ │ │ ├── WebApplication.java │ │ │ ├── domain/ │ │ │ │ └── Book.java │ │ │ ├── service/ │ │ │ │ ├── BookService.java │ │ │ │ └── impl/ │ │ │ │ └── BookServiceImpl.java │ │ │ └── web/ │ │ │ └── BookController.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ ├── java/ │ │ └── demo/ │ │ └── springboot/ │ │ ├── WebApplicationTests.java │ │ └── web/ │ │ └── BookControllerTest.java │ └── resources/ │ └── application.properties ├── chapter-4-spring-boot-validating-form-input/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── spring/ │ │ │ └── boot/ │ │ │ └── core/ │ │ │ ├── ValidatingFormInputApplication.java │ │ │ ├── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ ├── service/ │ │ │ │ ├── UserService.java │ │ │ │ └── impl/ │ │ │ │ └── UserServiceImpl.java │ │ │ └── web/ │ │ │ └── UserController.java │ │ └── resources/ │ │ ├── application.properties │ │ ├── static/ │ │ │ └── css/ │ │ │ └── default.css │ │ └── templates/ │ │ ├── userForm.html │ │ └── userList.html │ └── test/ │ ├── java/ │ │ └── spring/ │ │ └── boot/ │ │ └── core/ │ │ ├── ValidatingFormInputApplicationTests.java │ │ └── web/ │ │ └── UserControllerTest.java │ └── resources/ │ ├── application.properties │ ├── static/ │ │ └── css/ │ │ └── default.css │ └── templates/ │ ├── userForm.html │ └── userList.html ├── chapter-4-spring-boot-web-thymeleaf/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── demo/ │ │ │ └── springboot/ │ │ │ ├── WebApplication.java │ │ │ ├── domain/ │ │ │ │ └── Book.java │ │ │ ├── service/ │ │ │ │ ├── BookService.java │ │ │ │ └── impl/ │ │ │ │ └── BookServiceImpl.java │ │ │ └── web/ │ │ │ └── BookController.java │ │ └── resources/ │ │ ├── application.properties │ │ ├── static/ │ │ │ └── css/ │ │ │ └── default.css │ │ └── templates/ │ │ ├── bookForm.html │ │ └── bookList.html │ └── test/ │ └── java/ │ └── demo/ │ └── springboot/ │ └── WebApplicationTests.java ├── chapter-5-spring-boot-data-jpa/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── demo/ │ │ │ └── springboot/ │ │ │ ├── WebApplication.java │ │ │ ├── domain/ │ │ │ │ ├── Book.java │ │ │ │ └── BookRepository.java │ │ │ ├── service/ │ │ │ │ ├── BookService.java │ │ │ │ └── impl/ │ │ │ │ └── BookServiceImpl.java │ │ │ └── web/ │ │ │ └── BookController.java │ │ └── resources/ │ │ ├── application.properties │ │ ├── static/ │ │ │ └── css/ │ │ │ └── default.css │ │ └── templates/ │ │ ├── bookForm.html │ │ └── bookList.html │ └── test/ │ └── java/ │ └── demo/ │ └── springboot/ │ └── WebApplicationTests.java ├── chapter-5-spring-boot-paging-sorting/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── spring/ │ │ │ └── boot/ │ │ │ └── core/ │ │ │ ├── PagingSortingApplication.java │ │ │ ├── domain/ │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ ├── service/ │ │ │ │ ├── UserService.java │ │ │ │ └── impl/ │ │ │ │ └── UserServiceImpl.java │ │ │ └── web/ │ │ │ └── UserController.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ └── java/ │ └── spring/ │ └── boot/ │ └── core/ │ └── PagingSortingApplicationTests.java ├── pom.xml ├── spring-data-elasticsearch-crud/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── repository/ │ │ │ └── CityRepository.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityESServiceImpl.java │ └── resources/ │ └── application.properties ├── spring-data-elasticsearch-query/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── repository/ │ │ │ └── CityRepository.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityESServiceImpl.java │ └── resources/ │ └── application.properties ├── springboot-configuration/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ └── config/ │ │ └── MessageConfiguration.java │ └── test/ │ └── java/ │ └── org/ │ └── spring/ │ └── springboot/ │ └── config/ │ └── MessageConfigurationTest.java ├── springboot-dubbo-client/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── ClientApplication.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── dubbo/ │ │ ├── CityDubboConsumerService.java │ │ └── CityDubboService.java │ └── resources/ │ └── application.properties ├── springboot-dubbo-server/ │ ├── DubboProperties.md │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── ServerApplication.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── dubbo/ │ │ ├── CityDubboService.java │ │ └── impl/ │ │ └── CityDubboServiceImpl.java │ └── resources/ │ └── application.properties ├── springboot-elasticsearch/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── repository/ │ │ │ └── CityRepository.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityESServiceImpl.java │ └── resources/ │ └── application.properties ├── springboot-freemarker/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityController.java │ │ ├── dao/ │ │ │ └── CityDao.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ ├── application.properties │ ├── mapper/ │ │ └── CityMapper.xml │ └── web/ │ ├── city.ftl │ └── cityList.ftl ├── springboot-hbase/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── dao/ │ │ │ └── CityRowMapper.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ └── application.properties ├── springboot-helloworld/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ └── web/ │ │ └── HelloWorldController.java │ └── test/ │ └── java/ │ └── org/ │ └── spring/ │ └── springboot/ │ └── web/ │ └── HelloWorldControllerTest.java ├── springboot-mybatis/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── dao/ │ │ │ └── CityDao.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ ├── application.properties │ └── mapper/ │ └── CityMapper.xml ├── springboot-mybatis-annotation/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── dao/ │ │ │ └── CityDao.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ └── application.properties ├── springboot-mybatis-mutil-datasource/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── config/ │ │ │ └── ds/ │ │ │ ├── ClusterDataSourceConfig.java │ │ │ └── MasterDataSourceConfig.java │ │ ├── controller/ │ │ │ └── UserRestController.java │ │ ├── dao/ │ │ │ ├── cluster/ │ │ │ │ └── CityDao.java │ │ │ └── master/ │ │ │ └── UserDao.java │ │ ├── domain/ │ │ │ ├── City.java │ │ │ └── User.java │ │ └── service/ │ │ ├── UserService.java │ │ └── impl/ │ │ └── UserServiceImpl.java │ └── resources/ │ ├── application.properties │ └── mapper/ │ ├── cluster/ │ │ └── CityMapper.xml │ └── master/ │ └── UserMapper.xml ├── springboot-mybatis-redis/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── dao/ │ │ │ └── CityDao.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ ├── application.properties │ └── mapper/ │ └── CityMapper.xml ├── springboot-mybatis-redis-annotation/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── spring/ │ │ │ └── springboot/ │ │ │ ├── Application.java │ │ │ ├── domain/ │ │ │ │ └── City.java │ │ │ └── service/ │ │ │ ├── CityService.java │ │ │ └── impl/ │ │ │ └── CityServiceImpl.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ └── org/ │ └── spring/ │ └── springboot/ │ └── ApplicationTests.java ├── springboot-properties/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── spring/ │ │ │ └── springboot/ │ │ │ ├── Application.java │ │ │ ├── property/ │ │ │ │ ├── HomeProperties.java │ │ │ │ └── UserProperties.java │ │ │ └── web/ │ │ │ └── HelloWorldController.java │ │ └── resources/ │ │ ├── application-dev.properties │ │ ├── application-prod.properties │ │ └── application.properties │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── property/ │ │ │ ├── HomeProperties1.java │ │ │ └── PropertiesTest.java │ │ └── web/ │ │ └── HelloWorldControllerTest.java │ └── resouorces/ │ └── application.yml ├── springboot-restful/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── controller/ │ │ │ └── CityRestController.java │ │ ├── dao/ │ │ │ └── CityDao.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── service/ │ │ ├── CityService.java │ │ └── impl/ │ │ └── CityServiceImpl.java │ └── resources/ │ ├── application.properties │ └── mapper/ │ └── CityMapper.xml ├── springboot-validation-over-json/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── constant/ │ │ │ └── CityErrorInfoEnum.java │ │ ├── result/ │ │ │ ├── ErrorInfoInterface.java │ │ │ ├── GlobalErrorInfoEnum.java │ │ │ ├── GlobalErrorInfoException.java │ │ │ ├── GlobalErrorInfoHandler.java │ │ │ └── ResultBody.java │ │ └── web/ │ │ ├── City.java │ │ └── ErrorJsonController.java │ └── test/ │ └── java/ │ └── org/ │ └── spring/ │ └── springboot/ │ └── web/ │ └── ErrorJsonControllerTest.java ├── springboot-webflux-1-quickstart/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── router/ │ │ └── CityRouter.java │ └── resources/ │ └── application.properties ├── springboot-webflux-10-book-manage-sys/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── demo/ │ │ └── springboot/ │ │ ├── WebApplication.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── service/ │ │ │ ├── CityService.java │ │ │ └── impl/ │ │ │ └── CityServiceImpl.java │ │ └── web/ │ │ └── CityController.java │ └── resources/ │ ├── application.properties │ ├── static/ │ │ └── css/ │ │ └── default.css │ └── templates/ │ ├── cityForm.html │ └── cityList.html ├── springboot-webflux-2-restful/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ └── application.properties ├── springboot-webflux-3-mongodb/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ └── application.properties ├── springboot-webflux-4-thymeleaf/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ ├── application.properties │ └── templates/ │ ├── cityList.html │ └── hello.html ├── springboot-webflux-5-thymeleaf-mongodb/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ ├── application.properties │ └── templates/ │ ├── city.html │ └── cityList.html ├── springboot-webflux-6-redis/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── domain/ │ │ │ └── City.java │ │ └── webflux/ │ │ └── controller/ │ │ ├── CityWebFluxController.java │ │ └── CityWebFluxReactiveController.java │ └── resources/ │ └── application.properties ├── springboot-webflux-7-redis-cache/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ └── application.properties ├── springboot-webflux-8-websocket/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── spring/ │ │ │ └── springboot/ │ │ │ ├── Application.java │ │ │ ├── config/ │ │ │ │ └── WebSocketConfiguration.java │ │ │ └── handler/ │ │ │ └── EchoHandler.java │ │ └── resources/ │ │ ├── application.properties │ │ └── websocket-client.html │ └── test/ │ └── java/ │ └── WSClient.java └── springboot-webflux-9-test/ ├── pom.xml └── src/ ├── main/ │ ├── java/ │ │ └── org/ │ │ └── spring/ │ │ └── springboot/ │ │ ├── Application.java │ │ ├── dao/ │ │ │ └── CityRepository.java │ │ ├── domain/ │ │ │ └── City.java │ │ ├── handler/ │ │ │ └── CityHandler.java │ │ └── webflux/ │ │ └── controller/ │ │ └── CityWebFluxController.java │ └── resources/ │ └── application.properties └── test/ └── java/ └── org/ └── spring/ └── springboot/ └── handler/ └── CityHandlerTest.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.class # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.ear # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ### NetBeans ### nbproject/private/ build/ nbbuild/ dist/ nbdist/ .nb-gradle/ ================================================ FILE: 2-x-spring-boot-groovy/pom.xml ================================================ 4.0.0 springboot 2-x-spring-boot-groovy 0.0.1-SNAPSHOT 2-x-spring-boot-groovy org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.codehaus.groovy groovy org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2-x-spring-boot-groovy/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: 2-x-spring-boot-groovy/src/main/java/org/spring/springboot/filter/RouteRuleFilter.java ================================================ package org.spring.springboot.filter; import groovy.lang.Binding; import groovy.lang.GroovyShell; import groovy.lang.Script; import org.springframework.stereotype.Component; import java.util.Map; @Component public class RouteRuleFilter { public Map filter(Map input) { Binding binding = new Binding(); binding.setVariable("input", input); GroovyShell shell = new GroovyShell(binding); String filterScript = "def field = input.get('field')\n" + "if (input.field == 'buyer') { return ['losDataBusinessName':'losESDataBusiness3', 'esIndex':'potential_goods_recommend1']}\n" + "if (input.field == 'seller') { return ['losDataBusinessName':'losESDataBusiness4', 'esIndex':'potential_goods_recommend2']}\n"; Script script = shell.parse(filterScript); Object ret = script.run(); System.out.println(ret); return (Map) ret; } } ================================================ FILE: 2-x-spring-boot-groovy/src/main/java/org/spring/springboot/web/GroovyScriptController.java ================================================ package org.spring.springboot.web; import org.spring.springboot.filter.RouteRuleFilter; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/groovy/script") public class GroovyScriptController { @RequestMapping(value = "/filter", method = RequestMethod.GET) public String filter() { RouteRuleFilter routeRuleFilter = new RouteRuleFilter(); Map input = new HashMap<>(); input.put("field", "seller"); Map output = routeRuleFilter.filter(input); return "true"; } public static void main(String[] args) { GroovyScriptController groovyScriptController = new GroovyScriptController(); groovyScriptController.filter(); } } ================================================ FILE: 2-x-spring-boot-groovy/src/main/resources/application.properties ================================================ ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/pom.xml ================================================ 4.0.0 springboot 2-x-spring-boot-webflux-handling-errors 0.0.1-SNAPSHOT 2-x-spring-boot-webflux-handling-errors org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-test test io.projectreactor reactor-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorAttributes.java ================================================ package org.spring.springboot.error; import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.server.ServerRequest; import java.util.Map; @Component public class GlobalErrorAttributes extends DefaultErrorAttributes { @Override public Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { Map map = super.getErrorAttributes(request, includeStackTrace); if (getError(request) instanceof GlobalException) { GlobalException ex = (GlobalException) getError(request); map.put("exception", ex.getClass().getSimpleName()); map.put("message", ex.getMessage()); map.put("status", ex.getStatus().value()); map.put("error", ex.getStatus().getReasonPhrase()); return map; } map.put("exception", "SystemException"); map.put("message", "System Error , Check logs!"); map.put("status", "500"); map.put("error", " System Error "); return map; } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalErrorWebExceptionHandler.java ================================================ package org.spring.springboot.error; import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; import org.springframework.boot.web.reactive.error.ErrorAttributes; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; import java.util.Map; @Component @Order(-2) public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) { super(g, new ResourceProperties(), applicationContext); super.setMessageWriters(serverCodecConfigurer.getWriters()); super.setMessageReaders(serverCodecConfigurer.getReaders()); } @Override protected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) { return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); } private Mono renderErrorResponse(final ServerRequest request) { final Map errorPropertiesMap = getErrorAttributes(request, false); return ServerResponse.status(HttpStatus.BAD_REQUEST) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(errorPropertiesMap)); } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/error/GlobalException.java ================================================ package org.spring.springboot.error; import org.springframework.http.HttpStatus; import org.springframework.web.server.ResponseStatusException; public class GlobalException extends ResponseStatusException { public GlobalException(HttpStatus status, String message) { super(status, message); } public GlobalException(HttpStatus status, String message, Throwable e) { super(status, message, e); } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.error.GlobalException; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; import java.util.Optional; @Component public class CityHandler { public Mono helloCity(ServerRequest request) { return ServerResponse.ok().body(sayHelloCity(request), String.class); } private Mono sayHelloCity(ServerRequest request) { Optional cityParamOptional = request.queryParam("city"); if (!cityParamOptional.isPresent()) { throw new GlobalException(HttpStatus.INTERNAL_SERVER_ERROR, "request param city is ERROR"); } return Mono.just("Hello," + cityParamOptional.get()); } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/java/org/spring/springboot/router/CityRouter.java ================================================ package org.spring.springboot.router; import org.spring.springboot.handler.CityHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; @Configuration public class CityRouter { @Bean public RouterFunction routeCity(CityHandler cityHandler) { return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity); } } ================================================ FILE: 2-x-spring-boot-webflux-handling-errors/src/main/resources/application.properties ================================================ ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ [![Star History Chart](https://api.star-history.com/svg?repos=JeffLi1993/springboot-learning-example&type=Date)](https://star-history.com/#JeffLi1993/springboot-learning-example&Date) ### 一、支持泥瓦匠 关注泥瓦匠个人博客的更新:[我的博客](https://www.bysocket.com "我的博客") - 分享学习可落地的技术博文 **Spring Boot 2.x 系列教程**,spring boot 实践学习案例,是初学者及核心技术巩固的最佳实践。 1. 拿起微信,关注公众号:「程序员泥瓦匠 」 2. 给教程的开源代码仓库点个 **Star** 吧 - [GitHub(springboot-learning-example)](https://github.com/JeffLi1993/springboot-learning-example "GitHub(springboot-learning-example)") - [Gitee(springboot-learning-example)](https://gitee.com/jeff1993/springboot-learning-example "Gitee(springboot-learning-example)") 3. 帮忙分享该系列文章链接给更多的朋友 ### 二、系列文章目录 #### 『 Spring Boot 2 快速教程 』 - [Spring Boot 2 快速教程:WebFlux 集成 Thymeleaf(五)](https://www.bysocket.com/springboot/2358.html) - [Spring Boot 2 快速教程:WebFlux 集成 Mongodb(四)](https://www.bysocket.com/springboot/2342.html) - [Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)](https://www.bysocket.com/technique/2328.html) - [Spring Boot 2 快速教程:WebFlux 快速入门(二)](https://www.bysocket.com/technique/2306.html) - [Spring Boot 2 快速教程:WebFlux REST API 全局异常处理 Error Handling](https://www.bysocket.com/technique/2272.html) - [Spring Boot 2 快速教程:WebFlux 系列教程大纲(一)](https://www.bysocket.com/technique/2290.html) #### 『 基础 - 入门篇 』 - [Spring Boot 2.0 配置图文教程](https://www.bysocket.com/technique/2135.html) - [Spring Boot 2.0 的快速入门(图文教程)](https://www.bysocket.com/technique/2119.html) - [Spring Boot 之 HelloWorld 详解](http://www.bysocket.com/?p=1124) - [Spring Boot 之配置文件详解](http://www.bysocket.com/?p=1786) #### 『 基础 - Web 业务开发篇 』 - [Spring Boot Web 开发注解篇](http://www.bysocket.com/?p=1929) - [Spring Boot 表单验证篇](http://www.bysocket.com/?p=1942) - [Spring Boot 2.x 小新功能 – Spring Data Web configuration](http://www.bysocket.com/?p=1950) - [Spring Boot 实现 Restful 服务,基于 HTTP / JSON 传输](http://www.bysocket.com/?p=1627) - [Spring Boot 之 RESRful API 权限控制](http://www.bysocket.com/?p=1080) - [Spring Boot 集成 FreeMarker](http://www.bysocket.com/?p=1666) - [Spring Boot HTTP over JSON 的错误码异常处理](http://www.bysocket.com/?p=1692) - Spring Boot 使用 Swagger2 构建 RESRful API 文档 - Spring Boot 集成 JSP - Spring Boot 集成 Thymeleaf - Spring Boot 单元测试的使用 - Spring Boot 热更新部署 #### 『 基础 – 数据存储篇 』 - [Spring Boot 整合 Mybatis 的完整 Web 案例](http://www.bysocket.com/?p=1610) - [Spring Boot 整合 Mybatis Annotation 注解案例](http://www.bysocket.com/?p=1811) - [Spring Boot 整合 Mybatis 实现 Druid 多数据源配置](http://www.bysocket.com/?p=1712) - Spring Boot 整合使用 JdbcTemplate - Spring Boot 整合 Spring-data-jpa - Spring Boot 声明式事务管理 #### 『 基础 – 数据缓存篇 』 - [Spring Boot 整合 Redis 实现缓存操作](http://www.bysocket.com/?p=1756) - Spring Boot 整合 Redis Annotation 实现缓存操作 - Spring Boot 整合 MongoDB 实现缓存操作 - Spring Boot 整合 EhCache 实现缓存操作 #### 『 基础 – 日志管理篇 』 - Spring Boot 默认日志 logback 配置解析 - Spring Boot 使用 log4j 记录日志 - Spring Boot 对 log4j 进行多环境不同日志级别的控制 - Spring Boot 使用 log4j 记录日志到 MongoDB - Spring Boot 1.5.x 动态修改日志级别 #### 『 基础 – 应用篇 』 - Spring Boot Actuator 监控 - Spring Boot Web 应用部署 #### 『 提升 – 安全控制及权限篇 』 - Spring Boot 整合 Spring Security - Spring Boot 整合 Shiro - Spring Boot 整合 Spring Session #### 『 提升 – 中间件篇 』 - [Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase](https://www.bysocket.com/technique/2162.html) - Spring Boot 整合 RabbitMQ - Spring Boot 整合 Quartz #### 『 提升 – 源码篇 』 - Spring Boot 启动原理解析 #### 『 Elasticsearch 篇 』 - [Spring Boot 整合 Elasticsearch](http://www.bysocket.com/?p=1829) - [深入浅出 spring-data-elasticsearch 之 ElasticSearch 架构初探(一)](http://www.bysocket.com/?p=1889) - [深入浅出 spring-data-elasticsearch 系列 – 概述及入门(二)](http://www.bysocket.com/?p=1894) - [深入浅出 spring-data-elasticsearch – 基本案例详解(三)](http://www.bysocket.com/?p=1899) - [深入浅出 spring-data-elasticsearch – 实战案例详解(四)](http://www.bysocket.com/?p=1902) #### 『 Dubbo 篇 』 - [Spring Boot 整合 Dubbo/ZooKeeper 详解 SOA 案例](http://www.bysocket.com/?p=1681) - [Spring Boot 中如何使用 Dubbo Activate 扩展点](http://www.bysocket.com/?p=1782) - [Spring Boot Dubbo applications.properties 配置清单](http://www.bysocket.com/?p=1805) ### 三、最后推荐 - [我的博客](https://www.bysocket.com "我的博客"):分享学习可落地的技术博文 - [我的GitHub](https://github.com/JeffLi1993 "我的GitHub"):Follow 下呗 - [我的Gitee](https://gitee.com/jeff1993 "我的Gitee"):Follow 下呗 - [Spring问答社区](http://www.spring4all.com/ "Spring问答社区"):如果您有什么问题,可以去这里发帖 ### 四、我的公号 ================================================ FILE: chapter-1-spring-boot-quickstart/pom.xml ================================================ 4.0.0 chapter-1-spring-boot-quickstart 《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 1 章《Spring Boot 入门》Demo demo.springboot chapter-1-spring-boot-quickstart 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin spring-snapshots Spring Snapshots https://repo.spring.io/libs-snapshot true ================================================ FILE: chapter-1-spring-boot-quickstart/src/main/java/demo/springboot/QuickStartApplication.java ================================================ package demo.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 26/09/2017. */ @SpringBootApplication public class QuickStartApplication { public static void main(String[] args) { SpringApplication.run(QuickStartApplication.class, args); } } ================================================ FILE: chapter-1-spring-boot-quickstart/src/main/java/demo/springboot/web/HelloBookController.java ================================================ package demo.springboot.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * Spring Boot Hello案例 * * Created by bysocket on 26/09/2017. */ @RestController public class HelloBookController { @RequestMapping(value = "/book/hello",method = RequestMethod.GET) public String sayHello() { return "Hello,《Spring Boot 2.x 核心技术实战 - 上 基础篇》!"; } } ================================================ FILE: chapter-1-spring-boot-quickstart/src/main/java/demo/springboot/web/HelloController.java ================================================ package demo.springboot.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; /** * Spring Boot Hello案例 * * Created by bysocket on 26/09/2017. */ @Controller public class HelloController { @RequestMapping(value = "/hello",method = RequestMethod.GET) @ResponseBody public String sayHello() { return "Hello,Spring Boot!"; } } ================================================ FILE: chapter-1-spring-boot-quickstart/src/main/resources/application.properties ================================================ server.port=-1 ================================================ FILE: chapter-1-spring-boot-quickstart/src/test/java/demo/springboot/QuickStartApplicationTests.java ================================================ package demo.springboot; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = QuickStartApplication.class) @AutoConfigureMockMvc @TestPropertySource(locations = "classpath:application.properties") public class QuickStartApplicationTests { @Autowired private MockMvc mvc; @Test public void requestHello_thenStatus200_and_outputHello() throws Exception { mvc.perform(get("/hello") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) .andExpect(content().encoding("UTF-8")) .andExpect(content().string("Hello,Spring Boot!")); } } ================================================ FILE: chapter-1-spring-boot-quickstart/src/test/resources/application.properties ================================================ server.port=-1 ================================================ FILE: chapter-2-spring-boot-config/pom.xml ================================================ 4.0.0 chapter-2-spring-boot-config 《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 2 章《Spring Boot 配置》Demo demo.springboot chapter-2-spring-boot-config 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web com.spring4all spring-boot-starter-swagger 1.5.1.RELEASE org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin 2.1.3.RELEASE spring-snapshots Spring Snapshots https://repo.spring.io/libs-snapshot true ================================================ FILE: chapter-2-spring-boot-config/src/main/java/demo/springboot/ConfigApplication.java ================================================ package demo.springboot; import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 26/09/2017. */ @EnableSwagger2Doc // 开启 Swagger @SpringBootApplication public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } } ================================================ FILE: chapter-2-spring-boot-config/src/main/java/demo/springboot/config/BookComponent.java ================================================ package demo.springboot.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; /** * 书属性 * */ @Component @ConfigurationProperties(prefix = "demo.book") @Validated public class BookComponent { /** * 书名 */ @NotEmpty private String name; /** * 作者 */ @NotNull private String writer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriter() { return writer; } public void setWriter(String writer) { this.writer = writer; } } ================================================ FILE: chapter-2-spring-boot-config/src/main/java/demo/springboot/config/BookProperties.java ================================================ package demo.springboot.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 书属性 * * Created by bysocket on 27/09/2017. */ @Component public class BookProperties { /** * 书名 */ @Value("${demo.book.name}") private String name; /** * 作者 */ @Value("${demo.book.writer}") private String writer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriter() { return writer; } public void setWriter(String writer) { this.writer = writer; } } ================================================ FILE: chapter-2-spring-boot-config/src/main/java/demo/springboot/web/HelloBookController.java ================================================ package demo.springboot.web; import demo.springboot.config.BookProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * Spring Boot Hello案例 * * Created by bysocket on 26/09/2017. */ @RestController public class HelloBookController { @Autowired BookProperties bookProperties; @GetMapping("/book/hello") public String sayHello() { return "Hello, " + bookProperties.getWriter() + " is writing " + bookProperties.getName() + " !"; } } ================================================ FILE: chapter-2-spring-boot-config/src/main/resources/application-dev.properties ================================================ ## \u4E66\u4FE1\u606F demo.book.name=[Spring Boot 2.x Core Action] From Dev demo.book.writer=BYSocket ================================================ FILE: chapter-2-spring-boot-config/src/main/resources/application-prod.properties ================================================ ## \u4E66\u4FE1\u606F demo.book.name=[Spring Boot 2.x Core Action] From Prod demo.book.writer=BYSocket ================================================ FILE: chapter-2-spring-boot-config/src/main/resources/application.properties ================================================ ## \u4E66\u4FE1\u606F demo.book.name=[Spring Boot 2.x Core Action] demo.book.writer=BYSocket demo.book.description=${demo.book.writer}'s${demo.book.name} ================================================ FILE: chapter-2-spring-boot-config/src/main/resources/application.yml ================================================ ## 书信息 demo: book: name: 《Spring Boot 2.x 核心技术实战 - 上 基础篇》 writer: 泥瓦匠BYSocket ================================================ FILE: chapter-2-spring-boot-config/src/test/java/demo/springboot/ConfigApplicationTests.java ================================================ package demo.springboot; import demo.springboot.config.BookComponent; import demo.springboot.config.BookProperties; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class ConfigApplicationTests { @Autowired BookProperties bookProperties; @Autowired BookComponent bookComponent; @Test public void testBookProperties() { Assert.assertEquals(bookProperties.getName(),"[Spring Boot 2.x Core Action]"); Assert.assertEquals(bookProperties.getWriter(),"BYSocket"); } @Test public void testBookComponent() { Assert.assertEquals(bookComponent.getName(),"[Spring Boot 2.x Core Action]"); Assert.assertEquals(bookComponent.getWriter(),"BYSocket"); } } ================================================ FILE: chapter-3-spring-boot-web/pom.xml ================================================ 4.0.0 chapter-3-spring-boot-web 《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 3 章《Web 开发》Demo demo.springboot chapter-3-spring-boot-web 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test spring-snapshots Spring Snapshots https://repo.spring.io/libs-snapshot true ================================================ FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/WebApplication.java ================================================ package demo.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 26/09/2017. */ @SpringBootApplication public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } } ================================================ FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/domain/Book.java ================================================ package demo.springboot.domain; import java.io.Serializable; /** * Book 实体类 * * Created by bysocket on 27/09/2017. */ public class Book implements Serializable { /** * 编号 */ private Long id; /** * 书名 */ private String name; /** * 作者 */ private String writer; /** * 简介 */ private String introduction; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriter() { return writer; } public void setWriter(String writer) { this.writer = writer; } public String getIntroduction() { return introduction; } public void setIntroduction(String introduction) { this.introduction = introduction; } public Book(Long id, String name, String writer, String introduction) { this.id = id; this.name = name; this.writer = writer; this.introduction = introduction; } public Book(Long id, String name) { this.id = id; this.name = name; } public Book(String name) { this.name = name; } public Book() { } } ================================================ FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/service/BookService.java ================================================ package demo.springboot.service; import demo.springboot.domain.Book; import java.util.List; /** * Book 业务接口层 * * Created by bysocket on 27/09/2017. */ public interface BookService { /** * 获取所有 Book */ List findAll(); /** * 新增 Book * * @param book {@link Book} */ Book insertByBook(Book book); /** * 更新 Book * * @param book {@link Book} */ Book update(Book book); /** * 删除 Book * * @param id 编号 */ Book delete(Long id); /** * 获取 Book * * @param id 编号 */ Book findById(Long id); /** * 查找书是否存在 * @param book * @return */ boolean exists(Book book); /** * 根据书名获取书籍 * @param name * @return */ Book findByName(String name); } ================================================ FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/service/impl/BookServiceImpl.java ================================================ package demo.springboot.service.impl; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import demo.springboot.web.BookController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import javax.annotation.PostConstruct; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * Book 业务层实现 *

* Created by bysocket on 27/09/2017. */ @Service public class BookServiceImpl implements BookService { private static final AtomicLong counter = new AtomicLong(); /** * 使用集合模拟数据库 */ private static List books = new ArrayList<>( Arrays.asList( new Book(counter.incrementAndGet(), "book"))); // 模拟数据库,存储 Book 信息 // 第五章《数据存储》会替换成 MySQL 存储 private static Map BOOK_DB = new HashMap<>(); @Override public List findAll() { return new ArrayList<>(BOOK_DB.values()); } @Override public Book insertByBook(Book book) { book.setId(BOOK_DB.size() + 1L); BOOK_DB.put(book.getId().toString(), book); return book; } @Override public Book update(Book book) { BOOK_DB.put(book.getId().toString(), book); return book; } @Override public Book delete(Long id) { return BOOK_DB.remove(id.toString()); } @Override public Book findById(Long id) { return BOOK_DB.get(id.toString()); } @Override public boolean exists(Book book) { return findByName(book.getName()) != null; } @Override public Book findByName(String name) { for (Book book : books) { if (book.getName().equals(name)) { return book; } } return null; } } ================================================ FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/web/BookController.java ================================================ package demo.springboot.web; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; import java.util.List; /** * Book 控制层 * * Created by bysocket on 27/09/2017. */ @RestController @RequestMapping(value = "/book") public class BookController { private final Logger LOG = LoggerFactory.getLogger(BookController.class); @Autowired BookService bookService; /** * 获取 Book 列表 * 处理 "/book" 的 GET 请求,用来获取 Book 列表 */ @RequestMapping(method = RequestMethod.GET) public List getBookList() { return bookService.findAll(); } /** * 获取 Book * 处理 "/book/{id}" 的 GET 请求,用来获取 Book 信息 */ @RequestMapping(value = "/{id}", method = RequestMethod.GET) public Book getBook(@PathVariable Long id) { return bookService.findById(id); } /** * 创建 Book * 处理 "/book/create" 的 POST 请求,用来新建 Book 信息 * 通过 @RequestBody 绑定实体参数,也通过 @RequestParam 传递参数 */ @RequestMapping(value = "/create", method = RequestMethod.POST) public ResponseEntity postBook(@RequestBody Book book, UriComponentsBuilder ucBuilder) { LOG.info("creating new book: {}", book); if (book.getName().equals("conflict")){ LOG.info("a book with name " + book.getName() + " already exists"); return new ResponseEntity<>(HttpStatus.CONFLICT); } bookService.insertByBook(book); HttpHeaders headers = new HttpHeaders(); headers.setLocation(ucBuilder.path("/book/{id}").buildAndExpand(book.getId()).toUri()); return new ResponseEntity<>(headers, HttpStatus.CREATED); } /** * 更新 Book * 处理 "/update" 的 PUT 请求,用来更新 Book 信息 */ @RequestMapping(value = "/update", method = RequestMethod.PUT) public Book putBook(@RequestBody Book book) { return bookService.update(book); } /** * 删除 Book * 处理 "/book/{id}" 的 GET 请求,用来删除 Book 信息 */ @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE) public Book deleteBook(@PathVariable Long id) { return bookService.delete(id); } } ================================================ FILE: chapter-3-spring-boot-web/src/main/resources/application.properties ================================================ ================================================ FILE: chapter-3-spring-boot-web/src/test/java/demo/springboot/WebApplicationTests.java ================================================ package demo.springboot; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class WebApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: chapter-3-spring-boot-web/src/test/java/demo/springboot/web/BookControllerTest.java ================================================ package demo.springboot.web; import com.fasterxml.jackson.databind.ObjectMapper; import demo.springboot.WebApplication; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WebApplication.class) @AutoConfigureMockMvc @TestPropertySource(locations = "classpath:application.properties") public class BookControllerTest { private MockMvc mockMvc; @Mock private BookService bookService; @InjectMocks private BookController bookController; @Before public void init() { MockitoAnnotations.initMocks(this); mockMvc = MockMvcBuilders .standaloneSetup(bookController) //.addFilters(new CORSFilter()) .build(); } @Test public void getBookList() throws Exception { mockMvc.perform(get("/book") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON_UTF8)) .andExpect(jsonPath("$", hasSize(0))); } @Test public void test_create_book_success() throws Exception { Book book = createOneBook(); when(bookService.insertByBook(book)).thenReturn(book); mockMvc.perform( post("/book/create") .contentType(MediaType.APPLICATION_JSON) .content(asJsonString(book))) .andExpect(status().isCreated()) .andExpect(header().string("location", containsString("/book/1"))); } @Test public void test_create_book_fail_404_not_found() throws Exception { Book book = new Book(99L, "conflict"); when(bookService.exists(book)).thenReturn(true); mockMvc.perform( post("/book/create") .contentType(MediaType.APPLICATION_JSON) .content(asJsonString(book))) .andExpect(status().isConflict()); } @Test public void test_get_book_success() throws Exception { Book book = new Book(1L, "测试获取一本书", "strongant作者", "社区 www.spring4all.com 出版社出版"); when(bookService.findById(1L)).thenReturn(book); mockMvc.perform(get("/book/{id}", 1L)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath("$.id", is(1))) .andExpect(jsonPath("$.name", is("测试获取一本书"))); verify(bookService, times(1)).findById(1L); verifyNoMoreInteractions(bookService); } @Test public void test_get_by_id_fail_null_not_found() throws Exception { when(bookService.findById(1L)).thenReturn(null); //TODO: 查找不到应该抛出 404 状态码, Demo 待优化 mockMvc.perform(get("/book/{id}", 1L)) .andExpect(status().isOk()) .andExpect(content().string("")); verify(bookService, times(1)).findById(1L); verifyNoMoreInteractions(bookService); } @Test public void test_update_book_success() throws Exception { Book book = createOneBook(); when(bookService.findById(book.getId())).thenReturn(book); doReturn(book).when(bookService).update(book); mockMvc.perform( put("/book/update", book) .contentType(MediaType.APPLICATION_JSON) .content(asJsonString(book))) .andExpect(status().isOk()); } @Test public void test_update_book_fail_not_found() throws Exception { Book book = new Book(999L, "测试书名1"); when(bookService.findById(book.getId())).thenReturn(null); mockMvc.perform( put("/book/update", book) .contentType(MediaType.APPLICATION_JSON) .content(asJsonString(book))) .andExpect(status().isOk()) .andExpect(content().string("")); } // =========================================== Delete Book ============================================ @Test public void test_delete_book_success() throws Exception { Book book = new Book(1L, "这本书会被删除啦"); when(bookService.findById(book.getId())).thenReturn(book); doReturn(book).when(bookService).delete(book.getId()); mockMvc.perform( delete("/book/delete/{id}", book.getId()) ).andExpect(status().isOk()); } @Test public void test_delete_book_fail_404_not_found() throws Exception { Book book = new Book(1L, "这本书会被删除啦"); when(bookService.findById(book.getId())).thenReturn(null); mockMvc.perform( delete("/book/delete/{id}", book.getId())) .andExpect(status().isOk()); } public static String asJsonString(final Object obj) { try { final ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(obj); } catch (Exception e) { throw new RuntimeException(e); } } private Book createOneBook() { Book book = new Book(); book.setId(1L); book.setName("测试书名1"); book.setIntroduction("这是一本 www.spring4all.com 社区出版的很不错的一本书籍"); book.setWriter("strongant"); return book; } } ================================================ FILE: chapter-3-spring-boot-web/src/test/resources/application.properties ================================================ server.port=9090 ================================================ FILE: chapter-4-spring-boot-validating-form-input/pom.xml ================================================ 4.0.0 spring.boot.core chapter-4-spring-boot-validating-form-input 0.0.1-SNAPSHOT jar chapter-4-spring-boot-validating-form-input 第四章表单校验案例 org.springframework.boot spring-boot-starter-parent 2.0.0.M4 UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-validation org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-maven-plugin 2.1.3.RELEASE spring-milestones Spring Milestones https://repo.spring.io/libs-milestone false ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/ValidatingFormInputApplication.java ================================================ package spring.boot.core; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import spring.boot.core.domain.User; import spring.boot.core.domain.UserRepository; @SpringBootApplication public class ValidatingFormInputApplication implements CommandLineRunner { private Logger LOG = LoggerFactory.getLogger(ValidatingFormInputApplication.class); @Autowired private UserRepository userRepository; public static void main(String[] args) { SpringApplication.run(ValidatingFormInputApplication.class, args); } @Override public void run(String... args) throws Exception { User user1 = new User("Sergey", 24, "1994-01-01"); User user2 = new User("Ivan", 26, "1994-01-01"); User user3 = new User("Adam", 31, "1994-01-01"); LOG.info("Inserting data in DB."); userRepository.save(user1); userRepository.save(user2); userRepository.save(user3); LOG.info("User count in DB: {}", userRepository.count()); LOG.info("User with ID 1: {}", userRepository.findById(1L)); LOG.info("Deleting user with ID 2L form DB."); userRepository.deleteById(2L); LOG.info("User count in DB: {}", userRepository.count()); } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/domain/User.java ================================================ package spring.boot.core.domain; import org.hibernate.validator.constraints.NotEmpty; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.io.Serializable; /** * 用户实体类 *

* Created by bysocket on 21/07/2017. */ @Entity public class User implements Serializable { /** * 编号 */ @Id @GeneratedValue private Long id; /** * 名称 */ @NotEmpty(message = "姓名不能为空") @Size(min = 2, max = 8, message = "姓名长度必须大于 2 且小于 20 字") private String name; /** * 年龄 */ @NotNull(message = "年龄不能为空") @Min(value = 0, message = "年龄大于 0") @Max(value = 300, message = "年龄不大于 300") private Integer age; /** * 出生时间 */ @NotEmpty(message = "出生时间不能为空") private String birthday; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public User(String name, Integer age, String birthday) { this.name = name; this.age = age; this.birthday = birthday; } public User() {} @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", birthday=" + birthday + '}'; } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/domain/UserRepository.java ================================================ package spring.boot.core.domain; import org.springframework.data.jpa.repository.JpaRepository; /** * 用户持久层操作接口 * * Created by bysocket on 21/07/2017. */ public interface UserRepository extends JpaRepository { } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/service/UserService.java ================================================ package spring.boot.core.service; import spring.boot.core.domain.User; import java.util.List; /** * User 业务层接口 * * Created by bysocket on 24/07/2017. */ public interface UserService { List findAll(); User insertByUser(User user); User update(User user); User delete(Long id); User findById(Long id); } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java ================================================ package spring.boot.core.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import spring.boot.core.domain.User; import spring.boot.core.domain.UserRepository; import spring.boot.core.service.UserService; import java.util.List; /** * User 业务层实现 * * Created by bysocket on 24/07/2017. */ @Service public class UserServiceImpl implements UserService { private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class); @Autowired UserRepository userRepository; @Override public List findAll() { return userRepository.findAll(); } @Override public User insertByUser(User user) { LOGGER.info("新增用户:" + user.toString()); return userRepository.save(user); } @Override public User update(User user) { LOGGER.info("更新用户:" + user.toString()); return userRepository.save(user); } @Override public User delete(Long id) { User user = userRepository.findById(id).get(); userRepository.delete(user); LOGGER.info("删除用户:" + user.toString()); return user; } @Override public User findById(Long id) { LOGGER.info("获取用户 ID :" + id); return userRepository.findById(id).get(); } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/web/UserController.java ================================================ package spring.boot.core.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import spring.boot.core.domain.User; import spring.boot.core.service.UserService; import javax.validation.Valid; /** * 用户控制层 * * Created by bysocket on 24/07/2017. */ @Controller @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在 /users public class UserController { @Autowired UserService userService; // 用户服务层 /** * 获取用户列表 * 处理 "/users" 的 GET 请求,用来获取用户列表 * 通过 @RequestParam 传递参数,进一步实现条件查询或者分页查询 */ @RequestMapping(method = RequestMethod.GET) public String getUserList(ModelMap map) { map.addAttribute("userList", userService.findAll()); return "userList"; } /** * 显示创建用户表单 * * @param map * @return */ @RequestMapping(value = "/create", method = RequestMethod.GET) public String createUserForm(ModelMap map) { map.addAttribute("user", new User()); map.addAttribute("action", "create"); return "userForm"; } /** * 创建用户 * 处理 "/users" 的 POST 请求,用来获取用户列表 * 通过 @ModelAttribute 绑定参数,也通过 @RequestParam 从页面中传递参数 */ @RequestMapping(value = "/create", method = RequestMethod.POST) public String postUser(ModelMap map, @ModelAttribute @Valid User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { map.addAttribute("action", "create"); return "userForm"; } userService.insertByUser(user); return "redirect:/users/"; } /** * 显示需要更新用户表单 * 处理 "/users/{id}" 的 GET 请求,通过 URL 中的 id 值获取 User 信息 * URL 中的 id ,通过 @PathVariable 绑定参数 */ @RequestMapping(value = "/update/{id}", method = RequestMethod.GET) public String getUser(@PathVariable Long id, ModelMap map) { map.addAttribute("user", userService.findById(id)); map.addAttribute("action", "update"); return "userForm"; } /** * 处理 "/users/{id}" 的 PUT 请求,用来更新 User 信息 * */ @RequestMapping(value = "/update", method = RequestMethod.POST) public String putUser(ModelMap map, @ModelAttribute @Valid User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { map.addAttribute("action", "update"); return "userForm"; } userService.update(user); return "redirect:/users/"; } /** * 处理 "/users/{id}" 的 GET 请求,用来删除 User 信息 */ @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE) public String deleteUser(@PathVariable Long id) { userService.delete(id); return "redirect:/users/"; } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/application.properties ================================================ ## 开启 H2 数据库 spring.h2.console.enabled=true ## 配置 H2 数据库连接信息 spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= ## 是否显示 SQL 语句 spring.jpa.show-sql=true hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.hbm2ddl.auto=create ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/static/css/default.css ================================================ /* contentDiv */ .contentDiv {padding:20px 60px;} ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/templates/userForm.html ================================================ 用户管理

《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
用户管理
  
================================================ FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/templates/userList.html ================================================ 用户列表
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
用户列表
用户编号 名称 年龄 出生时间 管理
删除
================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/java/spring/boot/core/ValidatingFormInputApplicationTests.java ================================================ package spring.boot.core; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class ValidatingFormInputApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/java/spring/boot/core/web/UserControllerTest.java ================================================ package spring.boot.core.web; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import spring.boot.core.ValidatingFormInputApplication; import spring.boot.core.domain.User; import spring.boot.core.service.UserService; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; import java.util.Map; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertTrue; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; import static org.junit.Assert.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ValidatingFormInputApplication.class) @AutoConfigureMockMvc @TestPropertySource(locations = "classpath:application.properties") public class UserControllerTest { @Autowired private MockMvc mockMvc; @Autowired private UserService userService; @Autowired private ObjectMapper objectMapper; @Test public void getUserList() throws Exception { mockMvc.perform(get("/users")) .andExpect(view().name("userList")) .andExpect(status().isOk()) .andDo(print()); } private User createUser() { User user = new User(); user.setName("测试用户"); user.setAge(100); user.setBirthday("1994-01-01"); return userService.insertByUser(user); } @Test public void createUserForm() throws Exception { mockMvc.perform(get("/users/create")) .andDo(print()) .andExpect(view().name("userForm")) .andExpect(request().attribute("action", "create")) .andDo(print()) .andReturn(); } @Test public void postUser() throws Exception { User user = createUser(); assertNotNull(user); MultiValueMap parameters = new LinkedMultiValueMap(); Map maps = objectMapper.convertValue(user, new TypeReference>() { }); parameters.setAll(maps); mockMvc.perform(post("/users/create").params(parameters)) .andDo(print()) .andExpect(status().is(HttpServletResponse.SC_FOUND)) .andDo(print()) .andExpect(view().name("redirect:/users/")) .andDo(print()) .andReturn(); } @Test public void getUser() throws Exception { MvcResult result= mockMvc.perform(get("/users/update/{id}/", 1)) .andExpect(status().isOk()) .andExpect(view().name("userForm")) .andExpect(MockMvcResultMatchers.model().attributeExists("action")) .andExpect(model().attribute("user", hasProperty("id", is(1L)))) .andExpect(model().attribute("user", hasProperty("name", is("Sergey")))) .andExpect(model().attribute("user", hasProperty("age", is(24)))) .andExpect(model().attribute("user", hasProperty("birthday", is("1994-01-01")))) .andReturn(); MockHttpServletResponse mockResponse=result.getResponse(); assertThat(mockResponse.getContentType()).isEqualTo("text/html;charset=UTF-8"); Collection responseHeaders = mockResponse.getHeaderNames(); assertNotNull(responseHeaders); assertEquals(2, responseHeaders.size()); assertEquals("Check for Content-Type header", "Accept-Language", responseHeaders.iterator().next()); String responseAsString=mockResponse.getContentAsString(); assertTrue(responseAsString.contains("用户管理")); } @Test public void putUser() throws Exception { User user = createUser(); assertNotNull(user); MultiValueMap parameters = new LinkedMultiValueMap(); Map maps = objectMapper.convertValue(user, new TypeReference>() { }); parameters.setAll(maps); mockMvc.perform(post("/users/update").params(parameters)) .andDo(print()) .andExpect(status().is(HttpServletResponse.SC_FOUND)) .andDo(print()) .andExpect(view().name("redirect:/users/")) .andDo(print()) .andReturn(); } @Test public void deleteUser() throws Exception { mockMvc.perform( MockMvcRequestBuilders.delete("/users/delete/{id}", 1L) ) .andDo(print()) .andExpect(status().is(HttpServletResponse.SC_FOUND)) .andExpect(view().name("redirect:/users/")); } public static byte[] convertObjectToJsonBytes(Object object) throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); return mapper.writeValueAsBytes(object); } } ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/resources/application.properties ================================================ ## 开启 H2 数据库 spring.h2.console.enabled=true ## 配置 H2 数据库连接信息 spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= ## 是否显示 SQL 语句 spring.jpa.show-sql=true hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.hbm2ddl.auto=create ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/resources/static/css/default.css ================================================ /* contentDiv */ .contentDiv {padding:20px 60px;} ================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/resources/templates/userForm.html ================================================ 用户管理
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
用户管理
  
================================================ FILE: chapter-4-spring-boot-validating-form-input/src/test/resources/templates/userList.html ================================================ 用户列表
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
用户列表
用户编号 名称 年龄 出生时间 管理
删除
================================================ FILE: chapter-4-spring-boot-web-thymeleaf/pom.xml ================================================ 4.0.0 chapter-4-spring-boot-web-thymeleaf 《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 4 章《模板引擎》Demo demo.springboot chapter-4-spring-boot-web-thymeleaf 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test spring-snapshots Spring Snapshots https://repo.spring.io/libs-snapshot true ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/java/demo/springboot/WebApplication.java ================================================ package demo.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 30/09/2017. */ @SpringBootApplication public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } } ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/java/demo/springboot/domain/Book.java ================================================ package demo.springboot.domain; import java.io.Serializable; /** * Book 实体类 * * Created by bysocket on 30/09/2017. */ public class Book implements Serializable { /** * 编号 */ private Long id; /** * 书名 */ private String name; /** * 作者 */ private String writer; /** * 简介 */ private String introduction; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriter() { return writer; } public void setWriter(String writer) { this.writer = writer; } public String getIntroduction() { return introduction; } public void setIntroduction(String introduction) { this.introduction = introduction; } } ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/java/demo/springboot/service/BookService.java ================================================ package demo.springboot.service; import demo.springboot.domain.Book; import java.util.List; /** * Book 业务接口层 * * Created by bysocket on 30/09/2017. */ public interface BookService { /** * 获取所有 Book */ List findAll(); /** * 新增 Book * * @param book {@link Book} */ Book insertByBook(Book book); /** * 更新 Book * * @param book {@link Book} */ Book update(Book book); /** * 删除 Book * * @param id 编号 */ Book delete(Long id); /** * 获取 Book * * @param id 编号 */ Book findById(Long id); } ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/java/demo/springboot/service/impl/BookServiceImpl.java ================================================ package demo.springboot.service.impl; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Book 业务层实现 * * Created by bysocket on 30/09/2017. */ @Service public class BookServiceImpl implements BookService { // 模拟数据库,存储 Book 信息 // 第五章《数据存储》会替换成 H2 数据源存储 private static Map BOOK_DB = new HashMap<>(); @Override public List findAll() { return new ArrayList<>(BOOK_DB.values()); } @Override public Book insertByBook(Book book) { book.setId(BOOK_DB.size() + 1L); BOOK_DB.put(book.getId(), book); return book; } @Override public Book update(Book book) { BOOK_DB.put(book.getId(), book); return book; } @Override public Book delete(Long id) { return BOOK_DB.remove(id); } @Override public Book findById(Long id) { return BOOK_DB.get(id); } } ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/java/demo/springboot/web/BookController.java ================================================ package demo.springboot.web; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.*; /** * Book 控制层 * * Created by bysocket on 30/09/2017. */ @Controller @RequestMapping(value = "/book") public class BookController { private static final String BOOK_FORM_PATH_NAME = "bookForm"; private static final String BOOK_LIST_PATH_NAME = "bookList"; private static final String REDIRECT_TO_BOOK_URL = "redirect:/book"; @Autowired BookService bookService; /** * 获取 Book 列表 * 处理 "/book" 的 GET 请求,用来获取 Book 列表 */ @RequestMapping(method = RequestMethod.GET) public String getBookList(ModelMap map) { map.addAttribute("bookList",bookService.findAll()); return BOOK_LIST_PATH_NAME; } /** * 获取创建 Book 表单 */ @RequestMapping(value = "/create", method = RequestMethod.GET) public String createBookForm(ModelMap map) { map.addAttribute("book", new Book()); map.addAttribute("action", "create"); return BOOK_FORM_PATH_NAME; } /** * 创建 Book * 处理 "/book/create" 的 POST 请求,用来新建 Book 信息 * 通过 @ModelAttribute 绑定表单实体参数,也通过 @RequestParam 传递参数 */ @RequestMapping(value = "/create", method = RequestMethod.POST) public String postBook(@ModelAttribute Book book) { bookService.insertByBook(book); return REDIRECT_TO_BOOK_URL; } /** * 获取更新 Book 表单 * 处理 "/book/update/{id}" 的 GET 请求,通过 URL 中的 id 值获取 Book 信息 * URL 中的 id ,通过 @PathVariable 绑定参数 */ @RequestMapping(value = "/update/{id}", method = RequestMethod.GET) public String getUser(@PathVariable Long id, ModelMap map) { map.addAttribute("book", bookService.findById(id)); map.addAttribute("action", "update"); return BOOK_FORM_PATH_NAME; } /** * 更新 Book * 处理 "/update" 的 PUT 请求,用来更新 Book 信息 */ @RequestMapping(value = "/update", method = RequestMethod.POST) public String putBook(@ModelAttribute Book book) { bookService.update(book); return REDIRECT_TO_BOOK_URL; } /** * 删除 Book * 处理 "/book/{id}" 的 GET 请求,用来删除 Book 信息 */ @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) public String deleteBook(@PathVariable Long id) { bookService.delete(id); return REDIRECT_TO_BOOK_URL; } } ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/resources/application.properties ================================================ ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/resources/static/css/default.css ================================================ /* contentDiv */ .contentDiv {padding:20px 60px;} ================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/resources/templates/bookForm.html ================================================ 书籍管理
《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 4 章《模板引擎》Demo
书籍管理
  
================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/main/resources/templates/bookList.html ================================================ 书籍列表
《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 4 章《模板引擎》Demo
书籍列表
书籍编号 书名 作者 简介 管理
删除
================================================ FILE: chapter-4-spring-boot-web-thymeleaf/src/test/java/demo/springboot/WebApplicationTests.java ================================================ package demo.springboot; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class WebApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: chapter-5-spring-boot-data-jpa/pom.xml ================================================ 4.0.0 chapter-5-spring-boot-data-jpa 《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 5 章《数据存储》Demo demo.springboot chapter-5-spring-boot-data-jpa 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 runtime org.springframework.boot spring-boot-starter-test test spring-snapshots Spring Snapshots https://repo.spring.io/libs-snapshot true ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/WebApplication.java ================================================ package demo.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 30/09/2017. */ @SpringBootApplication public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/domain/Book.java ================================================ package demo.springboot.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; /** * Book 实体类 * * Created by bysocket on 30/09/2017. */ @Entity public class Book implements Serializable { /** * 编号 */ @Id @GeneratedValue private Long id; /** * 书名 */ private String name; /** * 作者 */ private String writer; /** * 简介 */ private String introduction; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getWriter() { return writer; } public void setWriter(String writer) { this.writer = writer; } public String getIntroduction() { return introduction; } public void setIntroduction(String introduction) { this.introduction = introduction; } } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/domain/BookRepository.java ================================================ package demo.springboot.domain; import org.springframework.data.jpa.repository.JpaRepository; /** * Book 数据持久层操作接口 * * Created by bysocket on 09/10/2017. */ public interface BookRepository extends JpaRepository { } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/service/BookService.java ================================================ package demo.springboot.service; import demo.springboot.domain.Book; import java.util.List; /** * Book 业务接口层 * * Created by bysocket on 30/09/2017. */ public interface BookService { /** * 获取所有 Book */ List findAll(); /** * 新增 Book * * @param book {@link Book} */ Book insertByBook(Book book); /** * 更新 Book * * @param book {@link Book} */ Book update(Book book); /** * 删除 Book * * @param id 编号 */ Book delete(Long id); /** * 获取 Book * * @param id 编号 */ Book findById(Long id); } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/service/impl/BookServiceImpl.java ================================================ package demo.springboot.service.impl; import demo.springboot.domain.Book; import demo.springboot.domain.BookRepository; import demo.springboot.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * Book 业务层实现 * * Created by bysocket on 30/09/2017. */ @Service public class BookServiceImpl implements BookService { @Autowired BookRepository bookRepository; @Override public List findAll() { return bookRepository.findAll(); } @Override public Book insertByBook(Book book) { return bookRepository.save(book); } @Override public Book update(Book book) { return bookRepository.save(book); } @Override public Book delete(Long id) { Book book = bookRepository.findById(id).get(); bookRepository.delete(book); return book; } @Override public Book findById(Long id) { return bookRepository.findById(id).get(); } } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/java/demo/springboot/web/BookController.java ================================================ package demo.springboot.web; import demo.springboot.domain.Book; import demo.springboot.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.*; /** * Book 控制层 * * Created by bysocket on 30/09/2017. */ @Controller @RequestMapping(value = "/book") public class BookController { private static final String BOOK_FORM_PATH_NAME = "bookForm"; private static final String BOOK_LIST_PATH_NAME = "bookList"; private static final String REDIRECT_TO_BOOK_URL = "redirect:/book"; @Autowired BookService bookService; /** * 获取 Book 列表 * 处理 "/book" 的 GET 请求,用来获取 Book 列表 */ @RequestMapping(method = RequestMethod.GET) public String getBookList(ModelMap map) { map.addAttribute("bookList",bookService.findAll()); return BOOK_LIST_PATH_NAME; } /** * 获取创建 Book 表单 */ @RequestMapping(value = "/create", method = RequestMethod.GET) public String createBookForm(ModelMap map) { map.addAttribute("book", new Book()); map.addAttribute("action", "create"); return BOOK_FORM_PATH_NAME; } /** * 创建 Book * 处理 "/book/create" 的 POST 请求,用来新建 Book 信息 * 通过 @ModelAttribute 绑定表单实体参数,也通过 @RequestParam 传递参数 */ @RequestMapping(value = "/create", method = RequestMethod.POST) public String postBook(@ModelAttribute Book book) { bookService.insertByBook(book); return REDIRECT_TO_BOOK_URL; } /** * 获取更新 Book 表单 * 处理 "/book/update/{id}" 的 GET 请求,通过 URL 中的 id 值获取 Book 信息 * URL 中的 id ,通过 @PathVariable 绑定参数 */ @RequestMapping(value = "/update/{id}", method = RequestMethod.GET) public String getUser(@PathVariable Long id, ModelMap map) { map.addAttribute("book", bookService.findById(id)); map.addAttribute("action", "update"); return BOOK_FORM_PATH_NAME; } /** * 更新 Book * 处理 "/update" 的 PUT 请求,用来更新 Book 信息 */ @RequestMapping(value = "/update", method = RequestMethod.POST) public String putBook(@ModelAttribute Book book) { bookService.update(book); return REDIRECT_TO_BOOK_URL; } /** * 删除 Book * 处理 "/book/{id}" 的 GET 请求,用来删除 Book 信息 */ @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) public String deleteBook(@PathVariable Long id) { bookService.delete(id); return REDIRECT_TO_BOOK_URL; } } ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/resources/application.properties ================================================ ## 是否启动日志 SQL 语句 spring.jpa.show-sql=true ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/resources/static/css/default.css ================================================ /* contentDiv */ .contentDiv {padding:20px 60px;} ================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/resources/templates/bookForm.html ================================================ 书籍管理
《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 5 章《数据存储》Demo
书籍管理
  
================================================ FILE: chapter-5-spring-boot-data-jpa/src/main/resources/templates/bookList.html ================================================ 书籍列表
《Spring Boot 2.x 核心技术实战 - 上 基础篇》第 5 章《数据存储》Demo
书籍列表
书籍编号 书名 作者 简介 管理
删除
================================================ FILE: chapter-5-spring-boot-data-jpa/src/test/java/demo/springboot/WebApplicationTests.java ================================================ package demo.springboot; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class WebApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: chapter-5-spring-boot-paging-sorting/pom.xml ================================================ 4.0.0 spring.boot.core chapter-5-spring-boot-paging-sorting 0.0.1-SNAPSHOT jar chapter-5-spring-boot-paging-sorting 第五章数据分页排序案例 org.springframework.boot spring-boot-starter-parent 2.0.0.M4 UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-data-jpa com.h2database h2 runtime org.springframework.boot spring-boot-maven-plugin 2.1.3.RELEASE spring-milestones Spring Milestones https://repo.spring.io/libs-milestone false ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/PagingSortingApplication.java ================================================ package spring.boot.core; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 应用启动程序 * * Created by bysocket on 18/09/2017. */ @SpringBootApplication public class PagingSortingApplication { public static void main(String[] args) { SpringApplication.run(PagingSortingApplication.class, args); } } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/domain/User.java ================================================ package spring.boot.core.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.io.Serializable; /** * 用户实体类 * * Created by bysocket on 18/09/2017. */ @Entity public class User implements Serializable { /** * 编号 */ @Id @GeneratedValue private Long id; /** * 名称 */ private String name; /** * 年龄 */ private Integer age; /** * 出生时间 */ private String birthday; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", birthday=" + birthday + '}'; } } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/domain/UserRepository.java ================================================ package spring.boot.core.domain; import org.springframework.data.repository.PagingAndSortingRepository; /** * 用户持久层操作接口 * * Created by bysocket on 18/09/2017. */ public interface UserRepository extends PagingAndSortingRepository { } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/service/UserService.java ================================================ package spring.boot.core.service; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import spring.boot.core.domain.User; /** * User 业务层接口 * * Created by bysocket on 18/09/2017. */ public interface UserService { /** * 获取用户分页列表 * * @param pageable * @return */ Page findByPage(Pageable pageable); /** * 新增用户 * * @param user * @return */ User insertByUser(User user); } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java ================================================ package spring.boot.core.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import spring.boot.core.domain.User; import spring.boot.core.domain.UserRepository; import spring.boot.core.service.UserService; /** * User 业务层实现 * * Created by bysocket on 18/09/2017. */ @Service public class UserServiceImpl implements UserService { private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class); @Autowired UserRepository userRepository; @Override public Page findByPage(Pageable pageable) { LOGGER.info(" \n 分页查询用户:" + " PageNumber = " + pageable.getPageNumber() + " PageSize = " + pageable.getPageSize()); return userRepository.findAll(pageable); } @Override public User insertByUser(User user) { LOGGER.info("新增用户:" + user.toString()); return userRepository.save(user); } } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/java/spring/boot/core/web/UserController.java ================================================ package spring.boot.core.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.*; import spring.boot.core.domain.User; import spring.boot.core.service.UserService; /** * 用户控制层 * * Created by bysocket on 18/09/2017. */ @RestController @RequestMapping(value = "/users") // 通过这里配置使下面的映射都在 /users public class UserController { @Autowired UserService userService; // 用户服务层 /** * 获取用户分页列表 * 处理 "/users" 的 GET 请求,用来获取用户分页列表 * 通过 @RequestParam 传递参数,进一步实现条件查询或者分页查询 * * Pageable 支持的分页参数如下 * page - 当前页 从 0 开始 * size - 每页大小 默认值在 application.properties 配置 */ @RequestMapping(method = RequestMethod.GET) public Page getUserPage(Pageable pageable) { return userService.findByPage(pageable); } /** * 创建用户 * 处理 "/users" 的 POST 请求,用来获取用户列表 * 通过 @RequestBody 绑定实体类参数 */ @RequestMapping(value = "/create", method = RequestMethod.POST) public User postUser(@RequestBody User user) { return userService.insertByUser(user); } } ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/main/resources/application.properties ================================================ ## 是否显示 SQL 语句 spring.jpa.show-sql=true ## DATA WEB 相关配置 {@link SpringDataWebProperties} ## 分页大小 默认为 20 spring.data.web.pageable.default-page-size=3 ## 当前页参数名 默认为 page spring.data.web.pageable.page-parameter=pageNumber ## 当前页参数名 默认为 size spring.data.web.pageable.size-parameter=pageSize ## 字段排序参数名 默认为 sort spring.data.web.sort.sort-parameter=orderBy ================================================ FILE: chapter-5-spring-boot-paging-sorting/src/test/java/spring/boot/core/PagingSortingApplicationTests.java ================================================ package spring.boot.core; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class PagingSortingApplicationTests { @Test public void contextLoads() { } } ================================================ FILE: pom.xml ================================================ 4.0.0 springboot-learning-example springboot springboot-learning-example 1.0-SNAPSHOT pom 2-x-spring-boot-webflux-handling-errors 2-x-spring-boot-groovy chapter-1-spring-boot-quickstart chapter-2-spring-boot-config chapter-3-spring-boot-web chapter-4-spring-boot-web-thymeleaf chapter-5-spring-boot-data-jpa chapter-4-spring-boot-validating-form-input chapter-5-spring-boot-paging-sorting spring-data-elasticsearch-crud spring-data-elasticsearch-query springboot-configuration springboot-dubbo-server springboot-dubbo-client springboot-elasticsearch springboot-freemarker springboot-hbase springboot-helloworld springboot-mybatis springboot-mybatis-annotation springboot-mybatis-mutil-datasource springboot-mybatis-redis springboot-mybatis-redis-annotation springboot-restful springboot-properties springboot-validation-over-json springboot-webflux-1-quickstart springboot-webflux-2-restful springboot-webflux-3-mongodb springboot-webflux-4-thymeleaf springboot-webflux-5-thymeleaf-mongodb springboot-webflux-6-redis springboot-webflux-7-redis-cache ================================================ FILE: spring-data-elasticsearch-crud/pom.xml ================================================ 4.0.0 springboot spring-data-elasticsearch-crud 0.0.1-SNAPSHOT spring-data-elasticsearch-crud org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 城市 Controller 实现 Restful HTTP 服务 *

* Created by bysocket on 03/05/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; /** * 插入 ES 新城市 * * @param city * @return */ @RequestMapping(value = "/api/city", method = RequestMethod.POST) public Long createCity(@RequestBody City city) { return cityService.saveCity(city); } /** * AND 语句查询 * * @param description * @param score * @return */ @RequestMapping(value = "/api/city/and/find", method = RequestMethod.GET) public List findByDescriptionAndScore(@RequestParam(value = "description") String description, @RequestParam(value = "score") Integer score) { return cityService.findByDescriptionAndScore(description, score); } /** * OR 语句查询 * * @param description * @param score * @return */ @RequestMapping(value = "/api/city/or/find", method = RequestMethod.GET) public List findByDescriptionOrScore(@RequestParam(value = "description") String description, @RequestParam(value = "score") Integer score) { return cityService.findByDescriptionOrScore(description, score); } /** * 查询城市描述 * * @param description * @return */ @RequestMapping(value = "/api/city/description/find", method = RequestMethod.GET) public List findByDescription(@RequestParam(value = "description") String description) { return cityService.findByDescription(description); } /** * NOT 语句查询 * * @param description * @return */ @RequestMapping(value = "/api/city/description/not/find", method = RequestMethod.GET) public List findByDescriptionNot(@RequestParam(value = "description") String description) { return cityService.findByDescriptionNot(description); } /** * LIKE 语句查询 * * @param description * @return */ @RequestMapping(value = "/api/city/like/find", method = RequestMethod.GET) public List findByDescriptionLike(@RequestParam(value = "description") String description) { return cityService.findByDescriptionLike(description); } } ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.elasticsearch.annotations.Document; import java.io.Serializable; /** * 城市实体类 *

* Created by bysocket on 03/05/2017. */ @Document(indexName = "province", type = "city") public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 城市名称 */ private String name; /** * 描述 */ private String description; /** * 城市评分 */ private Integer score; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } } ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/repository/CityRepository.java ================================================ package org.spring.springboot.repository; import org.spring.springboot.domain.City; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * ES 操作类 *

* Created by bysocket on 17/05/2017. */ public interface CityRepository extends ElasticsearchRepository { /** * AND 语句查询 * * @param description * @param score * @return */ List findByDescriptionAndScore(String description, Integer score); /** * OR 语句查询 * * @param description * @param score * @return */ List findByDescriptionOrScore(String description, Integer score); /** * 查询城市描述 * * 等同于下面代码 * @Query("{\"bool\" : {\"must\" : {\"term\" : {\"description\" : \"?0\"}}}}") * Page findByDescription(String description, Pageable pageable); * * @param description * @param page * @return */ Page findByDescription(String description, Pageable page); /** * NOT 语句查询 * * @param description * @param page * @return */ Page findByDescriptionNot(String description, Pageable page); /** * LIKE 语句查询 * * @param description * @param page * @return */ Page findByDescriptionLike(String description, Pageable page); } ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市 ES 业务接口类 * */ public interface CityService { /** * 新增 ES 城市信息 * * @param city * @return */ Long saveCity(City city); /** * AND 语句查询 * * @param description * @param score * @return */ List findByDescriptionAndScore(String description, Integer score); /** * OR 语句查询 * * @param description * @param score * @return */ List findByDescriptionOrScore(String description, Integer score); /** * 查询城市描述 * * @param description * @return */ List findByDescription(String description); /** * NOT 语句查询 * * @param description * @return */ List findByDescriptionNot(String description); /** * LIKE 语句查询 * * @param description * @return */ List findByDescriptionLike(String description); } ================================================ FILE: spring-data-elasticsearch-crud/src/main/java/org/spring/springboot/service/impl/CityESServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.domain.City; import org.spring.springboot.repository.CityRepository; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.List; /** * 城市 ES 业务逻辑实现类 *

* Created by bysocket on 07/02/2017. */ @Service public class CityESServiceImpl implements CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class); // 分页参数 -> TODO 代码可迁移到具体项目的公共 common 模块 private static final Integer pageNumber = 0; private static final Integer pageSize = 10; Pageable pageable = new PageRequest(pageNumber, pageSize); // ES 操作类 @Autowired CityRepository cityRepository; public Long saveCity(City city) { City cityResult = cityRepository.save(city); return cityResult.getId(); } public List findByDescriptionAndScore(String description, Integer score) { return cityRepository.findByDescriptionAndScore(description, score); } public List findByDescriptionOrScore(String description, Integer score) { return cityRepository.findByDescriptionOrScore(description, score); } public List findByDescription(String description) { return cityRepository.findByDescription(description, pageable).getContent(); } public List findByDescriptionNot(String description) { return cityRepository.findByDescriptionNot(description, pageable).getContent(); } public List findByDescriptionLike(String description) { return cityRepository.findByDescriptionLike(description, pageable).getContent(); } } ================================================ FILE: spring-data-elasticsearch-crud/src/main/resources/application.properties ================================================ # ES spring.data.elasticsearch.repositories.enabled = true spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300 ================================================ FILE: spring-data-elasticsearch-query/pom.xml ================================================ 4.0.0 springboot spring-data-elasticsearch-query 0.0.1-SNAPSHOT spring-data-elasticsearch-query org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 20/06/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 城市 Controller 实现 Restful HTTP 服务 *

* Created by bysocket on 20/06/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; /** * 插入 ES 新城市 * * @param city * @return */ @RequestMapping(value = "/api/city", method = RequestMethod.POST) public Long createCity(@RequestBody City city) { return cityService.saveCity(city); } /** * 搜索返回分页结果 * * @param pageNumber 当前页码 * @param pageSize 每页大小 * @param searchContent 搜索内容 * @return */ @RequestMapping(value = "/api/city/search", method = RequestMethod.GET) public List searchCity(@RequestParam(value = "pageNumber") Integer pageNumber, @RequestParam(value = "pageSize", required = false) Integer pageSize, @RequestParam(value = "searchContent") String searchContent) { return cityService.searchCity(pageNumber, pageSize,searchContent); } } ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.elasticsearch.annotations.Document; import java.io.Serializable; /** * 城市实体类 *

* Created by bysocket on 20/06/2017. */ @Document(indexName = "province", type = "city") public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 城市名称 */ private String name; /** * 描述 */ private String description; /** * 城市评分 */ private Integer score; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } } ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/repository/CityRepository.java ================================================ package org.spring.springboot.repository; import org.spring.springboot.domain.City; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * ES 操作类 *

* Created by bysocket on 20/06/2017. */ public interface CityRepository extends ElasticsearchRepository { } ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市 ES 业务接口类 * */ public interface CityService { /** * 新增 ES 城市信息 * * @param city * @return */ Long saveCity(City city); /** * 搜索词搜索,分页返回城市信息 * * @param pageNumber 当前页码 * @param pageSize 每页大小 * @param searchContent 搜索内容 * @return */ List searchCity(Integer pageNumber, Integer pageSize, String searchContent); } ================================================ FILE: spring-data-elasticsearch-query/src/main/java/org/spring/springboot/service/impl/CityESServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.domain.City; import org.spring.springboot.repository.CityRepository; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.stereotype.Service; import java.util.List; /** * 城市 ES 业务逻辑实现类 *

* Created by bysocket on 20/06/2017. */ @Service public class CityESServiceImpl implements CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class); /* 分页参数 */ Integer PAGE_SIZE = 12; // 每页数量 Integer DEFAULT_PAGE_NUMBER = 0; // 默认当前页码 /* 搜索模式 */ String SCORE_MODE_SUM = "sum"; // 权重分求和模式 Float MIN_SCORE = 10.0F; // 由于无相关性的分值默认为 1 ,设置权重分最小值为 10 @Autowired CityRepository cityRepository; // ES 操作类 public Long saveCity(City city) { City cityResult = cityRepository.save(city); return cityResult.getId(); } @Override public List searchCity(Integer pageNumber, Integer pageSize, String searchContent) { // 校验分页参数 if (pageSize == null || pageSize <= 0) { pageSize = PAGE_SIZE; } if (pageNumber == null || pageNumber < DEFAULT_PAGE_NUMBER) { pageNumber = DEFAULT_PAGE_NUMBER; } LOGGER.info("\n searchCity: searchContent [" + searchContent + "] \n "); // 构建搜索查询 SearchQuery searchQuery = getCitySearchQuery(pageNumber,pageSize,searchContent); LOGGER.info("\n searchCity: searchContent [" + searchContent + "] \n DSL = \n " + searchQuery.getQuery().toString()); Page cityPage = cityRepository.search(searchQuery); return cityPage.getContent(); } /** * 根据搜索词构造搜索查询语句 * * 代码流程: * - 权重分查询 * - 短语匹配 * - 设置权重分最小值 * - 设置分页参数 * * @param pageNumber 当前页码 * @param pageSize 每页大小 * @param searchContent 搜索内容 * @return */ private SearchQuery getCitySearchQuery(Integer pageNumber, Integer pageSize,String searchContent) { // 短语匹配到的搜索词,求和模式累加权重分 // 权重分查询 https://www.elastic.co/guide/cn/elasticsearch/guide/current/function-score-query.html // - 短语匹配 https://www.elastic.co/guide/cn/elasticsearch/guide/current/phrase-matching.html // - 字段对应权重分设置,可以优化成 enum // - 由于无相关性的分值默认为 1 ,设置权重分最小值为 10 FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() .add(QueryBuilders.matchPhraseQuery("name", searchContent), ScoreFunctionBuilders.weightFactorFunction(1000)) .add(QueryBuilders.matchPhraseQuery("description", searchContent), ScoreFunctionBuilders.weightFactorFunction(500)) .scoreMode(SCORE_MODE_SUM).setMinScore(MIN_SCORE); // 分页参数 Pageable pageable = new PageRequest(pageNumber, pageSize); return new NativeSearchQueryBuilder() .withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); } } ================================================ FILE: spring-data-elasticsearch-query/src/main/resources/application.properties ================================================ # ES spring.data.elasticsearch.repositories.enabled = true spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300 ================================================ FILE: springboot-configuration/pom.xml ================================================ 4.0.0 springboot springboot-configuration 0.0.1-SNAPSHOT springboot-configuration org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: springboot-configuration/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-configuration/src/main/java/org/spring/springboot/config/MessageConfiguration.java ================================================ package org.spring.springboot.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Created by bysocket on 08/09/2017. */ @Configuration public class MessageConfiguration { @Bean public String message() { return "message configuration"; } } ================================================ FILE: springboot-configuration/src/test/java/org/spring/springboot/config/MessageConfigurationTest.java ================================================ package org.spring.springboot.config; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.junit.Assert.assertEquals; /** * Spring Boot MessageConfiguration 测试 - {@link MessageConfiguration} * */ public class MessageConfigurationTest { @Test public void testGetMessageBean() throws Exception { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MessageConfiguration.class); assertEquals("message configuration", ctx.getBean("message")); } @Test public void testScanPackages() throws Exception { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.scan("org.spring.springboot"); ctx.refresh(); assertEquals("message configuration", ctx.getBean("message")); } } ================================================ FILE: springboot-dubbo-client/pom.xml ================================================ 4.0.0 springboot springboot-dubbo-client 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.0.0 io.dubbo.springboot spring-boot-starter-dubbo ${dubbo-spring-boot} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-dubbo-client/src/main/java/org/spring/springboot/ClientApplication.java ================================================ package org.spring.springboot; import org.spring.springboot.dubbo.CityDubboConsumerService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class ClientApplication { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 ConfigurableApplicationContext run = SpringApplication.run(ClientApplication.class, args); CityDubboConsumerService cityService = run.getBean(CityDubboConsumerService.class); cityService.printCity(); } } ================================================ FILE: springboot-dubbo-client/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "City{" + "id=" + id + ", provinceId=" + provinceId + ", cityName='" + cityName + '\'' + ", description='" + description + '\'' + '}'; } } ================================================ FILE: springboot-dubbo-client/src/main/java/org/spring/springboot/dubbo/CityDubboConsumerService.java ================================================ package org.spring.springboot.dubbo; import com.alibaba.dubbo.config.annotation.Reference; import org.spring.springboot.domain.City; import org.springframework.stereotype.Component; /** * 城市 Dubbo 服务消费者 * * Created by bysocket on 28/02/2017. */ @Component public class CityDubboConsumerService { @Reference(version = "1.0.0") CityDubboService cityDubboService; public void printCity() { String cityName="温岭"; City city = cityDubboService.findCityByName(cityName); System.out.println(city.toString()); } } ================================================ FILE: springboot-dubbo-client/src/main/java/org/spring/springboot/dubbo/CityDubboService.java ================================================ package org.spring.springboot.dubbo; import org.spring.springboot.domain.City; /** * 城市业务 Dubbo 服务层 * * Created by bysocket on 28/02/2017. */ public interface CityDubboService { /** * 根据城市名称,查询城市信息 * @param cityName */ City findCityByName(String cityName); } ================================================ FILE: springboot-dubbo-client/src/main/resources/application.properties ================================================ ## 避免和 server 工程端口冲突 server.port=8081 ## Dubbo 服务消费者配置 spring.dubbo.application.name=consumer spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 spring.dubbo.scan=org.spring.springboot.dubbo ================================================ FILE: springboot-dubbo-server/DubboProperties.md ================================================ ## Dubbo 配置 # 扫描包路径
spring.dubbo.scan=org.
spring.
springboot.dubbo ## Dubbo 应用配置 // 应用名称
spring.dubbo.application.name=xxx // 模块版本
spring.dubbo.application.version=xxx // 应用负责人
spring.dubbo.application.owner=xxx // 组织名(BU或部门)
spring.dubbo.application.organization=xxx // 分层
spring.dubbo.application.architecture=xxx // 环境,如:dev/test/run
spring.dubbo.application.environment=xxx // Java代码编译器
spring.dubbo.application.compiler=xxx // 日志输出方式
spring.dubbo.application.logger=xxx // 注册中心 0
spring.dubbo.application.registries[0].address=zookeeper://127.0.0.1:2181=xxx // 注册中心 1
spring.dubbo.application.registries[1].address=zookeeper://127.0.0.1:2181=xxx // 服务监控
spring.dubbo.application.monitor.address=xxx ## Dubbo 注册中心配置类 // 注册中心地址
spring.dubbo.application.registries.address=xxx // 注册中心登录用户名
spring.dubbo.application.registries.username=xxx // 注册中心登录密码
spring.dubbo.application.registries.password=xxx // 注册中心缺省端口
spring.dubbo.application.registries.port=xxx // 注册中心协议
spring.dubbo.application.registries.protocol=xxx // 客户端实现
spring.dubbo.application.registries.transporter=xxx
spring.dubbo.application.registries.server=xxx
spring.dubbo.application.registries.client=xxx
spring.dubbo.application.registries.cluster=xxx
spring.dubbo.application.registries.group=xxx
spring.dubbo.application.registries.version=xxx // 注册中心请求超时时间(毫秒)
spring.dubbo.application.registries.timeout=xxx // 注册中心会话超时时间(毫秒)
spring.dubbo.application.registries.session=xxx // 动态注册中心列表存储文件
spring.dubbo.application.registries.file=xxx // 停止时等候完成通知时间
spring.dubbo.application.registries.wait=xxx // 启动时检查注册中心是否存在
spring.dubbo.application.registries.check=xxx // 在该注册中心上注册是动态的还是静态的服务
spring.dubbo.application.registries.dynamic=xxx // 在该注册中心上服务是否暴露
spring.dubbo.application.registries.register=xxx // 在该注册中心上服务是否引用
spring.dubbo.application.registries.subscribe=xxx ## Dubbo 服务协议配置 // 服务协议
spring.dubbo.application.protocol.name=xxx // 服务IP地址(多网卡时使用)
spring.dubbo.application.protocol.host=xxx // 服务端口
spring.dubbo.application.protocol.port=xxx // 上下文路径
spring.dubbo.application.protocol.contextpath=xxx // 线程池类型
spring.dubbo.application.protocol.threadpool=xxx // 线程池大小(固定大小)
spring.dubbo.application.protocol.threads=xxx // IO线程池大小(固定大小)
spring.dubbo.application.protocol.iothreads=xxx // 线程池队列大小
spring.dubbo.application.protocol.queues=xxx // 最大接收连接数
spring.dubbo.application.protocol.accepts=xxx // 协议编码
spring.dubbo.application.protocol.codec=xxx // 序列化方式
spring.dubbo.application.protocol.serialization=xxx // 字符集
spring.dubbo.application.protocol.charset=xxx // 最大请求数据长度
spring.dubbo.application.protocol.payload=xxx // 缓存区大小
spring.dubbo.application.protocol.buffer=xxx // 心跳间隔
spring.dubbo.application.protocol.heartbeat=xxx // 访问日志
spring.dubbo.application.protocol.accesslog=xxx // 网络传输方式
spring.dubbo.application.protocol.transporter=xxx // 信息交换方式
spring.dubbo.application.protocol.exchanger=xxx // 信息线程模型派发方式
spring.dubbo.application.protocol.dispatcher=xxx // 对称网络组网方式
spring.dubbo.application.protocol.networker=xxx // 服务器端实现
spring.dubbo.application.protocol.server=xxx // 客户端实现
spring.dubbo.application.protocol.client=xxx // 支持的telnet命令,多个命令用逗号分隔
spring.dubbo.application.protocol.telnet=xxx // 命令行提示符
spring.dubbo.application.protocol.prompt=xxx // status检查
spring.dubbo.application.protocol.status=xxx // 是否注册
spring.dubbo.application.protocol.status=xxx ================================================ FILE: springboot-dubbo-server/pom.xml ================================================ 4.0.0 springboot springboot-dubbo-server 0.0.1-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.0.0 io.dubbo.springboot spring-boot-starter-dubbo ${dubbo-spring-boot} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-dubbo-server/src/main/java/org/spring/springboot/ServerApplication.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class ServerApplication { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(ServerApplication.class,args); } } ================================================ FILE: springboot-dubbo-server/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public City() { } public City(Long id, Long provinceId, String cityName, String description) { this.id = id; this.provinceId = provinceId; this.cityName = cityName; this.description = description; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-dubbo-server/src/main/java/org/spring/springboot/dubbo/CityDubboService.java ================================================ package org.spring.springboot.dubbo; import org.spring.springboot.domain.City; /** * 城市业务 Dubbo 服务层 * * Created by bysocket on 28/02/2017. */ public interface CityDubboService { /** * 根据城市名称,查询城市信息 * @param cityName */ City findCityByName(String cityName); } ================================================ FILE: springboot-dubbo-server/src/main/java/org/spring/springboot/dubbo/impl/CityDubboServiceImpl.java ================================================ package org.spring.springboot.dubbo.impl; import com.alibaba.dubbo.config.annotation.Service; import org.spring.springboot.domain.City; import org.spring.springboot.dubbo.CityDubboService; import org.springframework.beans.factory.annotation.Autowired; /** * 城市业务 Dubbo 服务层实现层 * * Created by bysocket on 28/02/2017. */ // 注册为 Dubbo 服务 @Service(version = "1.0.0") public class CityDubboServiceImpl implements CityDubboService { public City findCityByName(String cityName) { return new City(1L,2L,"温岭","是我的故乡"); } } ================================================ FILE: springboot-dubbo-server/src/main/resources/application.properties ================================================ ## Dubbo 服务提供者配置 spring.dubbo.application.name=provider spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 spring.dubbo.protocol.name=dubbo spring.dubbo.protocol.port=20880 spring.dubbo.scan=org.spring.springboot.dubbo ================================================ FILE: springboot-elasticsearch/pom.xml ================================================ 4.0.0 springboot springboot-elasticsearch 0.0.1-SNAPSHOT springboot-elasticsearch org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 城市 Controller 实现 Restful HTTP 服务 *

* Created by bysocket on 03/05/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city", method = RequestMethod.POST) public Long createCity(@RequestBody City city) { return cityService.saveCity(city); } @RequestMapping(value = "/api/city/search", method = RequestMethod.GET) public List searchCity(@RequestParam(value = "pageNumber") Integer pageNumber, @RequestParam(value = "pageSize", required = false) Integer pageSize, @RequestParam(value = "searchContent") String searchContent) { return cityService.searchCity(pageNumber,pageSize,searchContent); } } ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.elasticsearch.annotations.Document; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 03/05/2017. */ @Document(indexName = "cityindex", type = "city") public class City implements Serializable{ private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceid; /** * 城市名称 */ private String cityname; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceid() { return provinceid; } public void setProvinceid(Long provinceid) { this.provinceid = provinceid; } public String getCityname() { return cityname; } public void setCityname(String cityname) { this.cityname = cityname; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/repository/CityRepository.java ================================================ package org.spring.springboot.repository; import org.spring.springboot.domain.City; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; /** * Created by bysocket on 17/05/2017. */ @Repository public interface CityRepository extends ElasticsearchRepository { } ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; public interface CityService { /** * 新增城市信息 * * @param city * @return */ Long saveCity(City city); /** * 根据关键词,function score query 权重分分页查询 * * @param pageNumber * @param pageSize * @param searchContent * @return */ List searchCity(Integer pageNumber, Integer pageSize, String searchContent); } ================================================ FILE: springboot-elasticsearch/src/main/java/org/spring/springboot/service/impl/CityESServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.domain.City; import org.spring.springboot.repository.CityRepository; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.stereotype.Service; import java.util.List; /** * 城市 ES 业务逻辑实现类 * * Created by bysocket on 07/02/2017. */ @Service public class CityESServiceImpl implements CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class); @Autowired CityRepository cityRepository; @Override public Long saveCity(City city) { City cityResult = cityRepository.save(city); return cityResult.getId(); } @Override public List searchCity(Integer pageNumber, Integer pageSize, String searchContent) { // 分页参数 Pageable pageable = new PageRequest(pageNumber, pageSize); // Function Score Query FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("cityname", searchContent)), ScoreFunctionBuilders.weightFactorFunction(1000)) .add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("description", searchContent)), ScoreFunctionBuilders.weightFactorFunction(100)); // 创建搜索 DSL 查询 SearchQuery searchQuery = new NativeSearchQueryBuilder() .withPageable(pageable) .withQuery(functionScoreQueryBuilder).build(); LOGGER.info("\n searchCity(): searchContent [" + searchContent + "] \n DSL = \n " + searchQuery.getQuery().toString()); Page searchPageResults = cityRepository.search(searchQuery); return searchPageResults.getContent(); } } ================================================ FILE: springboot-elasticsearch/src/main/resources/application.properties ================================================ # ES spring.data.elasticsearch.repositories.enabled = true spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300 ================================================ FILE: springboot-freemarker/pom.xml ================================================ 4.0.0 springboot springboot-freemarker 0.0.1-SNAPSHOT springboot-freemarker org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 org.springframework.boot spring-boot-starter-freemarker org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} junit junit 4.12 ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.mybatis.spring.annotation.MapperScan; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication // mapper 接口类扫描包配置 @MapperScan("org.spring.springboot.dao") public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/controller/CityController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 城市 Controller 实现 Restful HTTP 服务 *

* Created by bysocket on 07/02/2017. */ @Controller public class CityController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city/{id}", method = RequestMethod.GET) public String findOneCity(Model model, @PathVariable("id") Long id) { model.addAttribute("city", cityService.findCityById(id)); return "city"; } @RequestMapping(value = "/api/city", method = RequestMethod.GET) public String findAllCity(Model model) { List cityList = cityService.findAllCity(); model.addAttribute("cityList",cityList); return "cityList"; } } ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/dao/CityDao.java ================================================ package org.spring.springboot.dao; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.City; import java.util.List; /** * 城市 DAO 接口类 * * Created by bysocket on 07/02/2017. */ public interface CityDao { /** * 获取城市信息列表 * * @return */ List findAllCity(); /** * 根据城市 ID,获取城市信息 * * @param id * @return */ City findById(@Param("id") Long id); Long saveCity(City city); Long updateCity(City city); Long deleteCity(Long id); } ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市业务逻辑接口类 * * Created by bysocket on 07/02/2017. */ public interface CityService { /** * 获取城市信息列表 * * @return */ List findAllCity(); /** * 根据城市 ID,查询城市信息 * * @param id * @return */ City findCityById(Long id); /** * 新增城市信息 * * @param city * @return */ Long saveCity(City city); /** * 更新城市信息 * * @param city * @return */ Long updateCity(City city); /** * 根据城市 ID,删除城市信息 * * @param id * @return */ Long deleteCity(Long id); } ================================================ FILE: springboot-freemarker/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 城市业务逻辑实现类 * * Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { @Autowired private CityDao cityDao; public List findAllCity(){ return cityDao.findAllCity(); } public City findCityById(Long id) { return cityDao.findById(id); } @Override public Long saveCity(City city) { return cityDao.saveCity(city); } @Override public Long updateCity(City city) { return cityDao.updateCity(city); } @Override public Long deleteCity(Long id) { return cityDao.deleteCity(id); } } ================================================ FILE: springboot-freemarker/src/main/resources/application.properties ================================================ ## 数据源配置 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml ## Freemarker 配置 ## 文件配置路径 spring.freemarker.template-loader-path=classpath:/web/ spring.freemarker.cache=false spring.freemarker.charset=UTF-8 spring.freemarker.check-template-location=true spring.freemarker.content-type=text/html spring.freemarker.expose-request-attributes=true spring.freemarker.expose-session-attributes=true spring.freemarker.request-context-attribute=request spring.freemarker.suffix=.ftl ================================================ FILE: springboot-freemarker/src/main/resources/mapper/CityMapper.xml ================================================ id, province_id, city_name, description insert into city(id,province_id,city_name,description) values (#{id},#{provinceId},#{cityName},#{description}) update city set province_id = #{provinceId}, city_name = #{cityName}, description = #{description} where id = #{id} delete from city where id = #{id} ================================================ FILE: springboot-freemarker/src/main/resources/web/city.ftl ================================================ City: ${city.cityName}!
Q:Why I like?
A:${city.description}! ================================================ FILE: springboot-freemarker/src/main/resources/web/cityList.ftl ================================================ <#list cityList as city> City: ${city.cityName}!
Q:Why I like?
A:${city.description}! ================================================ FILE: springboot-hbase/pom.xml ================================================ 4.0.0 springboot springboot-hbase 0.0.1-SNAPSHOT springboot-hbase org.springframework.boot spring-boot-starter-parent 1.5.6.RELEASE 1.0.0.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test com.spring4all spring-boot-starter-hbase ${hbase-spring-boot} junit junit 4.12 ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * Created by bysocket on 07/02/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city/save", method = RequestMethod.GET) public City save() { cityService.saveOrUpdate(); City city = new City(); city.setAge(1); return city; } @RequestMapping(value = "/api/city/get", method = RequestMethod.GET) public City getCity() { return cityService.query("135xxxxxx"); } } ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/dao/CityRowMapper.java ================================================ package org.spring.springboot.dao; import com.spring4all.spring.boot.starter.hbase.api.RowMapper; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; import org.spring.springboot.domain.City; public class CityRowMapper implements RowMapper { private static byte[] COLUMN_FAMILY = "f".getBytes(); private static byte[] NAME = "name".getBytes(); private static byte[] AGE = "age".getBytes(); @Override public City mapRow(Result result, int rowNum) throws Exception { String name = Bytes.toString(result.getValue(COLUMN_FAMILY, NAME)); int age = Bytes.toInt(result.getValue(COLUMN_FAMILY, AGE)); City dto = new City(); dto.setCityName(name); dto.setAge(age); return dto; } } ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份年龄 */ private Integer age; /** * 城市名称 */ private String cityName; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } } ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市业务逻辑接口类 *

* Created by bysocket on 07/02/2017. */ public interface CityService { List query(String startRow, String stopRow); public City query(String row); void saveOrUpdate(); } ================================================ FILE: springboot-hbase/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import com.spring4all.spring.boot.starter.hbase.api.HbaseTemplate; import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.util.Bytes; import org.spring.springboot.dao.CityRowMapper; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * 城市业务逻辑实现类 *

* Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { @Autowired private HbaseTemplate hbaseTemplate; public List query(String startRow, String stopRow) { Scan scan = new Scan(Bytes.toBytes(startRow), Bytes.toBytes(stopRow)); scan.setCaching(5000); List dtos = this.hbaseTemplate.find("people_table", scan, new CityRowMapper()); return dtos; } public City query(String row) { City dto = this.hbaseTemplate.get("people_table", row, new CityRowMapper()); return dto; } public void saveOrUpdate() { List saveOrUpdates = new ArrayList(); Put put = new Put(Bytes.toBytes("135xxxxxx")); put.addColumn(Bytes.toBytes("people"), Bytes.toBytes("name"), Bytes.toBytes("test")); saveOrUpdates.add(put); this.hbaseTemplate.saveOrUpdates("people_table", saveOrUpdates); } } ================================================ FILE: springboot-hbase/src/main/resources/application.properties ================================================ ## HBase 配置 spring.data.hbase.quorum=xxx spring.data.hbase.rootDir=xxx spring.data.hbase.nodeParent=xxx ================================================ FILE: springboot-helloworld/pom.xml ================================================ 4.0.0 springboot springboot-helloworld 0.0.1-SNAPSHOT springboot-helloworld org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: springboot-helloworld/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-helloworld/src/main/java/org/spring/springboot/web/HelloWorldController.java ================================================ package org.spring.springboot.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Spring Boot HelloWorld 案例 * * Created by bysocket on 16/4/26. */ @RestController public class HelloWorldController { @RequestMapping("/") public String sayHello() { return "Hello,World!"; } } ================================================ FILE: springboot-helloworld/src/test/java/org/spring/springboot/web/HelloWorldControllerTest.java ================================================ package org.spring.springboot.web; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Spring Boot HelloWorldController 测试 - {@link HelloWorldController} * * Created by bysocket on 16/4/26. */ public class HelloWorldControllerTest { @Test public void testSayHello() { assertEquals("Hello,World!",new HelloWorldController().sayHello()); } } ================================================ FILE: springboot-mybatis/pom.xml ================================================ 4.0.0 springboot springboot-mybatis 0.0.1-SNAPSHOT springboot-mybatis org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} junit junit 4.12 ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.mybatis.spring.annotation.MapperScan; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication // mapper 接口类扫描包配置 @MapperScan("org.spring.springboot.dao") public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by bysocket on 07/02/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city", method = RequestMethod.GET) public City findOneCity(@RequestParam(value = "cityName", required = true) String cityName) { return cityService.findCityByName(cityName); } } ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/dao/CityDao.java ================================================ package org.spring.springboot.dao; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.City; /** * 城市 DAO 接口类 * * Created by bysocket on 07/02/2017. */ public interface CityDao { /** * 根据城市名称,查询城市信息 * * @param cityName 城市名 */ City findByName(@Param("cityName") String cityName); } ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; /** * 城市业务逻辑接口类 * * Created by bysocket on 07/02/2017. */ public interface CityService { /** * 根据城市名称,查询城市信息 * @param cityName */ City findCityByName(String cityName); } ================================================ FILE: springboot-mybatis/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 城市业务逻辑实现类 * * Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { @Autowired private CityDao cityDao; public City findCityByName(String cityName) { return cityDao.findByName(cityName); } } ================================================ FILE: springboot-mybatis/src/main/resources/application.properties ================================================ ## 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml ================================================ FILE: springboot-mybatis/src/main/resources/mapper/CityMapper.xml ================================================ id, province_id, city_name, description ================================================ FILE: springboot-mybatis-annotation/pom.xml ================================================ 4.0.0 springboot springboot-mybatis-annotation 0.0.1-SNAPSHOT jar springboot-mybatis-annotation Springboot-mybatis org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} junit junit 4.12 ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; 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); } } ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by xchunzhao on 02/05/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city", method = RequestMethod.GET) public City findOneCity(@RequestParam(value = "cityName", required = true) String cityName) { return cityService.findCityByName(cityName); } } ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/dao/CityDao.java ================================================ package org.spring.springboot.dao; import org.apache.ibatis.annotations.*; import org.spring.springboot.domain.City; /** * 城市 DAO 接口类 * * Created by xchunzhao on 02/05/2017. */ @Mapper // 标志为 Mybatis 的 Mapper public interface CityDao { /** * 根据城市名称,查询城市信息 * * @param cityName 城市名 */ @Select("SELECT * FROM city") // 返回 Map 结果集 @Results({ @Result(property = "id", column = "id"), @Result(property = "provinceId", column = "province_id"), @Result(property = "cityName", column = "city_name"), @Result(property = "description", column = "description"), }) City findByName(@Param("cityName") String cityName); } ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * * Created by xchunzhao on 02/05/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; /** * 城市业务逻辑接口类 * * Created by xchunzhao on 02/05/2017. */ public interface CityService { /** * 根据城市名称,查询城市信息 * @param cityName */ City findCityByName(String cityName); } ================================================ FILE: springboot-mybatis-annotation/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 城市业务逻辑实现类 * * Created by xchunzhao on 02/05/2017. */ @Service public class CityServiceImpl implements CityService { @Autowired private CityDao cityDao; public City findCityByName(String cityName) { return cityDao.findByName(cityName); } } ================================================ FILE: springboot-mybatis-annotation/src/main/resources/application.properties ================================================ ## 数据源配置 spring.datasource.url=jdbc:mysql://139.224.14.39:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=yt0923666 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ================================================ FILE: springboot-mybatis-mutil-datasource/pom.xml ================================================ 4.0.0 springboot springboot-mybatis-mutil-datasource 0.0.1-SNAPSHOT springboot-mybatis-mutil-datasource org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 1.0.18 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} com.alibaba druid ${druid} junit junit 4.12 ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/config/ds/ClusterDataSourceConfig.java ================================================ package org.spring.springboot.config.ds; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration // 扫描 Mapper 接口并容器管理 @MapperScan(basePackages = ClusterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "clusterSqlSessionFactory") public class ClusterDataSourceConfig { // 精确到 cluster 目录,以便跟其他数据源隔离 static final String PACKAGE = "org.spring.springboot.dao.cluster"; static final String MAPPER_LOCATION = "classpath:mapper/cluster/*.xml"; @Value("${cluster.datasource.url}") private String url; @Value("${cluster.datasource.username}") private String user; @Value("${cluster.datasource.password}") private String password; @Value("${cluster.datasource.driverClassName}") private String driverClass; @Bean(name = "clusterDataSource") public DataSource clusterDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(user); dataSource.setPassword(password); return dataSource; } @Bean(name = "clusterTransactionManager") public DataSourceTransactionManager clusterTransactionManager() { return new DataSourceTransactionManager(clusterDataSource()); } @Bean(name = "clusterSqlSessionFactory") public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource clusterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(clusterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(ClusterDataSourceConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/config/ds/MasterDataSourceConfig.java ================================================ package org.spring.springboot.config.ds; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration // 扫描 Mapper 接口并容器管理 @MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourceConfig { // 精确到 master 目录,以便跟其他数据源隔离 static final String PACKAGE = "org.spring.springboot.dao.master"; static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml"; @Value("${master.datasource.url}") private String url; @Value("${master.datasource.username}") private String user; @Value("${master.datasource.password}") private String password; @Value("${master.datasource.driverClassName}") private String driverClass; @Bean(name = "masterDataSource") @Primary public DataSource masterDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(user); dataSource.setPassword(password); return dataSource; } @Bean(name = "masterTransactionManager") @Primary public DataSourceTransactionManager masterTransactionManager() { return new DataSourceTransactionManager(masterDataSource()); } @Bean(name = "masterSqlSessionFactory") @Primary public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(masterDataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(MasterDataSourceConfig.MAPPER_LOCATION)); return sessionFactory.getObject(); } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/controller/UserRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.domain.User; import org.spring.springboot.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * 用户控制层 * * Created by bysocket on 07/02/2017. */ @RestController public class UserRestController { @Autowired private UserService userService; /** * 根据用户名获取用户信息,包括从库的地址信息 * * @param userName * @return */ @RequestMapping(value = "/api/user", method = RequestMethod.GET) public User findByName(@RequestParam(value = "userName", required = true) String userName) { return userService.findByName(userName); } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/dao/cluster/CityDao.java ================================================ package org.spring.springboot.dao.cluster; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.City; /** * 城市 DAO 接口类 * * Created by bysocket on 07/02/2017. */ @Mapper public interface CityDao { /** * 根据城市名称,查询城市信息 * * @param cityName 城市名 */ City findByName(@Param("cityName") String cityName); } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/dao/master/UserDao.java ================================================ package org.spring.springboot.dao.master; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.User; /** * 用户 DAO 接口类 * * Created by bysocket on 07/02/2017. */ @Mapper public interface UserDao { /** * 根据用户名获取用户信息 * * @param userName * @return */ User findByName(@Param("userName") String userName); } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/domain/User.java ================================================ package org.spring.springboot.domain; /** * 用户实体类 * * Created by bysocket on 07/02/2017. */ public class User { /** * 城市编号 */ private Long id; /** * 城市名称 */ private String userName; /** * 描述 */ private String description; private City city; public City getCity() { return city; } public void setCity(City city) { this.city = city; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/service/UserService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import org.spring.springboot.domain.User; /** * 用户业务接口层 * * Created by bysocket on 07/02/2017. */ public interface UserService { /** * 根据用户名获取用户信息,包括从库的地址信息 * * @param userName * @return */ User findByName(String userName); } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/java/org/spring/springboot/service/impl/UserServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.spring.springboot.dao.cluster.CityDao; import org.spring.springboot.dao.master.UserDao; import org.spring.springboot.domain.City; import org.spring.springboot.domain.User; import org.spring.springboot.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 用户业务实现层 * * Created by bysocket on 07/02/2017. */ @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; // 主数据源 @Autowired private CityDao cityDao; // 从数据源 @Override public User findByName(String userName) { User user = userDao.findByName(userName); City city = cityDao.findByName("温岭市"); user.setCity(city); return user; } } ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/resources/application.properties ================================================ ## master 数据源配置 master.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 master.datasource.username=root master.datasource.password=123456 master.datasource.driverClassName=com.mysql.jdbc.Driver ## cluster 数据源配置 cluster.datasource.url=jdbc:mysql://localhost:3306/springbootdb_cluster?useUnicode=true&characterEncoding=utf8 cluster.datasource.username=root cluster.datasource.password=123456 cluster.datasource.driverClassName=com.mysql.jdbc.Driver ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/resources/mapper/cluster/CityMapper.xml ================================================ id, province_id, city_name, description ================================================ FILE: springboot-mybatis-mutil-datasource/src/main/resources/mapper/master/UserMapper.xml ================================================ id, user_name, description ================================================ FILE: springboot-mybatis-redis/pom.xml ================================================ 4.0.0 springboot springboot-mybatis-redis 0.0.1-SNAPSHOT springboot-mybatis-redis org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 1.3.2.RELEASE org.springframework.boot spring-boot-starter-redis ${spring-boot-starter-redis-version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} junit junit 4.12 ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.mybatis.spring.annotation.MapperScan; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication // mapper 接口类扫描包配置 @MapperScan("org.spring.springboot.dao") public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.util.List; /** * Created by bysocket on 07/02/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city/{id}", method = RequestMethod.GET) public City findOneCity(@PathVariable("id") Long id) { return cityService.findCityById(id); } @RequestMapping(value = "/api/city", method = RequestMethod.POST) public void createCity(@RequestBody City city) { cityService.saveCity(city); } @RequestMapping(value = "/api/city", method = RequestMethod.PUT) public void modifyCity(@RequestBody City city) { cityService.updateCity(city); } @RequestMapping(value = "/api/city/{id}", method = RequestMethod.DELETE) public void modifyCity(@PathVariable("id") Long id) { cityService.deleteCity(id); } } ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/dao/CityDao.java ================================================ package org.spring.springboot.dao; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.City; import java.util.List; /** * 城市 DAO 接口类 * * Created by bysocket on 07/02/2017. */ public interface CityDao { /** * 获取城市信息列表 * * @return */ List findAllCity(); /** * 根据城市 ID,获取城市信息 * * @param id * @return */ City findById(@Param("id") Long id); Long saveCity(City city); Long updateCity(City city); Long deleteCity(Long id); } ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "City{" + "id=" + id + ", provinceId=" + provinceId + ", cityName='" + cityName + '\'' + ", description='" + description + '\'' + '}'; } } ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市业务逻辑接口类 * * Created by bysocket on 07/02/2017. */ public interface CityService { /** * 根据城市 ID,查询城市信息 * * @param id * @return */ City findCityById(Long id); /** * 新增城市信息 * * @param city * @return */ Long saveCity(City city); /** * 更新城市信息 * * @param city * @return */ Long updateCity(City city); /** * 根据城市 ID,删除城市信息 * * @param id * @return */ Long deleteCity(Long id); } ================================================ FILE: springboot-mybatis-redis/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import java.util.List; import java.util.concurrent.TimeUnit; /** * 城市业务逻辑实现类 *

* Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class); @Autowired private CityDao cityDao; @Autowired private RedisTemplate redisTemplate; /** * 获取城市逻辑: * 如果缓存存在,从缓存中获取城市信息 * 如果缓存不存在,从 DB 中获取城市信息,然后插入缓存 */ public City findCityById(Long id) { // 从缓存中获取城市信息 String key = "city_" + id; ValueOperations operations = redisTemplate.opsForValue(); // 缓存存在 boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { City city = operations.get(key); LOGGER.info("CityServiceImpl.findCityById() : 从缓存中获取了城市 >> " + city.toString()); return city; } // 从 DB 中获取城市信息 City city = cityDao.findById(id); // 插入缓存 operations.set(key, city, 10, TimeUnit.SECONDS); LOGGER.info("CityServiceImpl.findCityById() : 城市插入缓存 >> " + city.toString()); return city; } @Override public Long saveCity(City city) { return cityDao.saveCity(city); } /** * 更新城市逻辑: * 如果缓存存在,删除 * 如果缓存不存在,不操作 */ @Override public Long updateCity(City city) { Long ret = cityDao.updateCity(city); // 缓存存在,删除缓存 String key = "city_" + city.getId(); boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); LOGGER.info("CityServiceImpl.updateCity() : 从缓存中删除城市 >> " + city.toString()); } return ret; } @Override public Long deleteCity(Long id) { Long ret = cityDao.deleteCity(id); // 缓存存在,删除缓存 String key = "city_" + id; boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); LOGGER.info("CityServiceImpl.deleteCity() : 从缓存中删除城市 ID >> " + id); } return ret; } } ================================================ FILE: springboot-mybatis-redis/src/main/resources/application.properties ================================================ ## 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml ## Redis 配置 ## Redis数据库索引(默认为0) spring.redis.database=0 ## Redis服务器地址 spring.redis.host=127.0.0.1 ## Redis服务器连接端口 spring.redis.port=6379 ## Redis服务器连接密码(默认为空) spring.redis.password= ## 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 ## 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 ## 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 ## 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 ## 连接超时时间(毫秒) spring.redis.timeout=0 ================================================ FILE: springboot-mybatis-redis/src/main/resources/mapper/CityMapper.xml ================================================ id, province_id, city_name, description insert into city(id,province_id,city_name,description) values (#{id},#{provinceId},#{cityName},#{description}) update city set province_id = #{provinceId}, city_name = #{cityName}, description = #{description} where id = #{id} delete from city where id = #{id} ================================================ FILE: springboot-mybatis-redis-annotation/pom.xml ================================================ 4.0.0 springboot springboot-mybatis-redis-annotation 0.0.1-SNAPSHOT springboot-mybatis-redis-annotation org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 1.2.32 org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-mybatis-redis-annotation/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-mybatis-redis-annotation/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public City(Long id, Long provinceId, String cityName, String description) { this.id = id; this.provinceId = provinceId; this.cityName = cityName; this.description = description; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "City{" + "id=" + id + ", provinceId=" + provinceId + ", cityName='" + cityName + '\'' + ", description='" + description + '\'' + '}'; } } ================================================ FILE: springboot-mybatis-redis-annotation/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市业务逻辑接口类 * * Created by bysocket on 07/02/2017. */ public interface CityService { /** * 获取城市 * */ City getCityByName(String cityName); /** * 新增城市信息 * */ void saveCity(City city); /** * 更新城市信息 * */ void updateCityDescription(String cityName, String description); } ================================================ FILE: springboot-mybatis-redis-annotation/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; /** * 城市业务逻辑实现类 *

* Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { // 模拟数据库存储 private Map cityMap = new HashMap(); public void saveCity(City city){ // 模拟数据库插入操作 cityMap.put(city.getCityName(), city); } @Cacheable(value = "baseCityInfo") public City getCityByName(String cityName){ // 模拟数据库查询并返回 return cityMap.get(cityName); } @CachePut(value = "baseCityInfo") public void updateCityDescription(String cityName, String description){ City city = cityMap.get(cityName); city.setDescription(description); // 模拟更新数据库 cityMap.put(cityName, city); } } ================================================ FILE: springboot-mybatis-redis-annotation/src/main/resources/application.properties ================================================ ## Redis 配置 ## Redis数据库索引(默认为0) spring.redis.database=0 ## Redis服务器地址 spring.redis.host=127.0.0.1 ## Redis服务器连接端口 spring.redis.port=6379 ## Redis服务器连接密码(默认为空) spring.redis.password= ## 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 ## 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 ## 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 ## 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 ## 连接超时时间(毫秒) spring.redis.timeout=0 ================================================ FILE: springboot-mybatis-redis-annotation/src/test/org/spring/springboot/ApplicationTests.java ================================================ package org.spring.springboot; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.spring.springboot.service.impl.CityServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * Created by bysocket on 05/06/2017. */ @RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class); @Autowired private CityService cityService; @Test public void testRedis() { City city = getShanghai(); // 向 redis 中存入数据 cityService.saveCity(city); // 从 redis 中取数据 City cityInfo = cityService.getCityByName("上海"); LOGGER.info(cityInfo.toString()); } @Test public void testRedisCache() { City city = getBeijing(); // 向 redis 中存入数据 cityService.saveCity(city); // 从 redis 中取数据, 第一次查询 City cityInfo = cityService.getCityByName("北京"); LOGGER.info("第一次查询:" + cityInfo.toString()); // 从 redis 中取数据, 第二次查询 cityInfo = cityService.getCityByName("北京"); LOGGER.info("第二次查询:" + cityInfo.toString()); // 更新 city 的描述信息后查询 cityService.updateCityDescription("北京", "想不想去北京玩玩呢?"); cityInfo = cityService.getCityByName("北京"); LOGGER.info("更新描述后查询:" + cityInfo.toString()); } private City getShanghai(){ return new City(1L, 10L, "上海", "人称魔都的地方"); } private City getBeijing(){ return new City(2L, 20L, "北京", "中国帝都"); } } ================================================ FILE: springboot-properties/pom.xml ================================================ 4.0.0 springboot springboot-properties 0.0.1-SNAPSHOT springboot-properties org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test junit junit 4.12 org.springframework.boot spring-boot-test 1.4.2.RELEASE test org.springframework.boot spring-boot-maven-plugin 2.1.3.RELEASE org.apache.maven.plugins maven-surefire-plugin 2.12.4 true ================================================ FILE: springboot-properties/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.spring.springboot.property.HomeProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 *

* Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private HomeProperties homeProperties; public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { System.out.println("\n" + homeProperties.toString()); System.out.println(); } } ================================================ FILE: springboot-properties/src/main/java/org/spring/springboot/property/HomeProperties.java ================================================ package org.spring.springboot.property; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 家乡属性 * * Created by bysocket on 17/04/2017. */ @Component @ConfigurationProperties(prefix = "home") public class HomeProperties { /** * 省份 */ private String province; /** * 城市 */ private String city; /** * 描述 */ private String desc; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "HomeProperties{" + "province='" + province + '\'' + ", city='" + city + '\'' + ", desc='" + desc + '\'' + '}'; } } ================================================ FILE: springboot-properties/src/main/java/org/spring/springboot/property/UserProperties.java ================================================ package org.spring.springboot.property; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * Created by bysocket on 20/04/2017. */ @Component @ConfigurationProperties(prefix = "user") public class UserProperties { /** * 用户 ID */ private Long id; /** * 年龄 */ private int age; /** * 用户名称 */ private String desc; /** * 用户 UUID */ private String uuid; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { return "UserProperties{" + "id=" + id + ", age=" + age + ", desc='" + desc + '\'' + ", uuid='" + uuid + '\'' + '}'; } } ================================================ FILE: springboot-properties/src/main/java/org/spring/springboot/web/HelloWorldController.java ================================================ package org.spring.springboot.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Spring Boot HelloWorld 案例 * * Created by bysocket on 16/4/26. */ @RestController public class HelloWorldController { @RequestMapping("/") public String sayHello() { return "Hello,World!"; } } ================================================ FILE: springboot-properties/src/main/resources/application-dev.properties ================================================ ## 家乡属性 Dev home.province=ZheJiang home.city=WenLing home.desc=dev: I'm living in ${home.province} ${home.city}. ================================================ FILE: springboot-properties/src/main/resources/application-prod.properties ================================================ ## 家乡属性 Prod home.province=ZheJiang home.city=WenLing home.desc=prod: I'm living in ${home.province} ${home.city}. ================================================ FILE: springboot-properties/src/main/resources/application.properties ================================================ # Spring Profiles Active spring.profiles.active=dev ================================================ FILE: springboot-properties/src/test/java/org/spring/springboot/property/HomeProperties1.java ================================================ package org.spring.springboot.property; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 家乡属性 * * Created by bysocket on 17/04/2017. */ @Component public class HomeProperties1 { /** * 省份 */ @Value("${home.province}") private String province; /** * 城市 */ @Value("${home.city}") private String city; /** * 描述 */ @Value("${home.desc}") private String desc; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override public String toString() { return "HomeProperties1{" + "province='" + province + '\'' + ", city='" + city + '\'' + ", desc='" + desc + '\'' + '}'; } } ================================================ FILE: springboot-properties/src/test/java/org/spring/springboot/property/PropertiesTest.java ================================================ package org.spring.springboot.property; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * 自定义配置文件测试类 *

* Created by bysocket on 17/04/2017. */ @RunWith(SpringRunner.class) @SpringBootTest public class PropertiesTest { private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesTest.class); @Autowired private UserProperties userProperties; @Autowired private HomeProperties homeProperties; @Test public void getHomeProperties() { LOGGER.info("\n\n" + homeProperties.toString() + "\n"); } @Test public void randomTestUser() { LOGGER.info("\n\n" + userProperties.toString() + "\n"); } } ================================================ FILE: springboot-properties/src/test/java/org/spring/springboot/web/HelloWorldControllerTest.java ================================================ package org.spring.springboot.web; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Spring Boot HelloWorldController 测试 - {@link HelloWorldController} * * Created by bysocket on 16/4/26. */ public class HelloWorldControllerTest { @Test public void testSayHello() { assertEquals("Hello,World!",new HelloWorldController().sayHello()); } } ================================================ FILE: springboot-properties/src/test/resouorces/application.yml ================================================ ## 家乡属性 home: province: 浙江省 city: 温岭松门 desc: 我家住在${home.province}的${home.city} ## 随机属性 user: id: ${random.long} age: ${random.int[1,200]} desc: 泥瓦匠叫做${random.value} uuid: ${random.uuid} ================================================ FILE: springboot-restful/pom.xml ================================================ 4.0.0 springboot springboot-restful 0.0.1-SNAPSHOT springboot-restful org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE 1.2.0 5.1.39 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis-spring-boot} mysql mysql-connector-java ${mysql-connector} junit junit 4.12 ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.mybatis.spring.annotation.MapperScan; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication // mapper 接口类扫描包配置 @MapperScan("org.spring.springboot.dao") public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/controller/CityRestController.java ================================================ package org.spring.springboot.controller; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import java.util.List; /** * 城市 Controller 实现 Restful HTTP 服务 * * Created by bysocket on 07/02/2017. */ @RestController public class CityRestController { @Autowired private CityService cityService; @RequestMapping(value = "/api/city/{id}", method = RequestMethod.GET) public City findOneCity(@PathVariable("id") Long id) { return cityService.findCityById(id); } @RequestMapping(value = "/api/city", method = RequestMethod.GET) public List findAllCity() { return cityService.findAllCity(); } @RequestMapping(value = "/api/city", method = RequestMethod.POST) public void createCity(@RequestBody City city) { cityService.saveCity(city); } @RequestMapping(value = "/api/city", method = RequestMethod.PUT) public void modifyCity(@RequestBody City city) { cityService.updateCity(city); } @RequestMapping(value = "/api/city/{id}", method = RequestMethod.DELETE) public void modifyCity(@PathVariable("id") Long id) { cityService.deleteCity(id); } } ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/dao/CityDao.java ================================================ package org.spring.springboot.dao; import org.apache.ibatis.annotations.Param; import org.spring.springboot.domain.City; import java.util.List; /** * 城市 DAO 接口类 * * Created by bysocket on 07/02/2017. */ public interface CityDao { /** * 获取城市信息列表 * * @return */ List findAllCity(); /** * 根据城市 ID,获取城市信息 * * @param id * @return */ City findById(@Param("id") Long id); Long saveCity(City city); Long updateCity(City city); Long deleteCity(Long id); } ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/service/CityService.java ================================================ package org.spring.springboot.service; import org.spring.springboot.domain.City; import java.util.List; /** * 城市业务逻辑接口类 * * Created by bysocket on 07/02/2017. */ public interface CityService { /** * 获取城市信息列表 * * @return */ List findAllCity(); /** * 根据城市 ID,查询城市信息 * * @param id * @return */ City findCityById(Long id); /** * 新增城市信息 * * @param city * @return */ Long saveCity(City city); /** * 更新城市信息 * * @param city * @return */ Long updateCity(City city); /** * 根据城市 ID,删除城市信息 * * @param id * @return */ Long deleteCity(Long id); } ================================================ FILE: springboot-restful/src/main/java/org/spring/springboot/service/impl/CityServiceImpl.java ================================================ package org.spring.springboot.service.impl; import org.spring.springboot.dao.CityDao; import org.spring.springboot.domain.City; import org.spring.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 城市业务逻辑实现类 * * Created by bysocket on 07/02/2017. */ @Service public class CityServiceImpl implements CityService { @Autowired private CityDao cityDao; public List findAllCity(){ return cityDao.findAllCity(); } public City findCityById(Long id) { return cityDao.findById(id); } @Override public Long saveCity(City city) { return cityDao.saveCity(city); } @Override public Long updateCity(City city) { return cityDao.updateCity(city); } @Override public Long deleteCity(Long id) { return cityDao.deleteCity(id); } } ================================================ FILE: springboot-restful/src/main/resources/application.properties ================================================ ## 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml ================================================ FILE: springboot-restful/src/main/resources/mapper/CityMapper.xml ================================================ id, province_id, city_name, description insert into city(id,province_id,city_name,description) values (#{id},#{provinceId},#{cityName},#{description}) update city set province_id = #{provinceId}, city_name = #{cityName}, description = #{description} where id = #{id} delete from city where id = #{id} ================================================ FILE: springboot-validation-over-json/pom.xml ================================================ 4.0.0 springboot springboot-validation-over-json 0.0.1-SNAPSHOT springboot-validation-over-json org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web junit junit 4.12 ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 16/4/26. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/constant/CityErrorInfoEnum.java ================================================ package org.spring.springboot.constant; import org.spring.springboot.result.ErrorInfoInterface; /** * 业务错误码 案例 * * Created by bysocket on 14/03/2017. */ public enum CityErrorInfoEnum implements ErrorInfoInterface { PARAMS_NO_COMPLETE("000001","params no complete"), CITY_EXIT("000002","city exit"); private String code; private String message; CityErrorInfoEnum(String code, String message) { this.code = code; this.message = message; } public String getCode(){ return this.code; } public String getMessage(){ return this.message; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/result/ErrorInfoInterface.java ================================================ package org.spring.springboot.result; /** * 错误码接口 * * Created by bysocket on 13/03/2017. */ public interface ErrorInfoInterface { String getCode(); String getMessage(); } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/result/GlobalErrorInfoEnum.java ================================================ package org.spring.springboot.result; /** * 应用系统级别的错误码 * * Created by bysocket on 14/03/2017. */ public enum GlobalErrorInfoEnum implements ErrorInfoInterface{ SUCCESS("0", "success"), NOT_FOUND("-1", "service not found"); private String code; private String message; GlobalErrorInfoEnum(String code, String message) { this.code = code; this.message = message; } public String getCode(){ return this.code; } public String getMessage(){ return this.message; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/result/GlobalErrorInfoException.java ================================================ package org.spring.springboot.result; /** * 统一错误码异常 * * Created by bysocket on 14/03/2017. */ public class GlobalErrorInfoException extends Exception { private ErrorInfoInterface errorInfo; public GlobalErrorInfoException (ErrorInfoInterface errorInfo) { this.errorInfo = errorInfo; } public ErrorInfoInterface getErrorInfo() { return errorInfo; } public void setErrorInfo(ErrorInfoInterface errorInfo) { this.errorInfo = errorInfo; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/result/GlobalErrorInfoHandler.java ================================================ package org.spring.springboot.result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; /** * 统一错误码异常处理 * * Created by bysocket on 14/03/2017. */ @RestControllerAdvice public class GlobalErrorInfoHandler { @ExceptionHandler(value = GlobalErrorInfoException.class) public ResultBody errorHandlerOverJson(HttpServletRequest request, GlobalErrorInfoException exception) { ErrorInfoInterface errorInfo = exception.getErrorInfo(); ResultBody result = new ResultBody(errorInfo); return result; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/result/ResultBody.java ================================================ package org.spring.springboot.result; /** * 返回体 * * Created by bysocket on 14/03/2017. */ public class ResultBody { /** * 响应代码 */ private String code; /** * 响应消息 */ private String message; /** * 响应结果 */ private Object result; public ResultBody(ErrorInfoInterface errorInfo) { this.code = errorInfo.getCode(); this.message = errorInfo.getMessage(); } public ResultBody(Object result) { this.code = GlobalErrorInfoEnum.SUCCESS.getCode(); this.message = GlobalErrorInfoEnum.SUCCESS.getMessage(); this.result = result; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/web/City.java ================================================ package org.spring.springboot.web; import java.io.Serializable; /** * 城市实体类 * * Created by bysocket on 07/02/2017. */ public class City implements Serializable { private static final long serialVersionUID = -1L; /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public City() { } public City(Long id, Long provinceId, String cityName, String description) { this.id = id; this.provinceId = provinceId; this.cityName = cityName; this.description = description; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-validation-over-json/src/main/java/org/spring/springboot/web/ErrorJsonController.java ================================================ package org.spring.springboot.web; import org.spring.springboot.constant.CityErrorInfoEnum; import org.spring.springboot.result.GlobalErrorInfoException; import org.spring.springboot.result.ResultBody; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * 错误码案例 * * Created by bysocket on 16/4/26. */ @RestController public class ErrorJsonController { /** * 获取城市接口 * * @param cityName * @return * @throws GlobalErrorInfoException */ @RequestMapping(value = "/api/city", method = RequestMethod.GET) public ResultBody findOneCity(@RequestParam("cityName") String cityName) throws GlobalErrorInfoException { // 入参为空 if (StringUtils.isEmpty(cityName)) { throw new GlobalErrorInfoException(CityErrorInfoEnum.PARAMS_NO_COMPLETE); } return new ResultBody(new City(1L,2L,"温岭","是我的故乡")); } } ================================================ FILE: springboot-validation-over-json/src/test/java/org/spring/springboot/web/ErrorJsonControllerTest.java ================================================ package org.spring.springboot.web; import org.junit.Test; /** * Spring Boot ErrorJsonController 测试 - {@link ErrorJsonController} * * Created by bysocket on 16/4/26. */ public class ErrorJsonControllerTest { @Test public void testSayHello() { } } ================================================ FILE: springboot-webflux-1-quickstart/pom.xml ================================================ 4.0.0 springboot springboot-webflux-1-quickstart 0.0.1-SNAPSHOT springboot-webflux-1-quickstart org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-test test io.projectreactor reactor-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: springboot-webflux-1-quickstart/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 09/29/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-1-quickstart/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; @Component public class CityHandler { public Mono helloCity(ServerRequest request) { return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN) .body(BodyInserters.fromObject("Hello, City!")); } } ================================================ FILE: springboot-webflux-1-quickstart/src/main/java/org/spring/springboot/router/CityRouter.java ================================================ package org.spring.springboot.router; import org.spring.springboot.handler.CityHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; @Configuration public class CityRouter { @Bean public RouterFunction routeCity(CityHandler cityHandler) { return RouterFunctions .route(RequestPredicates.GET("/hello") .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), cityHandler::helloCity); } } ================================================ FILE: springboot-webflux-1-quickstart/src/main/resources/application.properties ================================================ ================================================ FILE: springboot-webflux-10-book-manage-sys/pom.xml ================================================ 4.0.0 WebFlux 实战城市管理系统 demo.springboot springboot-webflux-10-book-manage-sys 1.0 jar org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/WebApplication.java ================================================ package demo.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket */ @SpringBootApplication public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/dao/CityRepository.java ================================================ package demo.springboot.dao; import demo.springboot.domain.City; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; @Repository public interface CityRepository extends ReactiveMongoRepository { } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/domain/City.java ================================================ package demo.springboot.domain; /** * 城市实体类 * */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/service/CityService.java ================================================ package demo.springboot.service; import demo.springboot.domain.City; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; public interface CityService { Flux findAll(); Mono insertByCity(City city); Mono update(City city); Mono delete(Long id); Mono findById(Long id); } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/service/impl/CityServiceImpl.java ================================================ package demo.springboot.service.impl; import demo.springboot.dao.CityRepository; import demo.springboot.domain.City; import demo.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityServiceImpl implements CityService { private final CityRepository cityRepository; @Autowired public CityServiceImpl(CityRepository cityRepository) { this.cityRepository = cityRepository; } @Override public Flux findAll() { return cityRepository.findAll(); } @Override public Mono insertByCity(City city) { return cityRepository.save(city); } @Override public Mono update(City city) { return cityRepository.save(city); } @Override public Mono delete(Long id) { return cityRepository.deleteById(id); } @Override public Mono findById(Long id) { return cityRepository.findById(id); } } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/java/demo/springboot/web/CityController.java ================================================ package demo.springboot.web; import demo.springboot.domain.City; import demo.springboot.service.CityService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import reactor.core.publisher.Mono; import java.awt.print.Book; /** * city 控制层 *

* Created by bysocket */ @Controller @RequestMapping(value = "/city") public class CityController { private static final String CITY_FORM_PATH_NAME = "cityForm"; private static final String CITY_LIST_PATH_NAME = "cityList"; private static final String REDIRECT_TO_CITY_URL = "redirect:/city"; @Autowired CityService cityService; @RequestMapping(method = RequestMethod.GET) public String getCityList(final Model model) { model.addAttribute("cityList", cityService.findAll()); return CITY_LIST_PATH_NAME; } @RequestMapping(value = "/create", method = RequestMethod.GET) public String createCityForm(final Model model) { model.addAttribute("city", new City()); model.addAttribute("action", "create"); return CITY_FORM_PATH_NAME; } @RequestMapping(value = "/create", method = RequestMethod.POST) public String postCity(@ModelAttribute City city) { cityService.insertByCity(city); return REDIRECT_TO_CITY_URL; } @RequestMapping(value = "/update/{id}", method = RequestMethod.GET) public String getCity(@PathVariable Long id, final Model model) { final Mono city = cityService.findById(id); model.addAttribute("city", city); model.addAttribute("action", "update"); return CITY_FORM_PATH_NAME; } @RequestMapping(value = "/update", method = RequestMethod.POST) public String putBook(@ModelAttribute City city) { cityService.update(city); return REDIRECT_TO_CITY_URL; } @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) public String deleteCity(@PathVariable Long id) { cityService.delete(id); return CITY_LIST_PATH_NAME; } } ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/resources/application.properties ================================================ spring.data.mongodb.host=localhost spring.data.mongodb.database=admin spring.data.mongodb.port=27017 spring.data.mongodb.username=admin spring.data.mongodb.password=admin ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/resources/static/css/default.css ================================================ /* contentDiv */ .contentDiv {padding:20px 60px;} ================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/resources/templates/cityForm.html ================================================ 城市管理

城市管理
  
================================================ FILE: springboot-webflux-10-book-manage-sys/src/main/resources/templates/cityList.html ================================================ 城市列表
城市列表
城市编号 城市名称 描述 省份编号 管理
删除
================================================ FILE: springboot-webflux-2-restful/pom.xml ================================================ 4.0.0 springboot springboot-webflux-2-restful 0.0.1-SNAPSHOT springboot-webflux-2-restful org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-2-restful/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 09/29/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-2-restful/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @Repository public class CityRepository { private ConcurrentMap repository = new ConcurrentHashMap<>(); private static final AtomicLong idGenerator = new AtomicLong(0); public Long save(City city) { Long id = idGenerator.incrementAndGet(); city.setId(id); repository.put(id, city); return id; } public Collection findAll() { return repository.values(); } public City findCityById(Long id) { return repository.get(id); } public Long updateCity(City city) { repository.put(city.getId(), city); return city.getId(); } public Long deleteCity(Long id) { repository.remove(id); return id; } } ================================================ FILE: springboot-webflux-2-restful/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-2-restful/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.save(city))); } public Mono findCityById(Long id) { return Mono.justOrEmpty(cityRepository.findCityById(id)); } public Flux findAllCity() { return Flux.fromIterable(cityRepository.findAll()); } public Mono modifyCity(City city) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.updateCity(city))); } public Mono deleteCity(Long id) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.deleteCity(id))); } } ================================================ FILE: springboot-webflux-2-restful/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } } ================================================ FILE: springboot-webflux-2-restful/src/main/resources/application.properties ================================================ ================================================ FILE: springboot-webflux-3-mongodb/pom.xml ================================================ 4.0.0 springboot springboot-webflux-3-mongodb 0.0.1-SNAPSHOT springboot-webflux-3-mongodb org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-3-mongodb/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 09/29/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-3-mongodb/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; @Repository public interface CityRepository extends ReactiveMongoRepository { } ================================================ FILE: springboot-webflux-3-mongodb/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.annotation.Id; /** * 城市实体类 * */ public class City { /** * 城市编号 */ @Id private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-3-mongodb/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return cityRepository.save(city); } public Mono findCityById(Long id) { return cityRepository.findById(id); } public Flux findAllCity() { return cityRepository.findAll(); } public Mono modifyCity(City city) { return cityRepository.save(city); } public Mono deleteCity(Long id) { return cityRepository.deleteById(id).flatMap(mono -> Mono.create(cityMonoSink -> cityMonoSink.success(id))); } } ================================================ FILE: springboot-webflux-3-mongodb/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } } ================================================ FILE: springboot-webflux-3-mongodb/src/main/resources/application.properties ================================================ spring.data.mongodb.host=localhost spring.data.mongodb.database=admin spring.data.mongodb.port=27017 spring.data.mongodb.username=admin spring.data.mongodb.password=admin ================================================ FILE: springboot-webflux-4-thymeleaf/pom.xml ================================================ 4.0.0 springboot springboot-webflux-4-thymeleaf 0.0.1-SNAPSHOT springboot-webflux-4-thymeleaf org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @Repository public class CityRepository { private ConcurrentMap repository = new ConcurrentHashMap<>(); private static final AtomicLong idGenerator = new AtomicLong(0); public Long save(City city) { Long id = idGenerator.incrementAndGet(); city.setId(id); repository.put(id, city); return id; } public Collection findAll() { return repository.values(); } public City findCityById(Long id) { return repository.get(id); } public Long updateCity(City city) { repository.put(city.getId(), city); return city.getId(); } public Long deleteCity(Long id) { repository.remove(id); return id; } } ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.save(city))); } public Mono findCityById(Long id) { return Mono.justOrEmpty(cityRepository.findCityById(id)); } public Flux findAllCity() { return Flux.fromIterable(cityRepository.findAll()); } public Mono modifyCity(City city) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.updateCity(city))); } public Mono deleteCity(Long id) { return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.deleteCity(id))); } } ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Controller @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") @ResponseBody public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() @ResponseBody public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() @ResponseBody public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() @ResponseBody public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") @ResponseBody public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } @GetMapping("/hello") public Mono hello(final Model model) { model.addAttribute("name", "泥瓦匠"); model.addAttribute("city", "浙江温岭"); String path = "hello"; return Mono.create(monoSink -> monoSink.success(path)); } private static final String CITY_LIST_PATH_NAME = "cityList"; @GetMapping("/page/list") public String listPage(final Model model) { final Flux cityFluxList = cityHandler.findAllCity(); model.addAttribute("cityList", cityFluxList); return CITY_LIST_PATH_NAME; } } ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/resources/application.properties ================================================ ================================================ FILE: springboot-webflux-4-thymeleaf/src/main/resources/templates/cityList.html ================================================ 城市列表
城市列表
城市编号 省份编号 名称 描述
================================================ FILE: springboot-webflux-4-thymeleaf/src/main/resources/templates/hello.html ================================================ 欢迎页面

你好,欢迎来自

================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/pom.xml ================================================ 4.0.0 springboot springboot-webflux-5-thymeleaf-mongodb 0.0.1-SNAPSHOT springboot-webflux-5-thymeleaf-mongodb org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; import reactor.core.publisher.Mono; @Repository public interface CityRepository extends ReactiveMongoRepository { Mono findByCityName(String cityName); } ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; /** * 城市实体类 * */ public class City { /** * 城市编号 */ private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return cityRepository.save(city); } public Mono findCityById(Long id) { return cityRepository.findById(id); } public Flux findAllCity() { return cityRepository.findAll(); } public Mono modifyCity(City city) { return cityRepository.save(city); } public Mono deleteCity(Long id) { cityRepository.deleteById(id); return Mono.create(cityMonoSink -> cityMonoSink.success(id)); } public Mono getByCityName(String cityName) { return cityRepository.findByCityName(cityName); } } ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Controller @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") @ResponseBody public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() @ResponseBody public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() @ResponseBody public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() @ResponseBody public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") @ResponseBody public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } private static final String CITY_LIST_PATH_NAME = "cityList"; private static final String CITY_PATH_NAME = "city"; @GetMapping("/page/list") public String listPage(final Model model) { final Flux cityFluxList = cityHandler.findAllCity(); model.addAttribute("cityList", cityFluxList); return CITY_LIST_PATH_NAME; } @GetMapping("/getByName") public String getByCityName(final Model model, @RequestParam("cityName") String cityName) { final Mono city = cityHandler.getByCityName(cityName); model.addAttribute("city", city); return CITY_PATH_NAME; } } ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/resources/application.properties ================================================ spring.data.mongodb.host=localhost spring.data.mongodb.database=admin spring.data.mongodb.port=27017 spring.data.mongodb.username=admin spring.data.mongodb.password=admin ================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/resources/templates/city.html ================================================ 城市
城市单个查询
================================================ FILE: springboot-webflux-5-thymeleaf-mongodb/src/main/resources/templates/cityList.html ================================================ 城市列表
城市列表
城市编号 省份编号 名称 描述
================================================ FILE: springboot-webflux-6-redis/pom.xml ================================================ 4.0.0 springboot springboot-webflux-6-redis 0.0.1-SNAPSHOT springboot-webflux-6-redis org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-redis-reactive org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-6-redis/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-6-redis/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.annotation.Id; import java.io.Serializable; /** * 城市实体类 * */ public class City implements Serializable { private static final long serialVersionUID = -2081742442561524068L; /** * 城市编号 */ @Id private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-6-redis/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Mono; import java.util.concurrent.TimeUnit; @RestController @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private RedisTemplate redisTemplate; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { String key = "city_" + id; ValueOperations operations = redisTemplate.opsForValue(); boolean hasKey = redisTemplate.hasKey(key); City city = operations.get(key); if (!hasKey) { return Mono.create(monoSink -> monoSink.success(null)); } return Mono.create(monoSink -> monoSink.success(city)); } @PostMapping() public Mono saveCity(@RequestBody City city) { String key = "city_" + city.getId(); ValueOperations operations = redisTemplate.opsForValue(); operations.set(key, city, 60, TimeUnit.SECONDS); return Mono.create(monoSink -> monoSink.success(city)); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { String key = "city_" + id; boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); } return Mono.create(monoSink -> monoSink.success(id)); } } ================================================ FILE: springboot-webflux-6-redis/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxReactiveController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.core.ReactiveValueOperations; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Mono; @RestController @RequestMapping(value = "/city2") public class CityWebFluxReactiveController { @Autowired private ReactiveRedisTemplate reactiveRedisTemplate; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { String key = "city_" + id; ReactiveValueOperations operations = reactiveRedisTemplate.opsForValue(); Mono city = operations.get(key); return city; } @PostMapping public Mono saveCity(@RequestBody City city) { String key = "city_" + city.getId(); ReactiveValueOperations operations = reactiveRedisTemplate.opsForValue(); return operations.getAndSet(key, city); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { String key = "city_" + id; return reactiveRedisTemplate.delete(key); } } ================================================ FILE: springboot-webflux-6-redis/src/main/resources/application.properties ================================================ ## Redis 配置 ## Redis服务器地址 spring.redis.host=127.0.0.1 ## Redis服务器连接端口 spring.redis.port=6379 ## Redis服务器连接密码(默认为空) spring.redis.password= # 连接超时时间(毫秒) spring.redis.timeout=5000 ================================================ FILE: springboot-webflux-7-redis-cache/pom.xml ================================================ 4.0.0 springboot springboot-webflux-7-redis-cache 0.0.1-SNAPSHOT springboot-webflux-7-redis-cache org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-data-redis-reactive org.springframework.boot spring-boot-starter-test test junit junit 4.12 ================================================ FILE: springboot-webflux-7-redis-cache/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 SpringApplication.run(Application.class, args); } } ================================================ FILE: springboot-webflux-7-redis-cache/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; @Repository public interface CityRepository extends ReactiveMongoRepository { } ================================================ FILE: springboot-webflux-7-redis-cache/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.annotation.Id; import java.io.Serializable; /** * 城市实体类 * */ public class City implements Serializable { private static final long serialVersionUID = -2081742442561524068L; /** * 城市编号 */ @Id private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "City{" + "id=" + id + ", provinceId=" + provinceId + ", cityName='" + cityName + '\'' + ", description='" + description + '\'' + '}'; } } ================================================ FILE: springboot-webflux-7-redis-cache/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private static final Logger LOGGER = LoggerFactory.getLogger(CityHandler.class); @Autowired private RedisTemplate redisTemplate; private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return cityRepository.save(city); } public Mono findCityById(Long id) { // 从缓存中获取城市信息 String key = "city_" + id; ValueOperations operations = redisTemplate.opsForValue(); // 缓存存在 boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { City city = operations.get(key); LOGGER.info("CityHandler.findCityById() : 从缓存中获取了城市 >> " + city.toString()); return Mono.create(cityMonoSink -> cityMonoSink.success(city)); } // 从 MongoDB 中获取城市信息 Mono cityMono = cityRepository.findById(id); if (cityMono == null) return cityMono; // 插入缓存 cityMono.subscribe(cityObj -> { operations.set(key, cityObj); LOGGER.info("CityHandler.findCityById() : 城市插入缓存 >> " + cityObj.toString()); }); return cityMono; } public Flux findAllCity() { return cityRepository.findAll().cache(); } public Mono modifyCity(City city) { // 缓存存在,删除缓存 String key = "city_" + city.getId(); boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); LOGGER.info("CityHandler.modifyCity() : 从缓存中删除城市 ID >> " + city.getId()); } return cityRepository.save(city).cache(); } public Mono deleteCity(Long id) { // 缓存存在,删除缓存 String key = "city_" + id; boolean hasKey = redisTemplate.hasKey(key); if (hasKey) { redisTemplate.delete(key); LOGGER.info("CityHandler.deleteCity() : 从缓存中删除城市 ID >> " + id); } cityRepository.deleteById(id); return Mono.create(cityMonoSink -> cityMonoSink.success(id)); } } ================================================ FILE: springboot-webflux-7-redis-cache/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } } ================================================ FILE: springboot-webflux-7-redis-cache/src/main/resources/application.properties ================================================ ## Redis 配置 ## Redis服务器地址 spring.redis.host=127.0.0.1 ## Redis服务器连接端口 spring.redis.port=6379 ## Redis服务器连接密码(默认为空) spring.redis.password= # 连接超时时间(毫秒) spring.redis.timeout=5000 ## MongoDB spring.data.mongodb.host=localhost spring.data.mongodb.database=admin spring.data.mongodb.port=27017 spring.data.mongodb.username=admin spring.data.mongodb.password=admin ================================================ FILE: springboot-webflux-8-websocket/pom.xml ================================================ 4.0.0 springboot springboot-webflux-8-websocket 0.0.1-SNAPSHOT springboot-webflux-8-websocket org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ================================================ FILE: springboot-webflux-8-websocket/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 09/29/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-8-websocket/src/main/java/org/spring/springboot/config/WebSocketConfiguration.java ================================================ package org.spring.springboot.config; import org.spring.springboot.handler.EchoHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; import java.util.HashMap; import java.util.Map; @Configuration public class WebSocketConfiguration { @Autowired @Bean public HandlerMapping webSocketMapping(final EchoHandler echoHandler) { final Map map = new HashMap<>(); map.put("/echo", echoHandler); final SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(Ordered.HIGHEST_PRECEDENCE); mapping.setUrlMap(map); return mapping; } @Bean public WebSocketHandlerAdapter handlerAdapter() { return new WebSocketHandlerAdapter(); } } ================================================ FILE: springboot-webflux-8-websocket/src/main/java/org/spring/springboot/handler/EchoHandler.java ================================================ package org.spring.springboot.handler; import org.springframework.stereotype.Component; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.WebSocketSession; import reactor.core.publisher.Mono; @Component public class EchoHandler implements WebSocketHandler { @Override public Mono handle(final WebSocketSession session) { return session.send( session.receive() .map(msg -> session.textMessage( "服务端返回:小明, " + msg.getPayloadAsText()))); } } ================================================ FILE: springboot-webflux-8-websocket/src/main/resources/application.properties ================================================ ================================================ FILE: springboot-webflux-8-websocket/src/main/resources/websocket-client.html ================================================ Client WebSocket
================================================ FILE: springboot-webflux-8-websocket/src/test/java/WSClient.java ================================================ import org.springframework.web.reactive.socket.WebSocketMessage; import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient; import org.springframework.web.reactive.socket.client.WebSocketClient; import reactor.core.publisher.Flux; import java.net.URI; import java.time.Duration; public class WSClient { public static void main(final String[] args) { final WebSocketClient client = new ReactorNettyWebSocketClient(); client.execute(URI.create("ws://localhost:8080/echo"), session -> session.send(Flux.just(session.textMessage("你好"))) .thenMany(session.receive().take(1).map(WebSocketMessage::getPayloadAsText)) .doOnNext(System.out::println) .then()) .block(Duration.ofMillis(5000)); } } ================================================ FILE: springboot-webflux-9-test/pom.xml ================================================ 4.0.0 springboot springboot-webflux-9-test 0.0.1-SNAPSHOT springboot-webflux-9-test org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE org.springframework.boot spring-boot-starter-webflux org.springframework.boot spring-boot-starter-data-mongodb-reactive org.springframework.boot spring-boot-starter-test test io.projectreactor reactor-test test junit junit 4.12 ================================================ FILE: springboot-webflux-9-test/src/main/java/org/spring/springboot/Application.java ================================================ package org.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot 应用启动类 * * Created by bysocket on 09/29/2017. */ // Spring Boot 应用的标识 @SpringBootApplication public class Application { public static void main(String[] args) { // 程序启动入口 // 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件 SpringApplication.run(Application.class,args); } } ================================================ FILE: springboot-webflux-9-test/src/main/java/org/spring/springboot/dao/CityRepository.java ================================================ package org.spring.springboot.dao; import org.spring.springboot.domain.City; import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; @Repository public interface CityRepository extends ReactiveMongoRepository { } ================================================ FILE: springboot-webflux-9-test/src/main/java/org/spring/springboot/domain/City.java ================================================ package org.spring.springboot.domain; import org.springframework.data.annotation.Id; /** * 城市实体类 * */ public class City { /** * 城市编号 */ @Id private Long id; /** * 省份编号 */ private Long provinceId; /** * 城市名称 */ private String cityName; /** * 描述 */ private String description; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getProvinceId() { return provinceId; } public void setProvinceId(Long provinceId) { this.provinceId = provinceId; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } ================================================ FILE: springboot-webflux-9-test/src/main/java/org/spring/springboot/handler/CityHandler.java ================================================ package org.spring.springboot.handler; import org.spring.springboot.dao.CityRepository; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public class CityHandler { private final CityRepository cityRepository; @Autowired public CityHandler(CityRepository cityRepository) { this.cityRepository = cityRepository; } public Mono save(City city) { return cityRepository.save(city); } public Mono findCityById(Long id) { return cityRepository.findById(id); } public Flux findAllCity() { return cityRepository.findAll(); } public Mono modifyCity(City city) { return cityRepository.save(city); } public Mono deleteCity(Long id) { cityRepository.deleteById(id); return Mono.create(cityMonoSink -> cityMonoSink.success(id)); } } ================================================ FILE: springboot-webflux-9-test/src/main/java/org/spring/springboot/webflux/controller/CityWebFluxController.java ================================================ package org.spring.springboot.webflux.controller; import org.spring.springboot.domain.City; import org.spring.springboot.handler.CityHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @RequestMapping(value = "/city") public class CityWebFluxController { @Autowired private CityHandler cityHandler; @GetMapping(value = "/{id}") public Mono findCityById(@PathVariable("id") Long id) { return cityHandler.findCityById(id); } @GetMapping() public Flux findAllCity() { return cityHandler.findAllCity(); } @PostMapping() public Mono saveCity(@RequestBody City city) { return cityHandler.save(city); } @PutMapping() public Mono modifyCity(@RequestBody City city) { return cityHandler.modifyCity(city); } @DeleteMapping(value = "/{id}") public Mono deleteCity(@PathVariable("id") Long id) { return cityHandler.deleteCity(id); } } ================================================ FILE: springboot-webflux-9-test/src/main/resources/application.properties ================================================ spring.data.mongodb.host=localhost spring.data.mongodb.database=admin spring.data.mongodb.port=27017 spring.data.mongodb.username=admin spring.data.mongodb.password=admin ================================================ FILE: springboot-webflux-9-test/src/test/java/org/spring/springboot/handler/CityHandlerTest.java ================================================ package org.spring.springboot.handler; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.spring.springboot.domain.City; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.reactive.function.BodyInserters; import java.util.HashMap; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class CityHandlerTest { @Autowired private WebTestClient webClient; private static Map cityMap = new HashMap<>(); @BeforeClass public static void setup() throws Exception { City wl = new City(); wl.setId(1L); wl.setProvinceId(2L); wl.setCityName("WL"); wl.setDescription("WL IS GOOD"); cityMap.put("WL", wl); } @Test public void testSave() throws Exception { City expectCity = webClient.post().uri("/city") .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromObject(cityMap.get("WL"))) .exchange() .expectStatus().isOk() .expectBody(City.class).returnResult().getResponseBody(); Assert.assertNotNull(expectCity); Assert.assertEquals(expectCity.getId(), cityMap.get("WL").getId()); Assert.assertEquals(expectCity.getCityName(), cityMap.get("WL").getCityName()); } }