spring cloud eureka服務調用出現feign.codec.EncodeException: Could not write request: no suitable HttpMessa

本地調用代碼:java

因爲服務方使用jersay而且要求消費類型爲application_form_urlencoded,也就是說content-type爲application/x-www-form-urlencoded類型,這種類型要求參數以key=value&key=value的方式傳遞。以上方式feign找不到相就的encoder來將message類轉爲要求的格式。feign對json是提供默認支持的,但對於以上類型則須要寫一個自定義的encoder來實現。feign支持自定義encoder的實現。web

一、自定義encoder實現類(採用java反射技術),主要做用是將對應的類參數轉爲url參數形式spring

import com.alibaba.fastjson.JSONObject;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.net.URLEncoder;

public class FormEncoder implements Encoder {
    @Override
    public void encode(Object o, Type type, RequestTemplate rt) throws EncodeException {
        StringBuffer sb = new StringBuffer();
        try {
            Class clazz = Thread.currentThread().getContextClassLoader().loadClass(type.getTypeName());
            Field[] fields =clazz.getDeclaredFields();
            String oStr = JSONObject.toJSONString(o);
            //JSONObject.parseObject(oStr,clazz);
            for(Field field : fields){
                if(sb.length() > 0){
                    sb.append("&");
                }
                field.setAccessible(true);
                Object fieldValue = field.get(JSONObject.parseObject(oStr,clazz));
                if(fieldValue != null){
                    sb.append(URLEncoder.encode(field.getName(),"UTF-8"))
                            .append("=")
                            .append(URLEncoder.encode(field.get(JSONObject.parseObject(oStr,clazz)).toString()));
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        rt.header("Content-Type", "application/x-www-form-urlencoded");
        rt.body(sb.toString());
    }
}

二、註冊自定義的encoder類json

import feign.codec.Encoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignSimpleEncoderConfig {
    @Bean
    public Encoder encoder(){
        return new FormEncoder();
    }
}

三、修改本地調用:app

import com.alibaba.fastjson.JSONObject;
import com.makeronly.common.bean.Message;
import com.makeronly.common.bean.ResultBean;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@FeignClient(name = "MSGCEN-SVR", configuration = FeignSimpleEncoderConfig.class)
public interface IMsgCen {

    @RequestMapping(value = "/msgcen/msg/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED)
    String sendMsg(Message message);
}
相關文章
相關標籤/搜索