Использование Spring @Retryable с десериализацией Джексона JSON - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь использовать Spring Retry для десериализации Джексона в объект POJO, например:

@Data
public class myPOJO {
    private String cmpStr = "test";
    private String myStr;

    @Retryable(maxAttempts=3, value=RuntimeException.class, backoff=@Backoff(delay=3000))
    @JsonProperty("jsonElement")
    private void retryableFunc(Map<String, Object> jsonElement) {
        try {
            myStr = jsonElement.get("jsonAttribute");
            if (!Objects.equals(myStr, cmpStr))
                throw new RuntimeException("Bad Response");
        }
        catch (Exception e) {
            throw new RuntimeException("Bad Response");
        }
    }

    @Recover
    private void recover(Exception e) {
        System.out.println("Recover triggered");
    }
}

MyPOJO создается следующим образом:

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singleTonList(MediaType.APPLICATION_JSON));
String jsonAttribute = restTemplate.exchange(URL, HttpMethod.GET, new HttpEntity<>(headers), myPOJO.class).getBody().getMyStr();

Основное приложение выглядит следующим образом:

@SpringBootApplication
@EnableRetry
public class mainApplication {
    public static void main(String[] args) {
        SpringApplication.run(mainApplication.class, args);
    }
}

Ответ JSON выглядит следующим образом:

{
    "jsonElement": {
        "jsonAttribute": "test1"
    }
}

Повтор не запускается, но генерируется исключение:

Error while extracting response for type myPOJO and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Bad Response; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Bad Response

1 Ответ

0 голосов
/ 26 июня 2019

Я думаю, у вас есть некоторые основные недоразумения. Spring Retry может применяться только к бобам, которыми управляет Spring. Ваш POJO может быть создан компонентом Spring (RestTemplate), это не управляемый @Bean в контексте приложения.

Вы не можете использовать повтор на основе аннотации для объектов, которые не управляются контекстом приложения.

Вы все еще не показали, как вы вызываете retryableFunc, но вместо этого вы должны вызывать свой объект из какого-то вспомогательного компонента:

public class MyHelper {

    @Retryable(...)
    public void validateMyPojo(MyPojo pojo, Map<...,...> jsonElement) {
        pojo.retryableFunc(jsonElement);
    }

}

и

@Bean
public MyHelper myHelper() {
    return new MyHelper();
}

Или вы можете просто использовать RetryTemplate для вызова метода.

...