首页 > 解决方案 > 将 Spring @Retryable 与 Jackson json 反序列化一起使用

问题描述

我正在尝试使用 Spring Retry 将 Jackson 反序列化为 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

标签: javajsonspring-bootjacksonspring-retry

解决方案


我认为你有一些基本的误解。Spring Retry 只能应用于 Spring 管理的 bean。您的 POJO 可能是由 Spring 组件 ( RestTemplate) 创建的,它不是@Bean在应用程序上下文中托管的。

您不能对不受应用程序上下文管理的对象使用基于注释的重试。

您仍然没有显示您是如何调用的,retryableFunc但是您应该从一些辅助 bean 调用您的对象:

public class MyHelper {

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

}

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

或者,您可以简单地使用 aRetryTemplate来调用该方法。


推荐阅读