3

I tried to replace RestTemplate from WebClient because according to the Java Doc the RestTemplate will be deprecated. Spring team advises using the WebClient if possible.

previous code with RestTempalte is as follows

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" );
        }

    }

I want to replace RestTemplate from WebClient. So I implement class WebClientConnection as follows

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 );
    }
}

I use this dependency

<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 );
    }

There is stackOverflow error on webclient create

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

    }

How to properly do this migration from RestTemplate to WebClient?

2 Answers2

1

Actually, StackOverflow exception javadoc:

Thrown when a stack overflow occurs because an application recurses too deeply.

(good explanation here)

In itself, creating a WebClient does not contain such recursion. Perhaps you are using (implicitly) recursion somewhere?

The stack trace could help to find out where the problem is.

K. Ilfat
  • 46
  • 4
1

I figure out the issue. It is a dependency with code issues. After add

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

to the pom and modify WebClientConnection class as follows.

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 );
    }
}

Then the issue is fixed.