解决feign接口返回泛型设置属性为null的问题

Feign是一种用于声明式、模板化HTTP客户端的工具。在使用Feign时,有时可能会遇到接口返回泛型数据时属性为null的问题。这是由于默认情况下Feign将返回的ResponseBody转换为String类型,而在将其转换成目标类型时,如果某些属性为null,则不会进行初始化。因此,需要手动对此问题进行处理,以保证数据的正确性。下面是解决此问题的完整攻略:

1. 示例一

1.1 编写自定义解码器

针对接口返回的泛型数据,我们可以自定义一个解码器,将返回的响应数据转换成目标类型。以下是一个示例代码:

public class GenericDecoder implements Decoder {

    private final Gson gson;

    public GenericDecoder() {
        gson = new Gson();
    }

    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {
        if (response.body() == null) {
            return null;
        }
        String json = response.body().toString();
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        JsonObject data = jsonObject.get("data").getAsJsonObject();
        return gson.fromJson(data, type);
    }
}

1.2 配置FeignClient

在使用FeignClient的地方,我们需要配置一下FeignClient,使用自定义的解码器,以将返回的响应数据正确地转换成目标类型。以下是一个示例代码:

@FeignClient(name = "example-service", url = "${example-service.url}", configuration = ExampleServiceFeignClient.CustomConfig.class)
public interface ExampleServiceFeignClient {

    @RequestMapping(method = RequestMethod.GET, value = "/users")
    List<User> listUsers();

    class CustomConfig {

        @Bean
        public Decoder decoder() {
            return new GenericDecoder();
        }

    }
}

2. 示例二

2.1 使用泛型参数

如果我们的FeignClient接口使用了泛型参数,可以在声明泛型参数时,使用类型通配符来限制泛型的类型。以下是一个示例代码:

public interface ExampleServiceFeignClient<T> {

    @RequestMapping(method = RequestMethod.GET, value = "/data")
    ResponseEntity<T> getData();

    class CustomConfig implements DecoderContract {

        @Override
        public void contract(RequestTemplate requestTemplate) {
            Type returnType = contractReturnType(requestTemplate);
            if (returnType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) returnType;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                if (actualTypeArguments.length == 1 && actualTypeArguments[0] instanceof Class) {
                    requestTemplate.header("Accept", MediaType.APPLICATION_JSON.toString());
                }
            }
        }

    }

}

2.2 配置解码器

在使用泛型参数的地方,我们需要配置一个解码器,以将返回的响应数据正确地转换成目标类型。以下是一个示例代码:

@Configuration
public class FeignConfig {

    @Bean
    public Decoder decoder() {
        return (response, type) -> {
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                if (actualTypeArguments.length == 1 && actualTypeArguments[0] instanceof Class) {
                    Class<?> clazz = (Class<?>) actualTypeArguments[0];
                    if (response.body() == null) {
                        return null;
                    }
                    String json = response.body().toString();
                    JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
                    JsonObject data = jsonObject.get("data").getAsJsonObject();
                    return new Gson().fromJson(data, clazz);
                }
            }
            throw new DecodeException("fail to decode");
        };
    }

}

以上就是解决Feign接口返回泛型数据属性为null的完整攻略。通过参考以上示例代码,我们可以在实际开发中解决类似的问题。

本文标题为:解决feign接口返回泛型设置属性为null的问题

基础教程推荐