Steps to build and run Spring Boot with Gradle.
build.gradle
def applicationVersion = project.properties['release.version']
// ~~~
// Spring Boot
buildscript {
def springBootVersion = '2.0.3.RELEASE'
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:' + springBootVersion
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
def springBootApplicationName = 'hello-world-spring-boot'
bootJar {
baseName = springBootApplicationName
version = applicationVersion
}
bootWar {
baseName = springBootApplicationName
version = applicationVersion
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-devtools'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
build.gradle
//Release version gradle.Get from properties and set
def applicationVersion = project.properties['release.version']
version = applicationVersion
//Java version
apply plugin: 'java'
def javaVersion = JavaVersion.VERSION_1_10
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
//Output war file
apply plugin: 'war'
//Dependent library version
def junitVersion = '5.2.0'
def jacocoVersion = '0.8.1'
def checkstyleVersion = '8.10.1'
//Dependent library acquisition destination
repositories {
//Use Maven Central
mavenCentral()
}
//Dependent libraries
dependencies {
// JUnit
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitVersion
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: junitVersion
}
test {
//Use JUnit5 when building gradle
useJUnitPlatform()
//Number of parallel execution threads for the test
maxParallelForks = 4
}
//Gradle plug-in settings that output various IDE configuration files
apply plugin: 'eclipse'
apply plugin: 'idea'
//Use Jacoco for test coverage
apply plugin: 'jacoco'
jacoco {
toolVersion = jacocoVersion
}
jacocoTestReport {
reports {
xml.enabled = true
html.enabled = true
}
}
build.dependsOn jacocoTestReport
//Static code analysis with Checkstyle
apply plugin: 'checkstyle'
checkstyle {
toolVersion = checkstyleVersion
//By default/src/main/Under resources, but refer to the XML file directly under the repository
configFile = file('checkstyle.xml')
//Make sure to interrupt the build if there is an error when running Checkstyle
ignoreFailures = false
}
// Spring Boot
buildscript {
def springBootVersion = '2.0.3.RELEASE'
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:' + springBootVersion
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
def springBootApplicationName = 'hello-world-spring-boot'
bootJar {
baseName = springBootApplicationName
version = applicationVersion
}
bootWar {
baseName = springBootApplicationName
version = applicationVersion
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-devtools'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
Application.java
package hello;
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);
}
}
ApplicationTest.java
package hello;
import org.junit.jupiter.api.Test;
class ApplicationTest {
@Test
void main() {
Application.main(new String[0]);
}
}
I get a warning that Spring Boot is automatically terminated, but there is no problem. Please advise if there is any better solution.
HelloWorldController.java
package hello;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
class HelloWorldController {
static final String HELLO_WORLD = "Hello, world.";
private static final int BUFFER_SIZE = 1024;
@RequestMapping(value = "/string", method = RequestMethod.GET)
String byString() {
return HELLO_WORLD;
}
@RequestMapping(value = "/byte", method = RequestMethod.GET)
byte[] byBytes() {
return HELLO_WORLD.getBytes();
}
@RequestMapping(value = "/stream", method = RequestMethod.GET)
ResponseEntity<InputStreamResource> byStream() {
final InputStreamResource inputStreamResource = new InputStreamResource(
new BufferedInputStream(new ByteArrayInputStream(HELLO_WORLD.getBytes()), BUFFER_SIZE)
);
final HttpHeaders headers = new HttpHeaders();
headers.setContentLength(HELLO_WORLD.getBytes().length);
return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
}
}
HelloControllerTest.java
package hello;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
class HelloControllerTest {
@Test
void byString() {
final HelloWorldController helloController = new HelloWorldController();
Assertions.assertAll(
() -> Assertions.assertEquals(helloController.byString(), HelloWorldController.HELLO_WORLD)
);
}
@Test
void byBytes() {
final HelloWorldController helloController = new HelloWorldController();
Assertions.assertAll(
() -> Assertions.assertEquals(Arrays.toString(helloController.byBytes()),
Arrays.toString(HelloWorldController.HELLO_WORLD.getBytes()))
);
}
@Test
void byStream() {
final HelloWorldController helloController = new HelloWorldController();
final ResponseEntity<InputStreamResource> response = helloController.byStream();
try (final InputStream input = response.getBody().getInputStream()) {
final byte[] body = input.readAllBytes();
Assertions.assertAll(
() -> Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK),
() -> Assertions.assertEquals(Arrays.toString(body),
Arrays.toString(HelloWorldController.HELLO_WORLD.getBytes()))
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Command execution
gradle bootRun
Or
gradlew bootRun
In both cases, Hello, world. Is returned in the response body (it appears in the browser in words).
In the response of the type that returns InputStream, I checked whether InputStream was properly closed.
@RequestMapping(value = "/stream", method = RequestMethod.GET)
ResponseEntity<InputStreamResource> byStream() {
final InputStreamResource inputStreamResource = new InputStreamResource(
new BufferedInputStreamCustom(new ByteArrayInputStream(HELLO_WORLD.getBytes()), BUFFER_SIZE)
);
final HttpHeaders headers = new HttpHeaders();
headers.setContentLength(HELLO_WORLD.getBytes().length);
return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
}
private static class BufferedInputStreamCustom extends BufferedInputStream {
public BufferedInputStreamCustom(InputStream in, int size) {
super(in, size);
}
@Override
public void close() throws IOException {
System.out.println("closed");
super.close();
}
}
Every time I ran the API, I got a closed output on the console, and found that the InputStream I passed was closed properly.
Recommended Posts