您的位置:首页 > 理论基础 > 计算机网络

spring cloud eureka服务调用出现feign.codec.EncodeException: Could not write request: no suitable HttpMessa

2018-04-04 00:00 1776 查看
摘要: 服务注册与发现使用:eureka,feign;
服务提供方是用spring boot + jersay 构建的微服务架构,服务方法消费类型为@Consumes(MediaType.APPLICATION_FORM_URLENCODED)。参数接收使用@BeanParam 注解的javabean.
调用方:spring boot+jersay

本地调用代码:



由于服务方使用jersay并且要求消费类型为application_form_urlencoded,也就是说content-type为application/x-www-form-urlencoded类型,这种类型要求参数以key=value&key=value的方式传递。以上方式feign找不到相就的encoder来将message类转为要求的格式。feign对json是提供默认支持的,但对于以上类型则需要写一个自定义的encoder来实现。feign支持自定义encoder的实现。

1、自定义encoder实现类(采用java反射技术),主要作用是将对应的类参数转为url参数形式

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());
}
}

2、注册自定义的encoder类

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();
}
}

3、修改本地调用:<
7fe0
/p>
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