Can you support the post form data of object type?
LIANGQI0811 opened this issue · comments
when I use it for spring boot of post form data.Map is too awkward to use.
I don't want to check that those are the default parameters or parameter names.
Will the object form be better?
For example:
class UserParams implements IParams{
int age;
String name;
UserParams(String name){
//age default is 1
this(name,1);
}
UserParams(String name,int age){
name=name;
age=age;
}
}
//then Realization IParams FormEncoder
Hi,
Thanks a lot for your interesting suggestion, as I understood clearly you would like to write something like:
@RequestLine("POST /form")
@Headers("Content-Type: application/x-www-form-urlencoded")
Response form (MyIParamsPojo pojo);
instead of the way it works now:
@RequestLine("POST /form")
@Headers("Content-Type: application/x-www-form-urlencoded")
Response form (@Param("key1") String key1, @Param("key2") String key2);
Unfortunately, I find it a little bit confusing for Feign and contracts (JAX-RS, Spring, and others, not only Feign-default as in the example above) users, who get used to working in one way - annotation based, don't you?
May this will help you
https://github.com/OpenFeign/feign#dynamic-query-parameters
I re-write SpringFormEncoder
to translate object into a Map
. I know it's a little bit tricky, but it can help us to write a lot of @Param
in our method parameter list. Below is a sample code:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import java.lang.reflect.Type;
import java.util.Map;
import org.springframework.web.multipart.MultipartFile;
public class MyFormEncoder extends SpringFormEncoder {
private final ObjectMapper mapper;
public MyFormEncoder() {
this(new Default(), null);
}
public MyFormEncoder(Encoder delegate) {
this(delegate, null);
}
public MyFormEncoder(Encoder delegate, ObjectMapper mapper) {
super(delegate);
if (mapper == null) {
mapper = new ObjectMapper();
}
this.mapper = mapper;
}
@Override
public void encode(Object object, Type bodyType, RequestTemplate template)
throws EncodeException {
if (!bodyType.equals(MultipartFile.class) && !(object instanceof Map)) {
Map<String, ?> requestBody = mapper.convertValue(object, new TypeReference<Map<String, ?>>() {
});
super.encode(requestBody, MAP_STRING_WILDCARD, template);
} else {
super.encode(object, bodyType, template);
}
}
}
@LIANGQI0811, @sgyyz, @shenliuyang
Guys, I have added this feature. See the README
This and other fixes will be available within the day in new version 3.5.0