Method of Constructing Web Service by Integrating SpringBoot with Scala

  • 2021-07-01 07:22:45
  • OfStack

Today, we tried Spring Boot to integrate Scala, and decided to build a very simple Spring Boot microservice, using Scala as the programming language for coding and construction.

Create a project

Initialize project

mvn archetype:generate -DgroupId=com.edurt.ssi -DartifactId=springboot-scala-integration -DarchetypeArtifactId=maven-archetype-quickstart -Dversion=1.0.0 -DinteractiveMode=false

Modify pom. xml to add support for java and 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>

1 simple application class


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])

}

Add Rest API interface functionality

Create an HelloController Rest API interface, we only provide a simple get request to obtain hello, scala output information


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"
 }

}

Modify the SpringBootScalaIntegration file to add the following settings scanning path


@ComponentScan(value = Array(
 "com.edurt.ssi.controller"
))

Add page functionality

Modify the pom. xml file to add the following page dependencies


<!-- mustache -->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-mustache</artifactId>
</dependency>

Modify the SpringBootScalaIntegration file to add the following settings in the value field of the scan path ComponentScan


"com.edurt.ssi.view"

Create the templates folder under the src/main/resources path

Create a page file named hello. mustache under the templates folder


<h1>Hello, Scala</h1>

Create a page converter 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";
 }

}

The browser can visit http://localhost: 8080/hello_view to see the page content

Add data persistence functionality

Modify the pom. xml file to add the following dependencies (we use the h2 main memory database due to test functionality)


<!-- 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>

Modify the SpringBootScalaIntegration file and add the following settings to scan the model path


@EntityScan(value = Array(
 "com.edurt.ssi.model"
))

Create an User entity


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])

}
0

Creating an UserSupport dao database manipulation tool class


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])

}
1

Create an UserService service class


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])

}
2

Create an UserServiceImpl implementation class


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)
 }

}

Create user UserController to persist data


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])

}
4

Use the console window to execute the following command to save the data


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])

}
5

Receive the return result

1

Indicates that the data was saved successfully

Add data reading and rendering function

Modify UserService to add the following code


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])

}
6

Modify UserServiceImpl to add the following code


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])

}
7

Modify UserController to add the following code


@GetMapping(value = Array("list"))
def get(): Page[UserModel] = this.userService.getAll(PageRequest.of(0, 10))

Create an UserView file to render User data


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])

}
9

Create user. mustache file to render data (parse the returned data by yourself)


{{users}}

The browser visits http://localhost: 8080/user_view to see the page content

Add unit function

Modify the pom. xml file to add the following dependencies


<!-- 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>

Create an UserServiceTest file to test UserService functionality


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)
 }

}

Source address: GitHub


Related articles: