spring-cloud feigin发送请求参数需要进行驼峰和下划线的转换

spring-cloud feigin发送请求参数需要进行驼峰和下划线的转换

背景

项目改造为sping-cloud, 依赖别人的feign(fei-api)服务,使用feign发送请求的时候,对方接口参数和返回值都是下划线类型的,所以需要把请求参数和返回值转换为驼峰类型

解决过程

1:使用spring的spring.jackson.property-naming-strategy 配置,
引起的问题,自己的接口和返回值会将驼峰转换为下划线,所以忽略
2:因为这边的feign-api中的参数都是对象,所以新建一个参数的子类加上@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)注解,传参数的时候使用子类,完美解决,但是新建子类返回值下划线/驼峰转换失败

解决方案

为@EnableFeignClients加上encode和decode
@EnableFeignClients(defaultConfiguration = {FeignClientEncoder.class,FeignClientEncoder.FeignClientDecoder.class})

public class FeignClientEncoder extends SpringEncoder {

    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);
            final String s = JSON.toJSONString(object);
            final Object jsonObject = JSON.parse(s);
            convertToCamelCase(jsonObject);
            template.body(JSON.toJSONString(jsonObject));
        } catch (Exception ex) {

        }

        System.out.println();
    }

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

        @Override
        public Object decode(Response response, Type type) throws IOException, FeignException {
            final Response.Body body = response.body();
            final String bodyClassName = body.getClass().getName();
            //Response.ByteArrayBody feign.Response$InputStreamBody feign.Response$ByteArrayBody
            //因为ByteArrayBody是private 所以不能instance of
            if (Objects.equals(bodyClassName, "feign.Response$ByteArrayBody") || Objects.equals(bodyClassName, "feign.Response$InputStreamBody")) {
                String result;
                if (Objects.equals(bodyClassName, "feign.Response$ByteArrayBody")) {
                    result = body.toString();
                } else {
                    byte[] bodyData = Util.toByteArray(body.asInputStream());
                    result = Util.decodeOrDefault(bodyData, UTF_8, "Binary data");
                }
                final Response.Builder respBuild = Response.builder()
                        .headers(response.headers())
                        .reason(response.reason())
                        .status(response.status())
                        .request(response.request());

                if (StringUtils.isNoneBlank(result) && JSONUtil.isJson(result)) {
                    final Object jsonObject = JSON.parse(result);
                    convertToUnderline(jsonObject);
                    respBuild.body(JSON.toJSONString(jsonObject), Charset.defaultCharset());
                } else {
                    respBuild.body(result, Charset.defaultCharset());
                }
                return super.decode(respBuild.build(), type);
            }
            return super.decode(response, type);
        }
    }

    public final static void convertToUnderline(Object json) {
        if (json instanceof JSONArray) {
            JSONArray arr = (JSONArray) json;
            for (Object obj : arr) {
                convertToUnderline(obj);
            }
        } else if (json instanceof JSONObject) {
            JSONObject jo = (JSONObject) json;
            Set<String> keys = jo.keySet();
            String[] array = keys.toArray(new String[keys.size()]);
            for (String key : array) {
                Object value = jo.get(key);
                final String underLineKey = StrUtil.toUnderlineCase(key);
                jo.remove(key);
                jo.put(underLineKey, value);
                convertToUnderline(value);
            }
        }
    }

    public final static void convertToCamelCase(Object json) {
        if (json instanceof JSONArray) {
            JSONArray arr = (JSONArray) json;
            for (Object obj : arr) {
                convertToCamelCase(obj);
            }
        } else if (json instanceof JSONObject) {
            JSONObject jo = (JSONObject) json;
            Set<String> keys = jo.keySet();
            String[] array = keys.toArray(new String[keys.size()]);
            for (String key : array) {
                Object value = jo.get(key);
                final String underLineKey = StrUtil.toCamelCase(key);
                jo.remove(key);
                jo.put(underLineKey, value);
                convertToCamelCase(value);
            }
        }
    }

}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走着路睡觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值