feign.codec.EncodeException: Could not write request: no suitable HttpMessa appears in spring cloud eureka service call

Local call code:

Since the server uses jersay and requires the consumption type to be application_form_urlencoded, that is to say, the content-type is application/x-www-form-urlencoded, which requires parameters to be passed in the form of key=value&key=value. In the above method, feign cannot find a suitable encoder to convert the message class into the required format. Feign provides default support for json, but for the above types, you need to write a custom encoder to achieve it. Feign supports the implementation of custom encoders.

1. Customize the encoder implementation class (using java reflection technology), the main function is to convert the corresponding class parameters into the form of url parameters

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. Register a custom encoder class

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. Modify the local call:

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325720777&siteId=291194637