es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cambio de modo de codificación condicional en el cliente web.

He creado el bean WebClient de la siguiente manera:

@Bean
public WebClient webClient(final HttpClient httpClient) {
    return WebClient
            .builder()
            .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(codecInmemoryMaxSize))
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();
}

Estoy reutilizando el mismo bean para hacer llamadas HTTP como:

public Mono<responsemodel> get(final String url) {
    return webClient.get().uri(url)
            .exchangeToMono(clientResponse -> clientResponse.toEntity(String.class)
                    .map(responseEntity -> new ResponseModel(responseEntity.getBody(), responseEntity.getStatusCode().value(),
                            CollectionUtils.toMultiValueMap(responseEntity.getHeaders().entrySet().stream()
                                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))))));
}

Deseo establecer el modo de codificación de manera condicional al llamar a la API. ¿Existe alguna forma de hacerlo?
Sé que hay una forma de establecer un factory como sigue:

DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
return WebClient
        .builder()
        .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(codecInmemoryMaxSize))
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .uriBuilderFactory(factory)
        .build();

Pero esto se aplicará a nivel del bean, por lo que la API seguirá el mismo modo de codificación. Deseo hacerlo de manera condicional al llamar a la API.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible establecer el modo de codificación condicionalmente al llamar a la API utilizando WebClient. Puedes lograr esto creando una nueva instancia de WebClient con el modo de codificación requerido y luego usándola para las llamadas a la API según la condición.

    Por ejemplo, puedes crear un método que acepte un indicador booleano que indique si se requiere la codificación o no, y cree una nueva instancia de WebClient en consecuencia:

    @Bean
    public WebClient defaultWebClient(final HttpClient httpClient) {
        return WebClient
                .builder()
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(codecInmemoryMaxSize))
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
    
    public WebClient getWebClient(boolean encodingRequired) {
        if (encodingRequired) {
            DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
            factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
            return WebClient.builder()
                    .clientConnector(new ReactorClientHttpConnector(HttpClient.create()))
                    .uriBuilderFactory(factory)
                    .build();
    
        } else {
            return defaultWebClient(HttpClient.create());
        }
    }
    

    En el ejemplo anterior, el bean defaultWebClient crea una instancia predeterminada de WebClient que se utilizará para las llamadas a la API cuando no se requiera codificación.

    El método getWebClient crea una nueva instancia de WebClient con el modo de codificación requerido en función del indicador booleano. Si se requiere codificación, crea una nueva instancia de WebClient con el modo de codificación especificado, y si no, devuelve la instancia predeterminada de WebClient.

    Luego puedes usar el método getWebClient para realizar llamadas a la API, pasando el indicador booleano según el requisito de codificación:

    public Mono<responsemodel> get(final String url, boolean encodingRequired) {
        WebClient webClient = getWebClient(encodingRequired);
    
        return webClient.get().uri(url)
                .exchangeToMono(clientResponse -> clientResponse.toEntity(String.class)
                        .map(responseEntity -> new ResponseModel(responseEntity.getBody(), responseEntity.getStatusCode().value(),
                                CollectionUtils.toMultiValueMap(responseEntity.getHeaders().entrySet().stream()
                                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))))));
    }
    

    En el ejemplo anterior, el método get acepta un indicador booleano que indica si se requiere codificación o no, y llama al método getWebClient para obtener la instancia adecuada de WebClient. Luego se realiza la llamada a la API utilizando esta instancia de WebClient.

Comments are closed.