SpringBoot、Groovy


Java——搭建自己的RESTful API服務器(SpringBoot、Groovy)

 

這又是一篇JavaWeb相關的博客,內容涉及:

  • SpringBoot:微框架,提供快速構建服務的功能
  • SpringMVC:Struts的替代者
  • MyBatis:數據庫操作庫
  • Groovy:能與Java結合的高級語言,底層為Java
  • Maven:用於簡化jar包導入和打包
  • log4j:日志管理

我們要做的是一個簡單的接口,根據URL請求得到對應的數據,數據格式可以是JSON或者Xml

效果如下:

可以看到,這里使用了Get方法,請求了當前服務器中所有書本信息,並得到了一個JSON格式的結果。

如果需要得到Xml格式,只需要設置請求頭的Accept字段為text/xml或者application/xml即可:

 

接着,開始我們的項目:

這里使用的是社區版的IDEA,原因很簡單,因為我們根本不需要配置服務器,SpringBoot自帶了Tomcat的支持,所以運行項目只需要運行一個main方法即可。

步驟如下:

  1. 創建並配置項目
  2. 編寫項目代碼(MyBatis、SpringMVC)
  3. 配置Log
  4. 打包

① 創建並配置項目

a.創建一個Maven項目(省略)

b.修改pom.xml

復制代碼
  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0"
  3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5     <modelVersion>4.0.0</modelVersion>
  6 
  7     <groupId>com.fndroid.javaweb</groupId>
  8     <artifactId>springboottest</artifactId>
  9     <version>1.0-SNAPSHOT</version>
 10 
 11     <!-- 依賴starter-parent-->
 12     <parent>
 13         <groupId>org.springframework.boot</groupId>
 14         <artifactId>spring-boot-starter-parent</artifactId>
 15         <version>1.4.2.RELEASE</version>
 16     </parent>
 17 
 18     <dependencies>
 19         <!-- 這是一個web項目-->
 20         <dependency>
 21             <groupId>org.springframework.boot</groupId>
 22             <artifactId>spring-boot-starter-web</artifactId>
 23             <exclusions>
 24                 <exclusion>
 25                     <artifactId>log4j-over-slf4j</artifactId>
 26                     <groupId>org.slf4j</groupId>
 27                 </exclusion>
 28             </exclusions>
 29         </dependency>
 30 
 31         <!-- 從parent項目中出去logging這個包,因為我們使用的是log4j -->
 32         <dependency>
 33             <groupId>org.springframework.boot</groupId>
 34             <artifactId>spring-boot-starter</artifactId>
 35             <exclusions>
 36                 <exclusion>
 37                     <groupId>org.springframework.boot</groupId>
 38                     <artifactId>spring-boot-starter-logging</artifactId>
 39                 </exclusion>
 40             </exclusions>
 41         </dependency>
 42 
 43         <!-- 引入log4j支持 -->
 44         <dependency>
 45             <groupId>org.springframework.boot</groupId>
 46             <artifactId>spring-boot-starter-log4j</artifactId>
 47             <version>1.3.8.RELEASE</version>
 48         </dependency>
 49         <dependency>
 50             <groupId>com.jayway.jsonpath</groupId>
 51             <artifactId>json-path</artifactId>
 52             <scope>test</scope>
 53         </dependency>
 54         <!-- groovy支持-->
 55         <dependency>
 56             <groupId>org.codehaus.groovy</groupId>
 57             <artifactId>groovy-all</artifactId>
 58             <version>2.4.7</version>
 59         </dependency>
 60         <!-- 使用Mybatis-->
 61         <dependency>
 62             <groupId>org.mybatis.spring.boot</groupId>
 63             <artifactId>mybatis-spring-boot-starter</artifactId>
 64             <version>1.1.1</version>
 65         </dependency>
 66         <!-- jdbc驅動-->
 67         <dependency>
 68             <groupId>mysql</groupId>
 69             <artifactId>mysql-connector-java</artifactId>
 70             <version>6.0.5</version>
 71             <scope>runtime</scope>
 72         </dependency>
 73         <dependency>
 74             <groupId>log4j</groupId>
 75             <artifactId>log4j</artifactId>
 76             <version>1.2.17</version>
 77         </dependency>
 78         <!-- 支持生成xml -->
 79         <dependency>
 80             <groupId>com.fasterxml.jackson.dataformat</groupId>
 81             <artifactId>jackson-dataformat-xml</artifactId>
 82         </dependency>
 83     </dependencies>
 84 
 85     <properties>
 86         <java.version>1.8</java.version>
 87     </properties>
 88 
 89 
 90     <build>
 91         <plugins>
 92             <!-- 用於生成jar文件-->
 93             <plugin>
 94                 <groupId>org.springframework.boot</groupId>
 95                 <artifactId>spring-boot-maven-plugin</artifactId>
 96             </plugin>
 97         </plugins>
 98     </build>
 99 
