मैं सफलता के बिना निम्नलिखित उपयोग के मामले का समाधान ढूंढ रहा हूं, मुझे आशा है कि कोई मदद कर सकता है:

निम्नलिखित उपयोग के मामले को मानते हुए। मुझे एक ग्राहक एपी (customerApi) को कॉल करने की आवश्यकता है और इस एपीआई को एक Bearer टोकन की आवश्यकता है जो कि मेरे द्वारा customerApi को कॉल करने पर समाप्त हो सकता है। यदि टोकन समाप्त हो गया है, तो customerApi एक 401 प्रतिक्रिया देता है।

मैं केवल एक बार पुनः प्रयास करना चाहता हूं यदि मुझे 401 प्राप्त हुआ है और एक नया Bearer टोकन प्राप्त करने के लिए विधि को कॉल करें। यदि पुनः प्रयास अभी भी 401 लौटाता है, तो मुझे एक Exception फेंकना होगा

Bearer टोकन प्राप्त करने की विधि:

private String getToken() {
    return oAuthService.getToken();
}

और webClient कॉल करने के लिए उपयोग customerApi (customerWebClient WebClient.Builder के साथ बनाया गया बीन है):

public Customer getCustomerById(String customerId, String token) {
        return customerWebClient.get()
            .uri("myurl/customers/{customerId}, customerId)
            .headers(httpHeaders -> {
                httpHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
            })
            .retrieve()
            .bodyToMono(Customer.class)
            .onErrorResume(WebClientResponseException.NotFound.class, notFound ->
                        Mono.error(new MyCustomException()))
            .block();
    }

ऐसा लगता है कि retryWhen का उपयोग केवल टाइमआउट अपग्रेड करने के लिए किया जा सकता है। तो मुझे आशा है कि कोई जानता है कि इस उपयोग के मामले को कैसे प्राप्त किया जाए ^^

आपकी सहायता के लिए धन्यवाद :)

संपादित करें:

मैंने reactor-extra से retryWhen(Retry.onlyIf(...)) का उपयोग करने की कोशिश की लेकिन इस पैकेज से अच्छे पुराने retryWhen को अब हटा दिया गया है (इस पर आधारित समाधान: वेब क्लाइंट के सभी अनुरोधों को पुनः प्रयास करना जोड़ना)

1
Pierre Jones 14 अक्टूबर 2020, 17:05

1 उत्तर

सबसे बढ़िया उत्तर

विधि

public final Mono<T> retryWhen(Function<Flux<Throwable>, ? extends Publisher<?>> whenFactory)

पदावनत कर दिया गया है और अब पसंदीदा तरीका है

public final Mono<T> retryWhen(Retry retrySpec)

इसलिए, आप अपने कोड को कुछ इस तरह संशोधित कर सकते हैं ताकि वह नए retryWhen के साथ काम कर सके।

public Customer getCustomerById(String customerId, String token) {

    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);

    final RetrySpec retrySpec = Retry.max(1).doBeforeRetry(
        retrySignal -> headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + someTokenGetterMethod()))
        .filter(throwable -> throwable.getClass() == Unauthorized.class);

    return Mono.defer(() -> webClient.get().uri("myurl/customers/{customerId}, customerId")
        .headers(httpHeaders -> httpHeaders.addAll(headers))
        .retrieve()
        .bodyToMono(Customer.class))
        .retryWhen(retrySpec)
        .onErrorResume(WebClientResponseException.NotFound.class,
            notFound -> Mono.error(new MyCustomException()))
        .block();
}

यहां https://httpbin.org/ का उपयोग करके एक कार्यशील उदाहरण दिया गया है

public CommandLineRunner commandLineRunner() {

    HttpHeaders headers = new HttpHeaders();

    final RetrySpec retrySpec = Retry.max(1).doBeforeRetry(
        retrySignal -> headers.add("Authorization", "Bearer 1234")).filter(
        throwable -> throwable.getClass() == Unauthorized.class);

    return args -> Mono.defer(() -> webClient.get().uri("https://httpbin.org/bearer")
        .headers(httpHeaders -> httpHeaders.addAll(headers)).retrieve().toEntity(Map.class)
        .retryWhen(retrySpec)
        .subscribe(objectResponseEntity -> System.out
            .println("objectResponseEntity = " + objectResponseEntity.getBody()));
}

साथ ही, मुझे नहीं लगता कि जिस तरह से आप प्राधिकरण टोकन जोड़ने के लिए पुन: प्रयास में शीर्षलेखों में हेरफेर करने का प्रयास कर रहे हैं, वह इसे प्राप्त करने का सही तरीका है। आपको बेहतर समाधान/डिज़ाइन के साथ आना चाहिए।

1
Isank 20 अक्टूबर 2020, 21:29