Jackson 数据类型转换(使用JavaType)

参考:
https://www.cnblogs.com/whyblogs/p/15062486.html

Jackson,我感觉是在Java与Json之间相互转换的最快速的框架,当然Google的Gson也很不错,但是参照网上有人的性能测试,看起来还是Jackson比较快一点

Jackson处理一般的JavaBean和Json之间的转换只要使用ObjectMapper 对象的readValue和writeValueAsString两个方法就能实现。但是如果要转换复杂类型Collection如 List,那么就需要先反序列化复杂类型 为泛型的Collection Type。

例子1

如果是HashMap<String,YourBean>那么 ObjectMapper 的

getTypeFactory().constructParametricType(HashMap.class,String.class, YourBean.class);

public final ObjectMapper mapper = new ObjectMapper();

    public static void main(String[] args) throws Exception{
        JavaType javaType = getCollectionType(ArrayList.class, YourBean.class);
        List<YourBean> lst =  (List<YourBean>)mapper.readValue(jsonString, javaType);
    }
       /**
        * 获取泛型的Collection Type
        * @param collectionClass 泛型的Collection
        * @param elementClasses 元素类
        * @return JavaType Java类型
        * @since 1.0
        */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

例子2

要转换的实体类

package cn.org.emcs.common.vo;

import cn.org.emcs.common.gogoenum.ResultCodeEnum;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Res<T> {
    private Integer code;
    private String msg;
    private T data;

    public Res(){}



    public Res(ResultCodeEnum resultCode, T data) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMsg();
        this.data = data;
    }

    public Res(Integer code,String msg, T data){
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Res(Integer code, T data,String msg) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> Res<T> success() {
        Res<T> res = new Res<>();
        res.setResultCode(ResultCodeEnum.SUCCESS);
        return res;
    }

    public static <T> Res<T> success(T data) {
        Res<T> res = new Res<>();
        res.setResultCode(ResultCodeEnum.SUCCESS);
        res.setData(data);
        return res;
    }

    public static <T> Res<T> success(Integer code,String msg){
        Res<T> res = new Res<>();
        res.setCode(code);
        res.setMsg(msg);
        return res;
    }

    public static <T> Res<T> fail() {
        Res<T> res = new Res<>();
        res.setResultCode(ResultCodeEnum.FAIL);
        return res;
    }

    public static <T> Res<T> fail(ResultCodeEnum resultCode) {
        Res<T> res = new Res<>();
        res.setResultCode(resultCode);
        return res;
    }

    public static <T> Res<T> fail(Integer code,String msg){
        Res<T> res = new Res<>();
        res.setCode(code);
        res.setMsg(msg);
        return res;
    }

    public static <T> Res<T> fail(ResultCodeEnum resultCode, T data) {
        Res<T> res = new Res<>();
        res.setResultCode(resultCode);
        res.setData(data);
        return res;
    }

    public static <T> Res<T> fail(T data) {
        Res<T> res = new Res<>();
        res.setResultCode(ResultCodeEnum.FAIL);
        res.setData(data);
        return res;
    }

    public void setResultCode(ResultCodeEnum resultCode) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMsg();
    }
}

自定义feign的解码

package cn.org.emcs.common.config.feign.decoder;

import cn.org.emcs.common.utils.JsonUtil;
import cn.org.emcs.common.vo.Res;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

@Slf4j
public class FeignResDecoder implements Decoder {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许出现特殊字符和转义符
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
        // 允许出现单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    }


    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {
        if (response.body() == null) {
            throw new DecodeException(response.status(), "没有返回有效的数据", response.request());
        }
        String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));



        //第一种情况,如果为Response
        if (type instanceof cn.org.emcs.common.vo.Response || Map.class.equals(type)){
            return JsonUtil.json2obj(bodyStr,type);
        }

        //第二种情况,如果有类型,如Res<UserInfo>,或者List<Permission>
        if (type instanceof ParameterizedType) {
            Type rawType = ((ParameterizedType) type).getRawType();
            //如果为如Res<UserInfo>
            if (Res.class.equals(rawType)) {
                return JsonUtil.json2obj(bodyStr, type);
                //或者List<Permission>
            }
            Res res = JsonUtil.json2obj(bodyStr, Res.class);
            return JsonUtil.json2obj(objectMapper.writeValueAsString(res.getData()), type);

        } else {
            //另一种情况
            //如下可以,但是不完美,Result<T>类可能是Res<T>类,也可能是Response<T>
            Res res = JsonUtil.json2obj(bodyStr, Res.class);
            return JsonUtil.json2obj(objectMapper.writeValueAsString(res.getData()), type);
        }
    }

}
public static <T> T json2obj(String jsonStr, Type targetType) {
        try {
            JavaType javaType = TypeFactory.defaultInstance().constructType(targetType);
            return objectMapper.readValue(jsonStr, javaType);
        } catch (IOException e) {
            throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值