OpenFeign用自定義Decoder解決JSON下划線轉駝峰的問題


背景

最近使用Spring Cloud OpenFeign組件,訪問第三方開源系統,對方系統的字段都是下划線的,而建模的時候,全部按照駝峰方式。
如果全部JsonProperty方式,每一個Model類,每一個字段都要處理一遍非常麻煩。

更好的辦法(實測可用)

public class FeignClientEncoder extends SpringEncoder {

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        objectMapper.disable(JsonGenerator.Feature.IGNORE_UNKNOWN);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.disable(MapperFeature.DEFAULT_VIEW_INCLUSION);
    }

    public FeignClientEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
        super(messageConverters);
    }

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {

        try {
            super.encode(object, bodyType, template);
            template.body(objectMapper.writeValueAsString(object));
        } catch (Exception ex) {
            throw new CdException(CdExceptionEnum.SYSTEM_ERROR);
        }

    }

    public static class FeignClientDecoder extends SpringDecoder {
        public FeignClientDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
            super(messageConverters);
        }

        @Override
        public Object decode(Response response, Type type) throws IOException, FeignException {
            //FIX:Feign默認Body返回的是String,換成ApacheHttpClient以后是一個匿名類
            String result = IOUtils.toString(response.body().asInputStream());
            if (type instanceof Class && StringUtils.isNoneBlank(result)) {
                Response build = Response.builder()
                        .body(new ObjectMapper().writeValueAsString(
                                objectMapper.readValue(result,
                                        (Class<? extends Object>) type)),
                                StandardCharsets.UTF_8)
                        .headers(response.headers())
                        .reason(response.reason())
                        .status(response.status())
                        .request(response.request())
                        .build();
                        //思考:這里是不是可以直接返回,因為使用這個Decoder的FeignClient應該是某個系統專用的。
                        //return objectMapper.readValue(result, (Class<? extends Object>) type));
                return super.decode(build, type);
            }
            return super.decode(response, type);
        }
    }
}

一個小坑

在使用HTTP PATCH請求的時候,發現Feign不識別PATCH請求,則需要添加Feign-HttpClient依賴。

       <!--HTTP PATCH SUPPORT-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

在更換HttpClient之后,發現下方這樣寫是不正確的。我參考了其他人的博客,發現這樣寫確實不對。正確的寫法應該是IOUtils.toString(response.body().asInputStream());

 @Override
        public Object decode(Response response, Type type) throws IOException, FeignException {
            //FIX:Feign默認Body返回的是String,換成ApacheHttpClient以后是一個匿名類,而不是String正文。
            String result = response.body().toString();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM