나는 Springboot Resttemplate를 사용하는 springboot 프로젝트가 있습니다. 우리는 1.5.3에서 springboot 2.0.1로 이동 한 우리는 웹 클라이언트를 사용하여 비동기 그것에서 나머지 통화를 위해 노력하고 있습니다. 우리는 아래로 Resttemplate를 사용하여받은 문자열을 처리하는 데 사용. 그러나 웹 클라이언트는 모노 또는 플럭스 만 데이터를 반환합니다. 어떻게 문자열로 데이터를 얻을 수 있습니다. 이미 블록 () 메소드를 시도하지만, 비동기 호출을 수행합니다.
@Retryable(maxAttempts = 4, value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public Mono<String> getResponse(String url) {
return webClient.get().uri(urlForCurrent).accept(APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class);
}
RestTemplate와 현재의 데이터 흐름
- 컨트롤러는 클라이언트 호출을 수신
- 제공자는 문자열 형식으로 데이터를 가져옵니다
- 공급자는 문자열을 처리
- 데이터는 제어기로 주어진다
Controller.java
@RequestMapping(value = traffic/, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public String getTraffic(@RequestParam("place") String location) throws InterruptedException, ExecutionException {
String trafficJSON = Provider.getTrafficJSON(location)
return trafficJSON;
}
Provider.java
public String getTrafficJSON(String location) {
String url = ----;
ResponseEntity<String> response = dataFetcher.getResponse(url);
/// RESPONSEBODY IS READ AS STRING AND IT NEEDS TO BE PROCESSED
if (null != response {
return parser.transformJSON(response.getBody(), params);
}
return null;
}
DataFetcher.java
@Retryable(maxAttempts = 4,
value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public ResponseEntity<String> getResponse(String url) {
/* ----------------------- */
return getRestTemplate().getForEntity(urlForCurrent, String.class);
}
때문에, 그래서 여기에 오해의 많은 있다는 사실에 나는 몇 가지를 정리하겠습니다.
봄은 공식적으로는 지양 것을 주장했다 RestTemplate
, 사용 할 수 있다면, 그래서 미래에 WebClient
가능한 한 미래의 증거로되고 싶어합니다.
에 명시된 바와 같이 RestTemplate API
참고 : 5.0로, 비 차단, 반응
org.springframework.web.reactive.client.WebClient
받는 이벤트 현대적인 대안RestTemplate
동기 및 비동기 모두를위한 효율적인 지원뿐만 아니라, 스트리밍 시나리오. 는RestTemplate
향후 버전에서 더 이상 사용되지 않습니다 및 향후 추가 된 새로운 주요 기능이 없습니다. 참고 항목WebClient
자세한 내용과 예제 코드를위한 Spring 프레임 워크 참조 문서의 섹션을 참조하십시오.
비 반응성 응용 프로그램
응용 프로그램이 비 반응성 응용 프로그램입니다 경우 당신이해야 할 것은 사용하는 것입니다 (호출 클라이언트에 플럭스 또는 MONOS 반환하지 않습니다) block()
당신이 값을 필요로하는 경우입니다. 당신은 물론 사용의 수 Mono
또는 Flux
응용 프로그램에서하지만 결국 내부적으로 당신은 호출해야 block()
당신이 호출 클라이언트에 반환해야하는 구체적인 값을 얻을 수 있습니다.
비 반응성 응용 프로그램을 사용하는 tomcat
당신은 반응성 응용 프로그램과 함께 얻는 성능 향상을 얻을되지 않도록 요청에 따라 1 개 스레드를 할당하는 서블릿 기반 서버 인 기본 서버 구현한다.
톰캣의 최신 버전은 차례로 지원하는 최신 서블릿 스펙 3.0 지원하는 I / O 비 차단 하지만,이 지원이 WebFlux 애플리케이션을 위해 얼마나 봄의 문서에서 명확하지이 글을 쓰는 같습니다.
반응성 응용 프로그램
당신은 다른 한편으로는 반응성 응용 프로그램이있는 경우에 당신은 어떤 상황 적 호출해서는 안됩니다 아래 block()
또는 subscribe()
응용 프로그램입니다. 그것은, 그것은 스레드 실행이 이동할 수 있습니다 때까지 스레드 블록을 차단하는 것이라고 정확히 무엇을 차단,이 반응성 세계에 좋지 않습니다.
여기 서버 구현을 근본적인 것은 인 netty
것이다 비 서블릿, 이벤트 기반 서버입니다 서버 되지 할당 한 스레드가 각 요청에, 서버 자체가 스레드 무관하며 요청시 언제든지 스레드를 사용할 의지 핸들 아무것도이다.
어떻게하면 내가 가지고있는 응용 프로그램을 알 수 있습니까?
봄 상태 당신이 모두있는 경우 spring-web
와 spring-webflux
클래스 패스에 응용 프로그램이 선호됩니다 spring-web
하고, 기본적으로 기초 바람둥이 서버와 비 반응성 응용 프로그램을 시작합니다.
스프링 상태로 필요한 경우이 문제가 수동으로 재정의 할 수 있습니다.
모두 추가
spring-boot-starter-web
및spring-boot-starter-webflux
봄 부팅 자동 구성 스프링 MVC하지 WebFlux에서 응용 프로그램 결과에 모듈을. 많은 봄 개발자가 추가되어 있기 때문에이 문제가 선택되었다spring-boot-starter-webflux
반응 웹 클라이언트를 사용하여 자신의 스프링 MVC 응용 프로그램. 당신은 여전히에 선택한 응용 프로그램 유형을 설정하여 선택 사항을 적용 할 수 있습니다SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)
.
그래서 웹 클라이언트를 구현하는 방법
@Retryable(maxAttempts = 4,
value = java.net.ConnectException.class,
backoff = @Backoff(delay = 3000, multiplier = 2))
public ResponseEntity<String> getResponse(String url) {
return webClient.get()
.uri(url)
.exchange()
.flatMap(response -> response.toEntity(String.class))
.block();
}
이것은 가장 쉽고 가장 덜 침해 구현입니다. 당신은 어쩌면에 적절한 웹 클라이언트를 구축 할 필요가 당연히 @Bean
그 클래스로를 autowire하기를.