Hello. This time, I went up to "Create a Hello World file and a Hello World test code file, save it in a jar, and run it on a mac". As in the last time, I proceeded with reference to Introduction to Spring. It's a simple procedure, but probably because of the version, I wrote an article because I was unexpectedly stuck around running it with JUnit or making it a jar. Please go beyond my corpse.
First, create a project template with Spring Initializr. Spring Initializr is a web service provided by Spring Boot. Just check the necessary information and you can download the directory that is the basis for creating a Spring Boot project in zip format. In addition, DemoApplication.java, which has a template for the main method, and DemoApplicationTests.java, which has a template for the test code, are already placed under the appropriate directory.
In other words, just download it and 80% of this creation will be completed lol
Since we built the environment with Maven last time, Project will select Maven. In addition, select the language, Spring Boot version, Java version, etc. that suits you and click the GENERATE button to start downloading demo.zip.
When you unzip demo.zip, the following Maven project is already created. Wow! Isn't it really easy! !!
It is easy to proceed if you move the unzipped demo file under the workspace directory created when you built the environment. Open STS, go to File> Import> Existing Maven Projects and select the demo folder you just unzipped to import.
The build will run automatically, so wait for a while until Package Explorer displays the package as shown in the image below. If the following does not occur automatically, press Project> Clean from the menu bar.
The contents of DemoApplication.java that you just downloaded should look like the following.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Spring is a framework for MVC models. Since the HelloWorld project requires a minimum implementation, I would like to implement only the Controller part, which receives the request from the client and returns the response [^ 1].
[^ 1]: I won't go into the details of Spring MVC, but to be precise, the front controller servlet in front of the controller receives the request and returns the response. We'll leave this to the framework, so developers will only implement the controller.
@Controller
to the DemoApplication classNeedless to say, you can make the class a controller by annotating it with @Controller
.
@RequestMapping
and @ResponseBody
By adding two annotations, @RequestMapping
and @ResponseBody
, the return value can be the content of the response.
Reference: Various return values in Spring MVC controller
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@SpringBootApplication
@Controller
public class DemoApplication {
@RequestMapping("/")
@ResponseBody
String helloWorld() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Save it, right-click on DemoApplication> Run As> Java Application and run the main method and you should be able to Hello Work at http: // localhost: 8080! You did it!
Even if you write something other than the above, if you change the controller annotation from @ Controller
to @ RestController
, the helloWorld () annotation will work only with @ RequestMapping
.
However, if you make a mistake in the combination of annotations, an error will occur (I did it). Apparently, this screen appears if the HTTP request is not received on the application side, and it seems that the same screen will be displayed even if DemoApplication.java is executed until it is downloaded.
We will also edit the test code according to the implementation of DemoApplication.java. Below is the downloaded Manma test code. I will modify this.
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Test
void contextLoads() {
}
}
@SpringBootTest
instead of @SpringApplicationConfigration
and @WebIntegrationTest
The former two annotations have been deprecated since Spring Boot 1.4, so replace them with @SpringBootTest
.
@SpringBootTest
recognizes the class with @SpringBootApplication
as the test configuration class. ](Https://qiita.com/BooookStore/items/14c7bd559878991cf112)
@ ExtendWith (SpringExtension.class)
instead of @ RunWith (SpringRunner.class)
SpringRunner is from JUnit4, so when I use it with JUnit5, the build doesn't work when I create the jar after that ...
In JUnit5, the @RunWith
annotation itself was replaced with @ExtendWith
, so I changed it there. JUnit5 @RunWith
@LocalServerPort
In Spring Boot 1.3 or earlier, the port number was acquired by @ Value (“$ {local.server.port}”)
, but since 1.4, @LocalServerPort
has been added as a shortcut. In 2.3, when I tried to get the port number with @Value
, the following error occurred and the test could not be executed. ..
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.demo.DemoApplicationTests': Unsatisfied dependency expressed through field 'port';
nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'int';
nested exception is java.lang.NumberFormatException: For input string: "${local.server.port"
JUnit assertThat says deprecated and adds the annotation @SuppressWarnings (“deprecated”)
to allow deprecated. But I couldn't build the jar well ... (maybe due to something other than the above)
Instead, I used hamcrest's assertThat.
The final test code looks like this:
package com.example.demo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {
TestRestTemplate restTemplate = new TestRestTemplate();
@LocalServerPort
int port;
@Test
public void testHello() {
assertThat(restTemplate.getForObject("http://localhost:" + port, String.class), is("Hello World!"));
}
}
You can run the test code by right-clicking on DemoApplicationTests.java> Run As> JUnit Test. If you see the following in the JUnit panel, the test is successful!
Try changing the "Hello World!" Part of either the above test code or DemoApplication.java to something else and see if the test fails.
By the process so far, Hello World of Spring project has already been completed. However, when I actually try to make it into a jar, I notice that compilation and build do not work, so it is good to do it!
I will explain the procedure to create a jar.
cd ~/Users/xxx/workspace/demo
./mvnw clean package
Even if Hello World and the test are successful on STS, you may get an error here (yourself)
I found out that @RunWith
cannot be used here.
If successful, you will see BUILD SUCCESS
as shown below.
If the build is successful, you should have "demo-0.0.1-SNAPSHOT.jar" under demo / target. Execute the one that does not have original at the end.
java -jar /Users/xxx/workspace/demo/target/demo-0.0.1-SNAPSHOT.jar
If Spring starts up as below, it will be successful! You can see Hello World! In the same way at http: // localhost: 8080.
As mentioned at the beginning, I did it while reading Spring Thorough Introduction, but when creating just Hello World, the same Java and IDE But I was surprised that it was so different just because the version was different ... I understood the reason why the version is important ... Now that I've created the template, I'd like to easily create an app and write test code next time!
Thank you for reading! If there is something that may be different here, please let me know as in the example ...!
Recommended Posts