Как инициализировать WebClient, используя базовую инициализацию конструктора в Java? - PullRequest
3 голосов
/ 17 октября 2019

Я попытался заменить RestTemplate из WebClient, потому что в соответствии с Java Doc RestTemplate будет устаревшим. Команда Spring рекомендует использовать WebClient, если это возможно.

предыдущий код с RestTempalte выглядит следующим образом

public Map<String,String> getInfo()
    {
        HttpHeaders headers = new HttpHeaders();
        headers.set( ACCEPT, MediaType.APPLICATION_JSON_VALUE );
        HttpEntity<?> entity = new HttpEntity<>( headers );
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl( this.endpoint + VERSION_INFO_PATH );

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<CPResponse> response = restTemplate.exchange(
                builder.toUriString(),
                HttpMethod.GET,
                entity,
                CPResponse.class );


        List<Object> resultList = response.getBody().getResults();

        if( response.getBody().getResults() != null && !( resultList )
                                                                .isEmpty() )
        {

            return ( ( LinkedHashMap ) resultList.get( 0 ) );
        }
        else
        {
            throw new CrawlerRuntimeExceptions( "Invalid response from API" );
        }

    }

Я хочу заменить RestTemplate из WebClient. Поэтому я реализую класс WebClientConnection следующим образом:

public class WebClientConnection
{
   private WebClient webClient;


    public WebClientConnection( String baseUrl )
    {
        this.webClient = WebClient.create( baseUrl );

    }

    public  Mono<CPResponse> get( String url )
    {
        return webClient.get().uri( "/{url}",url ).retrieve().bodyToMono( CPResponse.class );
    }

    public  Flux<CPResponse> getAll( String url )
    {
        return webClient.get().uri( "/{url}",url ).retrieve().bodyToFlux( CPResponse.class );
    }

    public  Mono<CPResponse> post( String url, HttpEntity entity )
    {
        return webClient.post().uri( "/{url}",url ).retrieve().bodyToMono( CPResponse.class );
    }
}

Я использую эту зависимость

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-webflux</artifactId>
   <version>>2.1.3.RELEASE</version>
</dependency>
public void getInfo()
    {
        WebClientConnection webClientConnection = new WebClientConnection( endpoint );
        Mono<CPResponse> response = webClientConnection.get( VERSION_INFO_PATH );
    }

При создании веб-клиента возникает ошибка stackOverflow

public WebClientConnection( String baseUrl )
    {
        this.webClient = WebClient.create( baseUrl );

    }

Какправильно ли выполнить эту миграцию с RestTemplate на WebClient?

Ответы [ 2 ]

1 голос
/ 17 октября 2019

На самом деле, исключение StackOverflow javadoc :

Брошено, когда переполнение стека происходит из-за слишком глубокого повторения приложения.

(хорошее объяснение здесь )

Само по себе создание WebClient не содержит такой рекурсии. Возможно, вы где-то (неявно) используете рекурсию?

Трассировка стека может помочь выяснить, в чем проблема.

0 голосов
/ 17 октября 2019

Я выясняю проблему. Это зависимость с проблемами кода. После добавления

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

в pom и изменения класса WebClientConnection следующим образом.

public class WebClientConnection
{
    private final WebClient webClient;
    private static final String API_MIME_TYPE = "application/json";
    private static final String API_BASE_URL = "http://localhost:8080";
    private static final String USER_AGENT = "Spring 5 WebClient";

    public WebClientConnection( )
    {
        this.webClient = WebClient.builder()
                                  .baseUrl(API_BASE_URL)
                                  .defaultHeader(HttpHeaders.CONTENT_TYPE, API_MIME_TYPE)
                                  .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
                                  .build();
    }

    public  Mono<CPResponse> get( String url )
    {
        return webClient.get().uri( "/{url}",url ).retrieve().bodyToMono( CPResponse.class );
    }

    public  Flux<CPResponse> getAll( String url )
    {
        return webClient.get().uri( "/{url}",url ).retrieve().bodyToFlux( CPResponse.class );
    }

    public  Mono<CPResponse> post( String url, HttpEntity entity )
    {
        return webClient.post().uri( "/{url}",url ).retrieve().bodyToMono( CPResponse.class );
    }
}

Тогда проблема устранена.

...