【原】基于Feign 重写自定义编码器

背景:

    内部有个spring cloud 项目需要调用公司php小组的接口,但是php提供的接口入参大部分是下划线命名,而Java这边是会按照驼峰编写,如果使用Fegin调用会导致php无法接收参数,所以针对这个问题进行了如下处理,主要是通过重写fegin的默认编码器实现

 

原理

Spring Cloud Feign 的编码器、解码器和客户端都是支持自定义扩展,可以对请求以及结果和发起请求的过程进行自定义实现,Feign 默认encoder实现是SpringEncoder,默认decocer实现是ResponseEntityDecoder,另外还有一些其它的编解码器。

Encoder/ Decoder 实现 说明
JacksonEncoder,JacksonDecoder 基于 Jackson 格式的持久化转换协议
GsonEncoder,GsonDecoder 基于Google GSON 格式的持久化转换协议
SaxEncoder,SaxDecoder 基于XML 格式的Sax 库持久化转换协议
JAXBEncoder,JAXBDecoder 基于XML 格式的JAXB 库持久化转换协议
ResponseEntityEncoder,ResponseEntityDecoder Spring MVC 基于 ResponseEntity< T > 返回格式的转换协议
SpringEncoder,SpringDecoder 基于Spring MVC HttpMessageConverters 一套机制实现的转换协议 ,应用于Spring Cloud 体系中

 

实现方案

**
 * 由于下游接口php是下划线命名,java是驼峰,通过fegin调用会导致下游php接收不到,所以需要针对这种问题特殊处理
 */
public class FeignClientEncoder extends SpringEncoder {

    public static final char UNDERLINE = '_';

    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);
            if(ObjectUtils.isNotEmpty(AnnotationUtils.getAnnotation(object.getClass(), FeginCamelCase.class))){
                final String s = JSON.toJSONString(object);
                final Object jsonObject = JSON.parse(s);
                Class clazz = Class.forName(bodyType.getTypeName());
                convertToCamelCase(jsonObject,clazz);
                template.body(JSON.toJSONString(jsonObject));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public final static void convertToCamelCase(Object json,Class clazz) throws NoSuchFieldException {
        if (json instanceof JSONArray) {
            JSONArray arr = (JSONArray) json;
            for (Object obj : arr) {
                convertToCamelCase(obj,clazz);
            }
        } 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) {
                Field field = clazz.getField(key);
          //由于有些字段因为特殊原因,不想处理成下划线形式,这时候就可以通过注解的方式进行标记不进行处理 if(ObjectUtils.isEmpty(AnnotationUtils.getAnnotation(field,IgnoreFeginCamelCase.class))){ Object value = jo.get(key); final String underLineKey = camelToUnderline(key,1); jo.remove(key); jo.put(underLineKey, value); convertToCamelCase(value,clazz); } } } } //驼峰转下划线 public static String camelToUnderline(String param, Integer charType) { if (param == null || "".equals(param.trim())) { return ""; } int len = param.length(); StringBuilder sb = new StringBuilder(len); for (int i = 0; i < len; i++) { char c = param.charAt(i); if (Character.isUpperCase(c)) { sb.append(UNDERLINE); } if (charType == 2) { sb.append(Character.toUpperCase(c)); //统一都转大写 } else { sb.append(Character.toLowerCase(c)); //统一都转小写 } } return sb.toString(); }

 启动类指定编码器

@EnableFeignClients(defaultConfiguration = FeignClientEncoder.class)

 

上一篇:解决win10下git闪退


下一篇:Lua中的weak表——weak table(转)