本地調用代碼: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); }