100     <repositories>
101         <repository>
102             <id>spring-releases</id>
103             <url>https://repo.spring.io/libs-release</url>
104         </repository>
105     </repositories>
106     <pluginRepositories>
107         <pluginRepository>
108             <id>spring-releases</id>
109             <url>https://repo.spring.io/libs-release</url>
110         </pluginRepository>
111     </pluginRepositories>
112 </project>
復制代碼

這里引入了一些依賴,對應的作用在代碼中已經注釋出來了。注意:使用parent標簽引入父類的所有依賴中,如果有需要的,可以使用exclusion除去,參考31-41行代碼。

同時注意到,這里還引入了groovy的支持,這就使得我們的編譯器可以創建和編寫Groovy代碼。

最后的plugin是用於打包jar,必須要添加,才能使用maven命令對項目進行打包發布。

c.創建application.yml文件

這里創建的可以是properties,但是yml文件更為直觀,而且IDEA能高亮顯示,並且官方的一些demo都是使用yml配置:

復制代碼
mybatis:
  mapperLocations: classpath:mybatis/*-mapper.xml
  config: classpath:mybatis/mybatis-conf.xml
  typeAliasesPackage: com.fndroid
  checkConfigLocation: false

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/books?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
復制代碼

這里配置了mybatis的一些屬性,SpringBoot雖然會默認配置屬性,但是當檢查到用戶配置的時候,會優先使用用戶配置的信息。

這個配置文件會在Application定義中用到。

d.在resources目錄下創建mybatis文件夾,在用於放置mybatis的配置文件以及mapper文件

e.在src/main/java目錄下創建對應的包,分別為dao、controller、service、entity等分別用於存放SpringMVC對應的類

配置完畢后目錄結構:

這里先不用管Application和log4j.properties這兩個文件,后面用到的時候會創建。至此項目就基本搭建完畢了,可以開始編寫代碼了。

 

② 編寫項目代碼

先說明一點,這里用的是Groovy,相比Java代碼會更加簡單,而且Groovy底層是編譯為Java運行的。

根據功能,現在希望通過下面兩個URL得到對應的結果:

獲取所有書本信息:http://localhost:8080/books

根據id獲取對應書本信息:http://localhost:8080/book/2 (獲取id為2的書本信息)

a.根據數據表,創建對應的實體類Book。在entity包中創建一個名為Book的groovy腳本:

復制代碼
 1 package com.fndroid.entity
 2 
 3 import javax.xml.bind.annotation.XmlRootElement
 4 
 5 @XmlRootElement(name = 'book')
 6 class Book {
 7     int id
 8     String title
 9     String description
10     String pub_time
11     String author
12 
13     Book() {
14     }
15 
16     Book(int id, String title, String description, String pub_time, String author) {
17         this.id = id
18         this.title = title
19         this.description = description
20         this.pub_time = pub_time
21         this.author = author
22     }
23 }
復制代碼

這里沒有對類進行修飾,Groovy默認會設定為public,而字段則默認是private,並且,Groovy會默認為private的字段生成setter和getter方法,所以也就不用我們自己寫了。

b.創建controller,在controller對應的包中創建BookController:

復制代碼
 1 package com.fndroid.controller
 2 
 3 import com.fndroid.entity.Book
 4 import com.fndroid.services.BookServices
 5 import org.springframework.web.bind.annotation.PathVariable
 6 import org.springframework.web.bind.annotation.RequestMapping
 7 import org.springframework.web.bind.annotation.RestController
 8 
 9 import javax.annotation.Resource
10 
11 @RestController
12 class BookController {
13 
14     @Resource
15     BookService service;
16 
17     @RequestMapping('/books')
18     List<Book> getBooks() {
19         service.getBooks()
20     }
21 
22     @RequestMapping('/book/{id}')
23     Book getBook(@PathVariable(name = 'id')int id) {
24         service.getBook(id)
25     }
26 }
復制代碼

這是SpringMVC的知識,@RestController表明這個類為RESTful的Controller。

使用@Resource表明通過注入取得BookServices的對象。

@RequestMapping則是表明請求的路徑,根據路徑執行對應的方法。

@PathVariable用於獲取路徑中名為id的值,用作查詢

可以看到這里的方法有返回值類型而沒有return語句,這是Groovy的特性,默認會將最后一個語句作為返回值。

c.創建Services,並定義對應方法:

上面Controller使用到兩個BookService的方法,需要我們對其進行編寫:

復制代碼
 1 package com.fndroid.services
 2 
 3 import com.fndroid.entity.Book
 4 import com.fndroid.dao.IBookDao
 5 import org.springframework.stereotype.Service
 6 
 7 import javax.annotation.Resource
 8 @Service
 9 class BookService {
10     @Resource
11     IBookDao bookDao;
12 
13     List<Book> getBooks() {
14         bookDao.getBooks()
15     }
16 
17     Book getBook(int id){
18         bookDao.getBook(id)
19     }
20 }
復制代碼

@Service表明此類為SpringMVC的服務層,並且通過注解注入了IBookDao的對象。

d.創建Dao接口IBookDao:

復制代碼
 1 package com.fndroid.dao
 2 
 3 import com.fndroid.entity.Book
 4 import org.springframework.stereotype.Repository
 5 
 6 @Repository
 7 interface IBookDao {
 8     List<Book> getBooks()
 9     Book getBook(int id)
10 }
復制代碼

@Repository表明此類為實體Bean類

接口只需要定義對應的方法即可。

e.根據接口編寫mapper文件,在mybatis文件夾中創建一個book-mapper.xml文件:

復制代碼
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.fndroid.dao.IBookDao">
 6     <select id="getBooks" resultType="com.fndroid.entity.Book">
 7         select * from book
 8     </select>
 9 
10     <select id="getBook" resultType="com.fndroid.entity.Book" parameterType="Integer">
11         select * from book where id = #{id}
12     </select>
13 </mapper>
復制代碼

這里要注意,mapper元素的namespace需要定義為我們Dao對應的全路徑名,接着定義兩個select分別對應我們的兩個方法,id對應方法名,resultType對應返回值,parameterType對應參數,接着在select中編寫SQL語句即可。

注意:這里getBooks雖然會返回多個行,但是resultType依然是Book而不是List,因為MyBatis會幫我們組裝成List。

f.定義mybatis-conf.xml

一般情況下對於MyBatis的配置如別名等會聲明在此文件中:

復制代碼
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <settings>
 7         <setting name="logImpl" value="LOG4J"/>
 8     </settings>
 9 
10     <typeAliases>
11         <typeAlias type="com.fndroid.entity.Book" alias="Book"/>
12     </typeAliases>
13 </configuration>
復制代碼

如果這里定義了Book的別名,則上面的mapper文件可以直接使用"Book"代替"com.fndroid.entity.Book"

g.創建程序的入口Application類:

復制代碼
 1 package com.fndroid
 2 
 3 import org.apache.ibatis.session.SqlSessionFactory
 4 import org.apache.tomcat.jdbc.pool.DataSource
 5 import org.mybatis.spring.SqlSessionFactoryBean
 6 import org.mybatis.spring.annotation.MapperScan
 7 import org.mybatis.spring.boot.autoconfigure.MybatisProperties
 8 import org.springframework.boot.SpringApplication
 9 import org.springframework.boot.autoconfigure.SpringBootApplication
10 import org.springframework.boot.context.properties.ConfigurationProperties
11 import org.springframework.context.annotation.Bean
12 import org.springframework.context.annotation.Primary
13 import org.springframework.core.io.support.PathMatchingResourcePatternResolver
14 import org.springframework.jdbc.datasource.DataSourceTransactionManager
15 import org.springframework.transaction.PlatformTransactionManager
16 
17 @SpringBootApplication
18 @MapperScan('com.fndroid.dao')
19 class Application {
20 
21     static void main(String[] args) {
22         SpringApplication.run(Application.class, args)
23     }
24 
25     @Bean
26     @ConfigurationProperties(prefix = 'spring.datasource')
27     DataSource dataSource() {
28         new DataSource()
29     }
30 
31     @Bean
32     SqlSessionFactory sqlSessionFactory() throws Exception {
33         def sqlSessionFactoryBean = new SqlSessionFactoryBean()
34         sqlSessionFactoryBean.setDataSource(dataSource())
35         def resolve = resolver()
36         def mybatisProperties = this.mybatisProperties()
37         sqlSessionFactoryBean.setConfigLocation(resolve.getResource(mybatisProperties.getConfigLocation()))
38         sqlSessionFactoryBean.setMapperLocations(resolve.getResources(mybatisProperties.mapperLocations[0]))
39         sqlSessionFactoryBean.getObject()
40     }
41 
42     @Bean
43     @Primary
44     @ConfigurationProperties(prefix = 'mybatis')
45     MybatisProperties mybatisProperties() {
46         new MybatisProperties()
47     }
48 
49     @Bean
50     PathMatchingResourcePatternResolver resolver(){
51         new PathMatchingResourcePatternResolver()
52     }
53 
54     @Bean
55     PlatformTransactionManager transactionManager() {
56         new DataSourceTransactionManager(dataSource())
57     }
58 }
復制代碼

16行@SpringBootApplication注解表明此類為SpringBoot的入口,並且啟動自動配置和組件掃描(掃描controller和service等注解聲明的類)等功能。

17行@MapperScan表明從dao包下面尋找mapper(這里的mapper指的是對應的Dao類)

21-23行定義了一個main方法,這個方法就是程序的入口,這里調用SpringApplication的靜態方法run來啟動一個Spring程序

25-29行通過注解@Bean注入了一個DataSource類型的對象,因為DataSource的屬性需要表明數據庫的連接信息,所以需要添加@ConfigurationProperties注解,這個注解會將我們先前定義的application.yml文件中,對應的屬性配置給這個DataSource對象

31-40行通過@Bean注解來注入SqlSessionFactory對象,這個對象會被Spring容器調用進行數據庫操作,我們要將application.yml中配置的mapper和conf路徑設置到SqlSessionFactoryBean中,最后通過getObject方法返回一個SqlSessionFactory的對象

42-47行則使用@Bean注解取得application.yml文件中對應mybatis的配置信息

54-57行則是將DataSource設置給PlatformTranscationManager,這就可以讓Spring來處理JDBC的事務了

 

③ 配置Log

其實項目到這里已經可以運行了,但是實際上運行起來控制台並不會有詳細的運行信息輸出,原因是我們在pom.xml中已經除去了默認的logging,也就是logback。如果需要使用logback,很簡單,只需要在resource中添加一個logback的配置文件就可以了。而這里用的是log4j,所以需要在resource中創建log4j.properties文件,這里不能用yml,因為log4j不支持。

復制代碼
 1 # 全局配置
 2 log4j.rootLogger=INFO, stdout, file
 3 # mybatis的配置
 4 log4j.logger.com.fndroid.dao.IBookDao=TRACE
 5 # 控制台輸出配置
 6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 8 log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] - %m%n
 9 # 文件輸出配置
10 log4j.appender.file=org.apache.log4j.FileAppender
11 log4j.appender.file.layout=org.apache.log4j.PatternLayout
12 log4j.appender.file.layout.ConversionPattern=%d %5p [%t] - %m%n
13 log4j.appender.file.File=D:/log.log4j
14 log4j.appender.file.ImmediateFlush=true
復制代碼

第2行聲明根Logger輸入的日志類型為INFO,輸出對象為控制台和文件

第4行則是表明對於對應的Dao類,我們希望顯示查詢語句和查詢結果,所以這里是TRACE

第6-8配置控制台輸出,包括顯示布局和格式

第10-14則是文件輸出,包括顯示布局、格式和輸出路徑等

 

到這里,項目已經可以在終端使用maven命令:mvn spring-boot:run 來運行項目,或者直接使用IDEA運行對應的main方法,可以看到,控制台打印了容器開啟的信息,而D盤中也生成了對應的log.log4j文件:

下面是啟動成功的信息:

使用調試工具或者瀏覽器訪問URL:http://localhost:8080/books

瀏覽器會顯示對應的xml結果文件:

返回控制台,可以看到SQL語句也被輸出了:

這就證明我們的Log配置沒有問題了

注意:如果需要重啟,要先關閉前一個Application,否則會提示端口被占用。

 

④ 打包

對於SpringBoot項目,打包非常簡單,只需要使用終端輸入:mvn packag 命令即可在項目的target目錄下生成一個jar文件,只需要在服務器環境下使用java -jar xxx.jar命令即可啟動這個SpringBoot項目。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM