ResponseEntityDecoder.java
package cn.home1.oss.lib.test;
import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via composition.
*
* @author chadjaros
*/
public class ResponseEntityDecoder implements Decoder {
private final Decoder decoder;
public ResponseEntityDecoder(final Decoder decoder) {
this.decoder = decoder;
}
@Override
public Object decode(final Response response, final Type type) throws IOException, FeignException {
final Object ret;
if (isParameterizeHttpEntity(type)) {
final Type type_ = ((ParameterizedType) type).getActualTypeArguments()[0];
final Object decodedObject = decoder.decode(response, type_);
ret = createResponse(decodedObject, response);
} else if (isHttpEntity(type)) {
ret = createResponse(null, response);
} else {
ret = decoder.decode(response, type);
}
return ret;
}
private boolean isParameterizeHttpEntity(final Type type) {
boolean ret = false;
if (type instanceof ParameterizedType) {
ret = isHttpEntity(((ParameterizedType) type).getRawType());
}
return ret;
}
@SuppressWarnings("rawtypes")
private boolean isHttpEntity(final Type type) {
boolean ret = false;
if (type instanceof Class) {
final Class c = (Class) type;
ret = HttpEntity.class.isAssignableFrom(c);
}
return ret;
}
@SuppressWarnings({"unchecked"})
private <T> ResponseEntity<T> createResponse(final Object instance, final Response response) {
final MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
for (final String key : response.headers().keySet()) {
headers.put(key, createLintedList(response.headers().get(key)));
}
return new ResponseEntity<>((T) instance, headers, HttpStatus.valueOf(response.status()));
}
<T> List<T> createLintedList(final Collection<T> type) {
return new LinkedList<>(type);
}
}