Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 리눅스
- 스프링부트핵심가이드
- Kernighan의 C언어 프로그래밍
- 코드로배우는스프링부트웹프로젝트
- d
- 목록처리
- iterator
- 네트워크 설정
- /etc/network/interfaces
- 친절한SQL튜닝
- 처음 만나는 AI 수학 with Python
- 구멍가게코딩단
- 처음 만나는 AI수학 with Python
- 서버설정
- 티스토리 쿠키 삭제
- resttemplate
- ㅒ
- network configuration
- 스프링 시큐리티
- 자바편
- 코드로배우는스프링웹프로젝트
- 페이징
- 선형대수
- 데비안
- 알파회계
- 자료구조와 함께 배우는 알고리즘 입문
- 이터레이터
- 자료구조와함께배우는알고리즘입문
- GIT
- baeldung
Archives
- Today
- Total
bright jazz music
WebClient 01 : GET 본문
1. WebClient란?
- Spring Web Flux가 제공하는 클라이언트. HTTP 요청을 수행한다.
- WebClient는 Reactor 기반으로 동작하는 API이다. 리액터 기반이므로 스레드와 동시성 문제를 벗어나 비동기 형식으로 사용할 수 있다.
2. WebClient의 특징
- 논블로킹(Non-Blocking) I/O를 지원
- Reactve Stream의 Back Pressure 지원
- 적은 하드웨어 리소스로 동시성 지원
- 함수형 API 지원
- 동기, 비동기 상호작용 지원
- 스트리밍 지원
3. 사용
3.1 WebClient 사용을 위한 의존성 추가
WebFlux를 빌드 설정에 추가해 줘야 한다.
//build.gradle
dependencies {
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}
WebFlux는 클라이언트와 서버 간 리액티브 애플리케이션 개발을 지원하기 위해 스프링 5에서 새롭게 추가된 모듈이다.
3.2 WebClient 구현
WebClient를 생성하는 대표적인 두 가지 방법
- create()
- builder()
//WebClientGetService.java
package com.project.base.service;
import org.apache.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class WebClientGetService {
public String getName(){
//builder()를 사용한 WebClient 생성
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:9090") //기본 url설정
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //헤더 설정
.build(); //생성
System.out.println("## webClient " + webClient.toString());
return webClient.get()
.uri("/api/v1/crud-api") //
.retrieve() //요청에 대한 응답을 받았을 때 그 값을 추출하는 방법
.bodyToMono(String.class)
//.toEntity(String.class)
.block();
}
public ResponseEntity<String> getAsObject(){
//builder()를 사용한 WebClient 생성
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:9090") //기본 url설정
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) //헤더 설정
.build(); //생성
return webClient.get()
.uri(uriBuilder -> uriBuilder.path("/api/v1/crud-api")
.path("/get-as-object").build())
.retrieve()
//.bodyToMono(String.class)
.toEntity(String.class)
.block();
}
public String getNameWithPathVariable() {
//create()를 사용한 WebClient 생성
WebClient webClient = WebClient.create("http://localhost:9090");
ResponseEntity<String> responseEntity = webClient.get()
.uri(uriBuilder -> uriBuilder.path("/api/v1/crud-api/{server}/{who}")
.build("localhost:8080", "catnails"))
.retrieve()
.toEntity(String.class)
.block();
System.out.println("##responseEntity.getBody()" + responseEntity.getBody());
return responseEntity.getBody();
}
public String getNameWithParameter(){
WebClient webClient = WebClient.create("http://localhost:9090");
String returnValue = webClient.get()
.uri(uriBuilder -> uriBuilder.path("/api/v1/crud-api")
.path("/param")
.queryParam("name", "catnails")
.build())
.exchangeToMono(clientResponse -> {
if (clientResponse.statusCode().equals(HttpStatus.OK)) {
return clientResponse.bodyToMono(String.class);
}else {
return clientResponse.createException().flatMap(Mono::error);
}
})
.block();
System.out.println("## returnValue from service : " + returnValue);
//## returnValue from service : catnails from http://localhost:9090/api/v1/crud-api
return returnValue;
}
}
WebClient는 우선 객체를 생성한 후 전달하는 방식으로 동작한다.
.builder()를 활용해 WebClient를 생성하고 defaultHeader()를 사용하여 WebClient의 기본 헤더값을 설정한다.
- defaultHeader() : WebClient의 기본 헤더 설정
- defaultCookie() : WebClient의 기본 쿠키 설정
- defaultUriVariable() : WebClient의 기본 URI 확장값 설정
- filter() : WebClient에서 발생하는 요청에 대한 필터 설정
- retrieve() : 요청에 대한 응답에서 그 값을 추출하는 방법 중 하나
- bodyToMono(리턴 타입) : 리턴 타입인 String.class을 넣으면 문자열을 받아온다.
- toEntity(리턴 타입) : 리턴 타입을 설정하여 ResponseEntity 타입으로 응답을 받을 수 있다.
- block() : blocking 방식으로 동작하도록 설정한다.
- queryParam() : 파라미터를 요청에 담는다.
- exchange() : 응답 결과 코드에 따라 응답을 다르게 설정할 수 있다. deprecated 되었기 때문에 exchangeToFlux()를 사용해야 한다.
-WebClient는 기본적으로 non-blocking 방식으로 동작한다. 이를 blocking 방식으로 동작하도록 하려면 block() 메소드를 사용한다.
-uri() 메서드 내부에서 uriBuilder를 사용해 path 설정 후 build() 메서드에 추가 값을 넣어서 PathVariable을 추가한다.
-빌드된 WebClient는 변경 불가. 아래와 같이 복사해서 사용은 가능.
//webClient는 미리 생성한 WebClient 객체
WebClient Clone = webClient.mutate().build();
4. WebClientController 생성( 서비스와 연결하기 위해)
//WebClientController.java
package com.project.base.controller;
import com.project.base.service.WebClientGetService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/web-client")
public class WebClinetController {
private final WebClientGetService webClientGetService;
public WebClinetController(WebClientGetService webClientGetService) {
this.webClientGetService = webClientGetService;
}
@GetMapping("/get-name")
public String getName(){
//String 값 반환
return webClientGetService.getName();
}
@GetMapping("/get-as-object")
public ResponseEntity<String> getAsObject(){
//String 값 반환
return webClientGetService.getAsObject();
}
@GetMapping("get-name-with-path-variable")
public String getNameWithPathVariable(){
return webClientGetService.getNameWithPathVariable();
}
@GetMapping("/get-name-with-parameter")
public String getNameWithParameter(){
return webClientGetService.getNameWithParameter();
}
}
5. 요청을 받는 서버 (http://localhost:9090) 설정
//외부 API 역할을 하는 서버 => server.port=9090
package com.project.base.controller;
import com.project.base.domain.MemberDto;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/v1/crud-api")
public class CrudController {
/* GET: 파라미터가 없는 경우 */
@GetMapping
public String getName() {
return "catnails from http://localhost:9090/api/v1/crud-api";
}
/* GET: 파라미터가 없는 경우 json으로 받기*/
@GetMapping("get-as-object")
public MemberDto getAsObject() {
//return MemberDto.builder().name("catnails").email("catnails@gmail.com").organization("catnails company").build();
return new MemberDto("catnails", "catnails@gmail.com", "catnails company");
}
/* GET: PathVariable을 사용하는 경우 */
@GetMapping(value = "/{server}/{who}")
public String getVariable (@PathVariable(required = false) String server,
@PathVariable(required = false) String who) {
System.out.println("## server : " + server);
System.out.println("## who : " + who);
return "request from server : " + server + " who : " + who;
}
/* GET: RequestParameter를 사용하는 경우 */
@GetMapping("/param")
public String getNameWithParam(@RequestParam String name) {
return "Hello! " + name + "!";
}
/* POST: RequestParameter와 RequestBody를 받는 경우. (귀찮아서 한 번에 해버리는 예시) */
@PostMapping
public ResponseEntity<MemberDto> getMember(@RequestBody MemberDto request, @RequestParam String name,
@RequestParam String email, @RequestParam String organization) {
System.out.println("## request.getName() = " + request.getName());
System.out.println("## request.getEmail() = " + request.getEmail());
System.out.println("## request.getOrganization() = " + request.getOrganization());
MemberDto memberDto = new MemberDto(name, email, organization);
return ResponseEntity.status(HttpStatus.OK).body(memberDto);
}
/* POST: 임의의 HTTP 헤더를 RequestBody와 함께 받는 경우*/
@PostMapping(value = "/add-header")
public ResponseEntity<MemberDto> addHeader(@RequestHeader("my-header") String header, @RequestBody MemberDto memberDto) {
System.out.println(header);
return ResponseEntity.status(HttpStatus.OK).header(header).body(memberDto);
}
}
6. 호출 결과
'Framework > Spring' 카테고리의 다른 글
WebClient 02 : POST (0) | 2023.03.08 |
---|---|
RestTemplate 02 : 커넥션 풀(connection pool) 추가 (0) | 2023.03.06 |
RestTemplate 01 : 파라미터 없는 GET 요청 (0) | 2023.03.02 |
[bootBoard] N:1(다대일) 연관관계: 11-7. 목록화면에서 검색 처리 (0) | 2022.10.12 |
[bootBoard] N:1(다대일) 연관관계: 11-6. JPQLQuery로 Page<Object[]> 처리: sort 처리 / count 처리 (0) | 2022.10.11 |
Comments