사이트)
https://javacan.tistory.com/entry/Reactor-Start-1-RS-Flux-Mono-Subscriber
https://durtchrt.github.io/blog/english/spring.io/webflux/
https://parkcheolu.tistory.com/134
http://woowabros.github.io/experience/2019/03/18/tech-toby-reactive.html
WebFlux
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.projectreactor/reactor-test -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.3.2.RELEASE</version>
<scope>test</scope>
</dependency>
package com.example.demo.webflux;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
public class HelloWorldController {
@GetMapping("/hello")
public Mono<String> hello(){
return Mono.just("Hello World!!");
}
}
테스트1)
package com.example.demo;
import com.example.demo.webflux.HelloWorldController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class HelloWorldControllerTest {
private final HelloWorldController controller = new HelloWorldController();
@Test
public void HelloTest(){
Mono<String> result = controller.hello();
StepVerifier.create(result)
.expectNext("Hello World!!")
.verifyComplete();
}
}
테스트2)
package com.example.demo;
import com.example.demo.webflux.HelloWorldController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
@ExtendWith(SpringExtension.class)
@WebFluxTest(HelloWorldController.class)
public class HelloWorldControllerTest2 {
@Autowired
private WebTestClient webClient;
@Test
public void HelloTest(){
webClient.get().uri("/hello").accept(MediaType.TEXT_PLAIN)
.exchange()
.expectStatus().isOk()
.expectBody(String.class)
.isEqualTo("Hello World!!");
}
}
반응형 REST 서비스의 배포와 사용하기
package com.example.demo.webflux;
import java.math.BigDecimal;
import java.util.Objects;
public class Card {
private String id;
private BigDecimal amount;
public Card() {
}
public Card(String id, BigDecimal amount) {
this.id = id;
this.amount = amount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
@Override
public String toString() {
return "Card{" +
"id='" + id + '\'' +
", amount=" + amount +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Card card = (Card) o;
return Objects.equals(id, card.id) &&
Objects.equals(amount, card.amount);
}
@Override
public int hashCode() {
return Objects.hash(id, amount);
}
}
package com.example.demo.webflux;
import java.math.BigDecimal;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
public class CardGenerator {
public Card generate(){
String id = UUID.randomUUID().toString();
var amount = ThreadLocalRandom.current().nextDouble(1000.00);
return new Card(id, BigDecimal.valueOf(amount));
}
}
package com.example.demo.webflux;
import com.example.demo.Asynchronous.Order;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
@Service
public class CardService {
private final Map<String, Card> cards = new ConcurrentHashMap<>(10);
@PostConstruct
public void init(){
CardGenerator generator = new CardGenerator();
for(int i=0; i<25; i++){
var card = generator.generate();
cards.put(card.getId(), card);
}
}
public Mono<Card> findById(String id){
return Mono.justOrEmpty(cards.get(id));
}
public Mono<Card> save(Mono<Card> card){
return card.map(this::save);
}
public Card save(Card card){
cards.put(card.getId(), card);
return card;
}
public Flux<Card> cards(){
return Flux.fromIterable(cards.values()).delayElements(Duration.ofMillis(128));
}
}
package com.example.demo.webflux;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/cards")
public class CardController {
private final CardService cardService;
public CardController(CardService cardService) {
this.cardService = cardService;
}
@PostMapping
public Mono<Card> store(@RequestBody Mono<Card> card){
return cardService.save(card);
}
@GetMapping("/{id}")
public Mono<Card> find(@PathVariable("id") String id){
return cardService.findById(id);
}
@GetMapping
public Flux<Card> list(){
return cardService.cards();
}
}
결과1)
블로킹 형태로 결과받음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | C:\Users\k>curl -v http://localhost:8080/cards * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /cards HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.55.1 > Accept: */* > < HTTP/1.1 200 < Content-Type: application/json < Transfer-Encoding: chunked < Date: Fri, 07 Feb 2020 07:24:38 GMT < [{"id":"9952d83e-97d8-4a1d-bdb8-b398409d8b0e","amount":750.0123717227026},{"id":"89d9606c-9505-425b-925f-840ef11d7c20","amount":148.9894487767811}, {"id":"91605f38-e294-45fa-bc6b-d578896d86e6","amount":422.44435564902574},{"id":"ba4e5dae-ef69-4cb7-93e4-7de0753f60a4","amount":749.5189290655574}, {"id":"1621c7bd-fd6d-41fc-ac10-6015b27e5f87","amount":162.5336383662268},{"id":"bb07ee25-7e70-4070-b024-196d989744df","amount":263.7169592782591}, {"id":"2640c285-4770-4661-bd9f-4a3956d794ea","amount":981.5248197789147},{"id":"97d6cd2b-f6b8-4283-9008-63ef4415858c","amount":962.672621112534}, {"id":"6c360056-5d48-49e7-96fb-3a135e58cb6d","amount":68.25511108318982},{"id":"ef95fb63-d474-4c95-92ac-51c70bba1acf","amount":741.6291164126758}, {"id":"5519b413-c6ff-4709-a2b9-a762dec7cd50","amount":140.51382974302018},{"id":"bda063cb-ea8f-4443-aa06-7447a4306ffd","amount":822.7363023383976}, {"id":"ef5d8e02-01fe-4904-9f69-0ea7f36a6f13","amount":406.5990303773198},{"id":"74f4f2d8-d4c1-4c4d-8246-cef829a2e390","amount":629.8772183472203}, {"id":"7a2c2485-2ad2-4b88-9769-c5677e0d2e8c","amount":737.2000738705611},{"id":"4dbfa58d-0bf6-4e37-884c-7bd8222a6b52","amount":739.523863547587}, {"id":"1594a2b8-808f-44f6-8eb6-46ee302deba7","amount":567.7356954332324},{"id":"9ba74e3a-ca85-4d48-ac65-c4cb4c0053f1","amount":843.5206984473494}, {"id":"59f20c88-24e8-42d2-a979-149d197723b5","amount":269.88138229645887},{"id":"2b5d7e49-68f6-49fd-8981-4720d14d1c24","amount":58.305065643697304}, {"id":"4f636a4a-f968-4c48-9cc7-7d8014d8a3c2","amount":485.41446075837416},{"id":"7d5fc8b1-8156-4cd1-8a4d-1f7e67432b03","amount":745.0151038437566}, {"id":"b63c99c3-8a29-498a-8d3f-8865ab47217f","amount":518.3171480929965},{"id":"9c06a084-1d99-440e-8752-734b1b3293e8","amount":942.8692669383402}, {"id":"ee281ee4-21af-4d77-9da5-11e72f3980f0","amount":623.2914230777963}] * Connection #0 to host localhost left intact | cs |
결과2)
부드럽게 스트리밍으로 변경
@GetMapping(produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<Card> list(){
return cardService.cards();
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | C:\Users\k>curl -v http://localhost:8080/cards * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /cards HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.55.1 > Accept: */* > < HTTP/1.1 200 < Content-Type: application/stream+json < Transfer-Encoding: chunked < Date: Fri, 07 Feb 2020 07:41:09 GMT < {"id":"686a72f2-7b17-4a6e-b0db-5c7f6ecb4247","amount":127.5656000500781} {"id":"e460d2c9-367d-4918-a5dc-a0e506c4f665","amount":160.83210969757346} {"id":"dacdb1d6-56d7-4685-b65e-12911b5287d9","amount":84.20640219275954} {"id":"b9fdb275-04b9-41ee-8478-4fee17ef2224","amount":467.1001135139228} {"id":"19c75e6f-7d3c-488f-b9f5-52b7ef7f12dc","amount":827.6926132808026} {"id":"855e0f10-65ca-4386-a6b6-0672c27c4c6c","amount":75.48687567462132} {"id":"3a615012-1e25-4521-9c38-e6f471d60f34","amount":64.88186909800342} {"id":"796b40c7-0a90-44b6-9230-e23a5d142d27","amount":780.5153321704377} {"id":"3f2d0abc-5851-4d7c-a17c-637118a1a519","amount":719.4092672960209} {"id":"0d31b024-42a2-4233-bffe-615b4db7f29b","amount":552.5416145504114} {"id":"a9960243-6d58-4a83-b0ef-86375ef3ae28","amount":965.5502543366686} {"id":"10464393-6d9c-4d7a-be04-60d098acaeab","amount":182.50970012667167} {"id":"bd004cd2-808b-45fe-89bf-42d0e0ffdd7d","amount":829.0018590712672} {"id":"76dcfbe6-c3cf-4320-98d0-678dcc683b1e","amount":90.68787720661398} {"id":"0709d4e7-1bd6-47fe-ae31-16389f396767","amount":787.135371859461} {"id":"048724ff-f1b7-4fc6-84e7-9ffc47f56139","amount":442.1838883756631} {"id":"b22018bd-b189-450f-8db7-1d023b39b1bc","amount":461.2993139118832} {"id":"e37ac175-22c0-422b-a229-b015186e23a9","amount":546.6597286257587} {"id":"dfe7869d-cc3c-4434-8e07-9afd5e5b71f1","amount":927.4071316263424} {"id":"9dfd5165-d4df-412f-8e4d-318511293cf0","amount":334.4025169113476} {"id":"a7c1f182-4016-4e4c-94a7-b1471eafb1da","amount":393.683743698349} {"id":"4d12066a-467b-4efd-9172-4082fda9293b","amount":952.9975766813096} {"id":"08bf59d8-660d-43b7-8db7-eb12a6075e50","amount":844.2504040090685} {"id":"f9eeb91a-7836-439f-b17f-47bf50700f9f","amount":560.2851345940044} {"id":"a6e78ae6-ef45-4a5f-b19d-edd9ea4dc211","amount":262.9722737194426} * Connection #0 to host localhost left intact | cs |
결과3)
서버에서 이벤트 보내기
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Card> list(){
return cardService.cards();
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | C:\Users\k>curl -v http://localhost:8080/cards * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > GET /cards HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.55.1 > Accept: */* > < HTTP/1.1 200 < Content-Type: text/event-stream;charset=UTF-8 < Transfer-Encoding: chunked < Date: Fri, 07 Feb 2020 07:42:59 GMT < data:{"id":"e834b6b6-d2fa-4a0b-b019-41be1bf0e279","amount":826.3154667236321} data:{"id":"fa02c5ea-2927-485f-b750-2221eb1ef0a9","amount":858.1500159440058} data:{"id":"55752a8e-7911-49e4-b4e5-ebd288b7ec87","amount":957.568311728922} data:{"id":"8c711522-0922-4fff-a8fa-b586d74e83df","amount":707.0568185867161} data:{"id":"300fa1db-f0ab-43f3-93c2-bf771f1b0bbb","amount":147.5958156199999} data:{"id":"d9edbc84-c4e6-4920-bd5c-ca279dffcbc9","amount":101.8207970526116} data:{"id":"b8bbeb86-22b7-42c8-bc69-d0f6c5c916ff","amount":390.54721772841816} data:{"id":"5242f6a2-0b8b-436d-bfde-7d4b97dd6324","amount":201.8183757489349} data:{"id":"4835b170-bddd-4879-83d7-3e3552823c56","amount":267.28033075207804} data:{"id":"88431e7e-8140-4eff-a597-ada41633d3f8","amount":94.46435869267911} data:{"id":"c0fb138c-5953-48d4-bb65-df2b3700a5f4","amount":856.2579115744311} data:{"id":"4c4199bf-6436-449f-ba1a-b6dfb50c76e6","amount":621.0601762993975} data:{"id":"069049cc-b6f4-4676-a90c-9ff3b01689ec","amount":262.5085617755284} data:{"id":"bdfb5a2a-57f0-4e15-832d-80fc696c7251","amount":782.6057188473436} data:{"id":"0b6cd599-6922-4f49-819e-2d886b3a04b0","amount":64.45794831192575} data:{"id":"63a3e007-444d-44bd-b6eb-6f3f9ae4a8c4","amount":476.0887529093811} data:{"id":"182c870e-bb6b-4c76-8a1d-d7d3e5fa55fa","amount":513.5560802453207} data:{"id":"9e4cee1f-b7ea-4016-b2e6-9de3e8c27be7","amount":478.18474198318427} data:{"id":"3a3d5e39-b43f-4d74-a638-6f0d9da30515","amount":802.6390382876965} data:{"id":"44439a3c-16f1-465d-bcce-35cf8b6575cd","amount":829.1811786941812} data:{"id":"2f656d7f-1937-49a7-8743-5f777a6f1bb2","amount":641.6973573771448} data:{"id":"a9db4e21-8208-4a08-83c1-0f250e87ac7f","amount":944.5129116764434} data:{"id":"8fbe5e84-3d29-4d3f-9a92-ff66f7198520","amount":741.4665049109587} data:{"id":"4471a77c-5baf-48a4-a3e3-a2308ecf4b88","amount":180.0191932223123} data:{"id":"8d3781cb-67bc-4692-8eda-9e0052581a73","amount":615.8590615077483} * Connection #0 to host localhost left intact | cs |
테스트
참고사이트
https://howtodoinjava.com/spring-webflux/webfluxtest-with-webtestclient/
http://wonwoo.ml/index.php/post/category/web
Spring Boot 2.2.0 syncBody deprecated : https://stackoverflow.com/questions/58423323/spring-boot-2-2-0-syncbody-deprecated
Spring 5 WebClient and WebTestClient Tutorial with Examples : https://www.callicoder.com/spring-5-reactive-webclient-webtestclient-examples/
package com.example.demo;
import com.example.demo.webflux.Card;
import com.example.demo.webflux.CardController;
import com.example.demo.webflux.CardService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;
import java.math.BigDecimal;
@ExtendWith(SpringExtension.class)
@WebFluxTest(controllers = {CardController.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@Import(CardService.class)
public class CardControllerTest {
@Autowired
private WebTestClient webTestClient;
@Test
@DisplayName("listOrders")
public void listOrders(){
webTestClient.get().uri("/cards")
.exchange()
.expectStatus().isOk()
.expectBodyList(Card.class).hasSize(25);
}
@Test
@DisplayName("addAndGetOrder")
public void addAndGetOrder(){
var card = new Card("testing", BigDecimal.TEN);
webTestClient.post()
.uri("/cards")
.body(Mono.just(card), Card.class)
.exchange()
.expectStatus().isOk()
.expectBody(Card.class).isEqualTo(card);
webTestClient.get()
.uri("/cards/{id}",card.getId())
.exchange()
.expectStatus().isOk()
.expectBody(Card.class).isEqualTo(card);
}
}
결과)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.4.RELEASE) 2020-02-07 17:58:03.095 INFO 17132 --- [ main] com.example.demo.CardControllerTest : Starting CardControllerTest on DESKTOP-6HPEM1U with PID 17132 (started by k in D:\example\springboot2_mvc_example2) 2020-02-07 17:58:03.097 INFO 17132 --- [ main] com.example.demo.CardControllerTest : No active profile set, falling back to default profiles: default 2020-02-07 17:58:03.881 WARN 17132 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration) 2020-02-07 17:58:03.995 DEBUG 17132 --- [ main] s.w.r.r.m.a.RequestMappingHandlerMapping : 3 mappings in 'requestMappingHandlerMapping' 2020-02-07 17:58:04.011 DEBUG 17132 --- [ main] o.s.w.r.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping' 2020-02-07 17:58:04.113 DEBUG 17132 --- [ main] o.s.w.r.r.m.a.ControllerMethodResolver : ControllerAdvice beans: none 2020-02-07 17:58:04.154 DEBUG 17132 --- [ main] o.s.w.s.adapter.HttpWebHandlerAdapter : enableLoggingRequestDetails='false': form data and headers will be masked to prevent unsafe logging of potentially sensitive data 2020-02-07 17:58:04.172 INFO 17132 --- [ main] com.example.demo.CardControllerTest : Started CardControllerTest in 1.406 seconds (JVM running for 2.834) 2020-02-07 17:58:04.500 DEBUG 17132 --- [ main] o.s.w.r.f.client.ExchangeFunctions : [3292d91a] HTTP POST /cards 2020-02-07 17:58:04.555 DEBUG 17132 --- [ parallel-1] org.springframework.web.HttpLogging : [3292d91a] Encoding [Card{id='testing', amount=10}] 2020-02-07 17:58:04.591 DEBUG 17132 --- [ parallel-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [3197f3be] HTTP POST "/cards" 2020-02-07 17:58:04.603 DEBUG 17132 --- [ parallel-1] s.w.r.r.m.a.RequestMappingHandlerMapping : [3197f3be] Mapped to com.example.demo.webflux.CardController#store(Mono) 2020-02-07 17:58:04.616 DEBUG 17132 --- [ parallel-1] .r.m.a.RequestBodyMethodArgumentResolver : [3197f3be] Content-Type:application/json 2020-02-07 17:58:04.634 DEBUG 17132 --- [ parallel-1] .r.m.a.RequestBodyMethodArgumentResolver : [3197f3be] 0..1 [com.example.demo.webflux.Card] 2020-02-07 17:58:04.641 DEBUG 17132 --- [ parallel-1] o.s.w.r.r.m.a.ResponseBodyResultHandler : Using 'application/json' given [*/*] and supported [application/json, application/*+json, text/event-stream] 2020-02-07 17:58:04.641 DEBUG 17132 --- [ parallel-1] o.s.w.r.r.m.a.ResponseBodyResultHandler : [3197f3be] 0..1 [com.example.demo.webflux.Card] 2020-02-07 17:58:04.655 DEBUG 17132 --- [ parallel-1] org.springframework.web.HttpLogging : [3197f3be] Decoded [Card{id='testing', amount=10}] 2020-02-07 17:58:04.655 DEBUG 17132 --- [ parallel-1] org.springframework.web.HttpLogging : [3197f3be] Encoding [Card{id='testing', amount=10}] 2020-02-07 17:58:04.658 DEBUG 17132 --- [ parallel-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [3197f3be] Completed 200 OK 2020-02-07 17:58:04.661 DEBUG 17132 --- [ parallel-1] o.s.w.r.f.client.ExchangeFunctions : [3292d91a] Response 200 OK 2020-02-07 17:58:04.670 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [3292d91a] Decoded [Card{id='testing', amount=10}] 2020-02-07 17:58:04.671 DEBUG 17132 --- [ main] o.s.w.r.f.client.ExchangeFunctions : [681c0ae6] HTTP GET /cards/testing 2020-02-07 17:58:04.672 DEBUG 17132 --- [ parallel-2] o.s.w.s.adapter.HttpWebHandlerAdapter : [799a50a] HTTP GET "/cards/testing" 2020-02-07 17:58:04.672 DEBUG 17132 --- [ parallel-2] s.w.r.r.m.a.RequestMappingHandlerMapping : [799a50a] Mapped to com.example.demo.webflux.CardController#find(String) 2020-02-07 17:58:04.689 DEBUG 17132 --- [ parallel-2] o.s.w.r.r.m.a.ResponseBodyResultHandler : Using 'application/json' given [*/*] and supported [application/json, application/*+json, text/event-stream] 2020-02-07 17:58:04.689 DEBUG 17132 --- [ parallel-2] o.s.w.r.r.m.a.ResponseBodyResultHandler : [799a50a] 0..1 [com.example.demo.webflux.Card] 2020-02-07 17:58:04.689 DEBUG 17132 --- [ parallel-2] org.springframework.web.HttpLogging : [799a50a] Encoding [Card{id='testing', amount=10}] 2020-02-07 17:58:04.690 DEBUG 17132 --- [ parallel-2] o.s.w.s.adapter.HttpWebHandlerAdapter : [799a50a] Completed 200 OK 2020-02-07 17:58:04.690 DEBUG 17132 --- [ parallel-2] o.s.w.r.f.client.ExchangeFunctions : [681c0ae6] Response 200 OK 2020-02-07 17:58:04.691 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [681c0ae6] Decoded [Card{id='testing', amount=10}] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.4.RELEASE) 2020-02-07 17:58:04.725 INFO 17132 --- [ main] com.example.demo.CardControllerTest : Starting CardControllerTest on DESKTOP-6HPEM1U with PID 17132 (started by k in D:\example\springboot2_mvc_example2) 2020-02-07 17:58:04.726 INFO 17132 --- [ main] com.example.demo.CardControllerTest : No active profile set, falling back to default profiles: default 2020-02-07 17:58:04.887 WARN 17132 --- [ main] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration) 2020-02-07 17:58:04.927 DEBUG 17132 --- [ main] s.w.r.r.m.a.RequestMappingHandlerMapping : 3 mappings in 'requestMappingHandlerMapping' 2020-02-07 17:58:04.938 DEBUG 17132 --- [ main] o.s.w.r.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping' 2020-02-07 17:58:04.945 DEBUG 17132 --- [ main] o.s.w.r.r.m.a.ControllerMethodResolver : ControllerAdvice beans: none 2020-02-07 17:58:04.970 DEBUG 17132 --- [ main] o.s.w.s.adapter.HttpWebHandlerAdapter : enableLoggingRequestDetails='false': form data and headers will be masked to prevent unsafe logging of potentially sensitive data 2020-02-07 17:58:04.977 INFO 17132 --- [ main] com.example.demo.CardControllerTest : Started CardControllerTest in 0.275 seconds (JVM running for 3.638) 2020-02-07 17:58:04.985 DEBUG 17132 --- [ main] o.s.w.r.f.client.ExchangeFunctions : [6e24ce51] HTTP GET /cards 2020-02-07 17:58:04.986 DEBUG 17132 --- [ parallel-3] o.s.w.s.adapter.HttpWebHandlerAdapter : [6ecad107] HTTP GET "/cards" 2020-02-07 17:58:04.987 DEBUG 17132 --- [ parallel-3] s.w.r.r.m.a.RequestMappingHandlerMapping : [6ecad107] Mapped to com.example.demo.webflux.CardController#list() 2020-02-07 17:58:04.989 DEBUG 17132 --- [ parallel-3] o.s.w.r.r.m.a.ResponseBodyResultHandler : Using 'application/json' given [*/*] and supported [application/json, application/*+json, text/event-stream] 2020-02-07 17:58:04.989 DEBUG 17132 --- [ parallel-3] o.s.w.r.r.m.a.ResponseBodyResultHandler : [6ecad107] 0..N [com.example.demo.webflux.Card] 2020-02-07 17:58:08.227 DEBUG 17132 --- [ parallel-4] org.springframework.web.HttpLogging : [6ecad107] Encoding [[Card{id='da161f4d-e254-4fc9-bb8b-fb670ef5ad2d', amount=659.0522665576615}, Card{id='5530d41c-011a-4 (truncated)...] 2020-02-07 17:58:08.245 DEBUG 17132 --- [ parallel-4] o.s.w.s.adapter.HttpWebHandlerAdapter : [6ecad107] Completed 200 OK 2020-02-07 17:58:08.246 DEBUG 17132 --- [ parallel-4] o.s.w.r.f.client.ExchangeFunctions : [6e24ce51] Response 200 OK 2020-02-07 17:58:08.275 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='da161f4d-e254-4fc9-bb8b-fb670ef5ad2d', amount=659.0522665576615}] 2020-02-07 17:58:08.275 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='5530d41c-011a-4629-b30f-65aad141d8d5', amount=669.8575292584534}] 2020-02-07 17:58:08.275 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='926b2cd6-779e-4a3a-b97a-09da4b6f97af', amount=338.3035760151568}] 2020-02-07 17:58:08.275 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='e8fd87d0-bde1-4173-ba42-bb12a956160b', amount=515.5512222387798}] 2020-02-07 17:58:08.275 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='c985071b-811b-4a4b-9981-4c1d2b8a2d26', amount=278.3756988497931}] 2020-02-07 17:58:08.276 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='f180b893-e99f-46be-a2b7-29bb6c46437c', amount=200.92289669217755}] 2020-02-07 17:58:08.276 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='7fca9666-b9e6-4b03-b1f1-aaab789d8bb1', amount=390.8201460458427}] 2020-02-07 17:58:08.276 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='8d632e16-fada-43be-825b-e89efdef7e2f', amount=772.1074666551409}] 2020-02-07 17:58:08.276 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='e3309c99-5931-4bd6-9388-0308d18cab60', amount=868.0882497704239}] 2020-02-07 17:58:08.276 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='67d5fbb9-3fa0-411e-8d80-08de2166de75', amount=679.5303928293825}] 2020-02-07 17:58:08.277 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='37362d4f-12ff-4fd0-92ce-cdf9c8e8b7e5', amount=832.2186440873733}] 2020-02-07 17:58:08.277 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='427b2b54-8606-4fe0-8c64-f09b11a60274', amount=309.9820548527883}] 2020-02-07 17:58:08.278 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='95dac2a3-cf0f-408b-b9c2-60d1937030a7', amount=361.01687930036155}] 2020-02-07 17:58:08.278 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='3c967ba8-8d19-446c-9a27-2d4b585838f7', amount=234.5998709781486}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='0a2716fb-5dcd-4b11-9392-912ae5a4db0f', amount=976.061671867787}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='546f860a-089e-4e28-b39b-6e5407b8ec96', amount=82.31128086883255}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='1db6c3e4-2055-4135-b455-227e11999869', amount=425.3299014061639}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='18ea3d00-ca76-4d63-be80-3d8efb7aaeec', amount=185.5251194325548}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='2db1a641-49c8-4445-a77b-99d74a3b823d', amount=809.275785593634}] 2020-02-07 17:58:08.279 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='07b383a7-90b9-4543-9676-24c27dafeb68', amount=412.76390856409364}] 2020-02-07 17:58:08.280 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='f1c0193a-9d0d-4c9d-ba43-0f6d942d4fe9', amount=350.25851366772054}] 2020-02-07 17:58:08.280 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='a14e2b6d-e2e7-4c80-a0d8-c9f4166be729', amount=471.81447302836557}] 2020-02-07 17:58:08.280 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='e45459eb-556a-49a2-9873-8f505bf1a961', amount=351.01581888891343}] 2020-02-07 17:58:08.280 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='adaff80b-5e24-46e4-b0f7-12409c89049c', amount=324.3402624523364}] 2020-02-07 17:58:08.280 DEBUG 17132 --- [ main] org.springframework.web.HttpLogging : [6e24ce51] Decoded [Card{id='7ea78c2a-ca4b-41ca-a749-2ddd461f0947', amount=192.41128201566548}] Process finished with exit code 0 | cs |
반응형
'WEB > 스프링 부트 2' 카테고리의 다른 글
Spring Security (0) | 2020.02.10 |
---|---|
WebFlux + Thymeleaf (0) | 2020.02.07 |
비동기 Emitter (0) | 2020.02.06 |
Jetty SSL, Http to Https (0) | 2020.02.06 |
Spring SSL, Http to Https (0) | 2020.02.05 |