SpringBoot整合Scala構建Web服務
阿新 • • 發佈:2019-03-02
今天我們嘗試Spring Boot整合Scala,並決定建立一個非常簡單的Spring Boot微服務,使用Scala作為程式語言進行編碼構建。
建立專案
- 初始化專案
mvn archetype:generate -DgroupId=com.edurt.ssi -DartifactId=springboot-scala-integration -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false
- 修改pom.xml增加java和scala的支援
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edurt.ssi</groupId> <artifactId>springboot-scala-integration</artifactId> <packaging>jar</packaging> <version>1.0.0</version> <name>springboot-scala-integration</name> <description>SpringBoot Scala Integration is a open source springboot, scala integration example.</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!-- dependency config --> <dependency.scala.version>2.12.1</dependency.scala.version> <!-- plugin config --> <plugin.maven.scala.version>3.1.3</plugin.maven.scala.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${dependency.scala.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <sourceDirectory>${project.basedir}/src/main/scala</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>${plugin.maven.scala.version}</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 一個簡單的應用類
package com.edurt.ssi import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication class SpringBootScalaIntegration object SpringBootScalaIntegration extends App{ SpringApplication.run(classOf[SpringBootScalaIntegration]) }
新增Rest API介面功能
- 建立一個HelloController Rest API介面,我們只提供一個簡單的get請求獲取hello,scala輸出資訊
package com.edurt.ssi.controller
import org.springframework.web.bind.annotation.{GetMapping, RestController}
@RestController
class HelloController {
@GetMapping(value = Array("hello"))
def hello(): String = {
return "hello,scala"
}
}
- 修改SpringBootScalaIntegration檔案增加以下設定掃描路徑
@ComponentScan(value = Array(
"com.edurt.ssi.controller"
))
新增頁面功能
- 修改pom.xml檔案增加以下頁面依賴
<!-- mustache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
- 修改SpringBootScalaIntegration檔案增加以下設定掃描路徑ComponentScan的value欄位中
"com.edurt.ssi.view"
-
在src/main/resources路徑下建立templates資料夾
-
在templates資料夾下建立一個名為hello.mustache的頁面檔案
<h1>Hello, Scala</h1>
- 建立頁面轉換器HelloView
package com.edurt.ssi.view
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
@Controller
class HelloView {
@GetMapping(value = Array("hello_view"))
def helloView: String = {
return "hello";
}
}
新增資料持久化功能
- 修改pom.xml檔案增加以下依賴(由於測試功能我們使用h2記憶體資料庫)
<!-- data jpa and db -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
- 修改SpringBootScalaIntegration檔案增加以下設定掃描model路徑
@EntityScan(value = Array(
"com.edurt.ssi.model"
))
- 建立User實體
package com.edurt.ssi.model
import javax.persistence.{Entity, GeneratedValue, Id}
@Entity
class UserModel {
@Id
@GeneratedValue
var id: Long = 0
var name: String = null
}
- 建立UserSupport dao資料庫操作工具類
package com.edurt.ssi.support
import com.edurt.ssi.model.UserModel
import org.springframework.data.repository.PagingAndSortingRepository
trait UserSupport extends PagingAndSortingRepository[UserModel, Long] {
}
- 建立UserService服務類
package com.edurt.ssi.service
import com.edurt.ssi.model.UserModel
trait UserService {
/**
* save model to db
*/
def save(model: UserModel): UserModel;
}
- 建立UserServiceImpl實現類
package com.edurt.ssi.service
import com.edurt.ssi.model.UserModel
import com.edurt.ssi.support.UserSupport
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
@Service(value = "userService")
class UserServiceImpl @Autowired() (
val userSupport: UserSupport
) extends UserService {
/**
* save model to db
*/
override def save(model: UserModel): UserModel = {
return this.userSupport.save(model)
}
}
- 建立使用者UserController進行持久化資料
package com.edurt.ssi.controller
import com.edurt.ssi.model.UserModel
import com.edurt.ssi.service.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.{PathVariable, PostMapping, RequestMapping, RestController}
@RestController
@RequestMapping(value = Array("user"))
class UserController @Autowired()(
val userService: UserService
) {
@PostMapping(value = Array("save/{name}"))
def save(@PathVariable name: String): Long = {
val userModel = {
new UserModel()
}
userModel.name = name
return this.userService.save(userModel).id
}
}
- 使用控制檯視窗執行以下命令儲存資料
curl -X POST http://localhost:8080/user/save/qianmoQ
收到返回結果
1
表示資料儲存成功
增加資料讀取渲染功能
- 修改UserService增加以下程式碼
/**
* get all model
*/
def getAll(page: Pageable): Page[UserModel]
- 修改UserServiceImpl增加以下程式碼
/**
* get all model
*/
override def getAll(page: Pageable): Page[UserModel] = {
return this.userSupport.findAll(page)
}
- 修改UserController增加以下程式碼
@GetMapping(value = Array("list"))
def get(): Page[UserModel] = this.userService.getAll(PageRequest.of(0, 10))
- 建立UserView檔案渲染User資料
package com.edurt.ssi.view
import com.edurt.ssi.service.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
@Controller
class UserView @Autowired()(
private val userService: UserService
) {
@GetMapping(value = Array("user_view"))
def helloView(model: Model): String = {
model.addAttribute("users", this.userService.getAll(PageRequest.of(0, 10)))
return "user"
}
}
- 建立user.mustache檔案渲染資料(自行解析返回資料即可)
{{users}}
增加單元功能
- 修改pom.xml檔案增加以下依賴
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
- 建立UserServiceTest檔案進行測試UserService功能
package com.edurt.ssi
import com.edurt.ssi.service.UserService
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.domain.PageRequest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserServiceTest @Autowired()(
private val userService: UserService) {
@Test
def `get all`() {
println(">> Assert blog page title, content and status code")
val entity = this.userService.getAll(PageRequest.of(0, 1))
print(entity.getTotalPages)
}
}