All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.ishow.starter.rpc.basic.CustomDecoder Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
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());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy