JAVA&JSP

Spring WebClient를 사용하여 POST 요청을 전송

강준한 2024. 4. 30. 10:53

클로드의 예시

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import com.example.model.Data;

public class WebClientExample {

    public static void main(String[] args) {
        WebClient webClient = WebClient.create("http://example.com");

        Data data = new Data("Sample Data");

        webClient.post()
                .uri("/api/data")
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(data))
                .retrieve()
                .bodyToMono(String.class)
                .map(ResponseEntity::ok)
                .onErrorResume(WebClientResponseException.class,
                        ex -> ex.getRawStatusCode() == 404 ? Mono.just(ResponseEntity.notFound().build()) : Mono.error(ex))
                .subscribe(response -> handleResponse(response));
    }

    private static void handleResponse(Object response) {
        System.out.println("Response received: " + response);
    }
}

 

이를 응용 하여 

 

@Configuration 에 빈으로 등록

 

private HttpClient httpClientConfig(int sec){
    int timeOut = sec * 1000;
    return HttpClient.create()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeOut)
            .responseTimeout(Duration.ofMillis(timeOut))
            .doOnConnected(conn -> conn
                    .addHandlerLast(new ReadTimeoutHandler(timeOut, TimeUnit.MILLISECONDS))
                    .addHandlerLast(new WriteTimeoutHandler(timeOut, TimeUnit.MILLISECONDS)));
}

private ExchangeStrategies exchangeStrategiesConfig(){
    ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
            .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(1024*1024*50))
            .build();
    exchangeStrategies
            .messageWriters().stream()
            .filter(LoggingCodecSupport.class::isInstance)
            .forEach(writer -> ((LoggingCodecSupport)writer).setEnableLoggingRequestDetails(true));

    return exchangeStrategies;
}

private ExchangeFilterFunction logRequest(){
    return ExchangeFilterFunction.ofRequestProcessor(
            clientRequest -> {
                log.debug("Request: {} {}", clientRequest.method(), clientRequest.url());
                clientRequest.headers().forEach((name, values) -> values.forEach(value -> log.debug("{} : {}", name, value)));
                return Mono.just(clientRequest);
            }
    );
}

private ExchangeFilterFunction logResponse(){
    return ExchangeFilterFunction.ofResponseProcessor(
            clientResponse -> {
                log.debug("Response: {}", clientResponse.statusCode());
                clientResponse.headers().asHttpHeaders().forEach((name, values) -> values.forEach(value -> log.debug("{} : {}", name, value)));
                return Mono.just(clientResponse);
            }
    );
}

@Bean(name = "testWebClient")
    public WebClient testWebClient() {
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClientConfig(15)))
                .baseUrl("http://localhost:8080")
                .exchangeStrategies(exchangeStrategiesConfig())
                .filter(logRequest())
                .filter(logResponse())
                .build();

    }

 

어쩌다보니 필터 로깅 하는 거까지 하게 됬습니다.

 

 

 

@Service
@RequiredArgsConstructor
@Slf4j
public class Client {
    private final WebClient testWebClient;

    public Mono<String> testWebClient(final MultiValueMap<String, HttpEntity<?>> formData) {
        return testWebClient.post()
                .uri(uriBuilder -> uriBuilder
                        .path("/test")
                        .build())
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .bodyValue(formData)
                .retrieve()
                .bodyToMono(String.class)
                .doOnNext(responseBody -> log.debug("Body: {}", responseBody.trim()));
    }
}

 

 

빈으로 등록한 웹클라이언트를 가져와서 서비스코딩 해주고

 

MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();

formData.add("subject", "테스트");

client.testWebClient(formData, fsr.contentLength()).subscribe(
                        responseString -> { //이하생략

 

 

반응형