cn.ishow.starter.rpc.basic.CustomDecoder Maven / Gradle / Ivy
package cn.ishow.starter.rpc.basic;
import cn.ishow.starter.common.exception.BizRuntimeException;
import cn.ishow.starter.common.util.JsonUtils;
import cn.ishow.starter.rpc.context.RpcContext;
import cn.ishow.starter.rpc.properties.RtDecode;
import com.fasterxml.jackson.databind.JsonNode;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import feign.optionals.OptionalDecoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
/**
* 自定义响应解析器
*
* @author bucheng
* @create 2022/5/15 20:04
*/
public class CustomDecoder implements Decoder {
public static final int HTTP_OK = 200;
public static final int HTTP_RD = 300;
private final Decoder delegate;
private final RpcContext context;
public CustomDecoder(ObjectFactory messageConverters,
RpcContext context) {
this.delegate = new OptionalDecoder(
new ResponseEntityDecoder(new SpringDecoder(messageConverters)));
this.context = context;
}
public CustomDecoder(Decoder decoder, RpcContext context) {
this.delegate = decoder;
this.context = context;
}
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
//判断是否存在自定义解码器
RtDecode decode = context.getRtDecoder();
//不存在直接调用框架解析器
if (decode == null) {
return delegate.decode(response, type);
}
int status = response.status();
//判断http响应码是否在200-300之间
if (status >= HTTP_OK && status < HTTP_RD) {
String result = Util.toString(response.body().asReader(StandardCharsets.UTF_8));
JsonNode jsonNode = JsonUtils.toJsonNode(result);
String codeField = decode.getCodeField();
String msgField = decode.getMessageField();
String dataField = decode.getDataField();
int code = jsonNode.get(codeField).intValue();
String msg = jsonNode.get(msgField).asText();
//如果code和业务成功码不一直抛出异常
if (code != decode.getCode()) {
throw new BizRuntimeException(code, msg);
}
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type rawType = parameterizedType.getRawType();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
return JsonUtils.deserializeGeneric(jsonNode.get(dataField).toString(), (Class>) rawType, actualTypeArguments);
} else {
return JsonUtils.deserialize(jsonNode.get(dataField), (Class>) type);
}
}
//如果响应码不再指定范围抛出解析失败异常
throw new DecodeException(status, "http status " + status + " invalid!", response.request());
}
}