JSON 泛型序列化方法 与 LinkedHashMap转成对象

1、说明

 
本文均基于 com.alibaba.fastjson.jar 包,所以首先引入jar
 

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.68</version>
		</dependency>

1、JSON 泛型序列化方法

 
       **public static <T> T parseObject(String text, TypeReference<T> type, Feature... features)**

       该方法可以把String parse为自己定义的实体类,前面返回值是泛型,也可以是其他jar包的数据类型,只要在后面指明它的类型就好了。
 

2.1 JSON 源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.alibaba.fastjson;

import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONScanner;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider;
import com.alibaba.fastjson.parser.deserializer.FieldTypeResolver;
import com.alibaba.fastjson.parser.deserializer.ParseProcess;
import com.alibaba.fastjson.serializer.JSONSerializable;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.JavaBeanSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.IOUtils;
import com.alibaba.fastjson.util.TypeUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

public abstract class JSON implements JSONStreamAware, JSONAware {
    
    
    public static TimeZone defaultTimeZone = TimeZone.getDefault();
    public static Locale defaultLocale = Locale.getDefault();
    public static String DEFAULT_TYPE_KEY = "@type";
    static final SerializeFilter[] emptyFilters = new SerializeFilter[0];
    public static String DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static int DEFAULT_PARSER_FEATURE;
    public static int DEFAULT_GENERATE_FEATURE;
    private static final ConcurrentHashMap<Type, Type> mixInsMapper = new ConcurrentHashMap(16);
    private static final ThreadLocal<byte[]> bytesLocal;
    private static final ThreadLocal<char[]> charsLocal;
    public static final String VERSION = "1.2.68";

    public JSON() {
    
    
    }
    
    // 省略代码 ……
    
    /**
     * <pre>
     * String jsonStr = "[{\"id\":1001,\"name\":\"Jobs\"}]";
     * List&lt;Model&gt; models = JSON.parseObject(jsonStr, new TypeReference&lt;List&lt;Model&gt;&gt;() {});
     * </pre>
     * @param text json string
     * @param type type refernce
     * @param features
     * @return
     */
    public static <T> T parseObject(String text, TypeReference<T> type, Feature... features) {
    
    
        return parseObject(text, type.type, ParserConfig.global, DEFAULT_PARSER_FEATURE, features);
    }


    public static <T> T parseObject(String input, Type clazz, ParserConfig config, int featureValues,
                                          Feature... features) {
    
    
        return parseObject(input, clazz, config, null, featureValues, features);
    }


    @SuppressWarnings("unchecked")
    public static <T> T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor,
                                          int featureValues, Feature... features) {
    
    
        if (input == null || input.isEmpty()) {
    
    
            return null;
        }

        if (features != null) {
    
    
            for (Feature feature : features) {
    
    
                featureValues |= feature.mask;
            }
        }

        DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);

        if (processor != null) {
    
    
            if (processor instanceof ExtraTypeProvider) {
    
    
                parser.getExtraTypeProviders().add((ExtraTypeProvider) processor);
            }

            if (processor instanceof ExtraProcessor) {
    
    
                parser.getExtraProcessors().add((ExtraProcessor) processor);
            }

            if (processor instanceof FieldTypeResolver) {
    
    
                parser.setFieldTypeResolver((FieldTypeResolver) processor);
            }
        }

        T value = (T) parser.parseObject(clazz, null);

        parser.handleResovleTask(value);

        parser.close();

        return (T) value;
    }
   // 省略代码 ……
}

2.2 示例

package com.icao.json;

import java.io.Serializable;

/**
 * @ClassName: Person
 * @Description:
 * @author:
 * @Date:2020/6/3 17:32
 **/
public class Person implements Serializable {
    
    

    private Integer id;

    private String name;

    private String addr;

    private Integer[] child;

    public Integer[] getChild() {
    
    
        return child;
    }

    public Integer getId() {
    
    
        return id;
    }

    public String getName() {
    
    
        return name;
    }

    public String getAddr() {
    
    
        return addr;
    }

    public void setChild(Integer[] child) {
    
    
        this.child = child;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public void setAddr(String addr) {
    
    
        this.addr = addr;
    }
}

package com.icao.json;

/**
 * @ClassName: PageResponse
 * @Description:
 * @author:
 * @Date:2020/6/3 17:34
 **/
public class PageResponse<T> {
    
    

    private Integer pageSize;

    private Integer pageNo;

    private Integer count;

    private T result;

    public void setPageSize(Integer pageSize) {
    
    
        this.pageSize = pageSize;
    }

    public void setPageNo(Integer pageNo) {
    
    
        this.pageNo = pageNo;
    }

    public void setCount(Integer count) {
    
    
        this.count = count;
    }

    public void setResult(T result) {
    
    
        this.result = result;
    }

    public Integer getPageSize() {
    
    
        return pageSize;
    }

    public Integer getPageNo() {
    
    
        return pageNo;
    }

    public Integer getCount() {
    
    
        return count;
    }

    public T getResult() {
    
    
        return result;
    }
}

package com.icao.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

import java.util.List;

/**
 * @ClassName: JsonTest
 * @Description:
 * @author:
 * @Date:2020/6/3 17:32
 **/
public class JsonTest {
    
    

    public static void main(String[] args) {
    
    


        String result = "{\"result\":[{\\\"id\\\":1,,\\\"name\\\":\\\"程成\\\",\\\"addr\\\":\\\"湖北省武汉市\\\",\\\"child\\\":[12,13]},{\\\"id\\\":2,,\\\"name\\\":\\\"武威\\\",\\\"addr\\\":\\\"湖北省宜昌市\\\",\\\"child\\\":[17,18]}],\"count\":2,\"pageSize\":50,\"pageNo\":1}";
        // JSON.parseObject 对json 字符串要求很严格,需要反转义。
        result = result.replace("\\\"","\"");
        PageResponse<List<Person>> pageResponse = JSON.parseObject(result, new TypeReference<PageResponse<List<Person>>>() {
    
    });
        System.out.println("pageResponse = "+JSON.toJSONString(pageResponse));

    }

}

 
运行结果:

在这里插入图片描述

Connected to the target VM, address: '127.0.0.1:51893', transport: 'socket'
pageResponse = {
    
    "count":2,"pageNo":1,"pageSize":50,"result":[{
    
    "addr":"湖北省武汉市","child":[12,13],"id":1,"name":"程成"},{
    
    "addr":"湖北省宜昌市","child":[17,18],"id":2,"name":"武威"}]}
Disconnected from the target VM, address: '127.0.0.1:51893', transport: 'socket'

Process finished with exit code 0

2.3 忽略反转义报错

package com.icao.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.util.List;

/**
 * @ClassName: JsonTest
 * @Description:
 * @author: 
 * @Date:2020/6/3 17:32
 **/
public class JsonTest {
    
    

    public static void main(String[] args) {
    
    

        String result = "{\"result\":[{\\\"id\\\":1,,\\\"name\\\":\\\"程成\\\",\\\"addr\\\":\\\"湖北省武汉市\\\",\\\"child\\\":[12,13]},{\\\"id\\\":2,,\\\"name\\\":\\\"武威\\\",\\\"addr\\\":\\\"湖北省宜昌市\\\",\\\"child\\\":[17,18]}],\"count\":2,\"pageSize\":50,\"pageNo\":1}";
        // JSON.parseObject 对json 字符串要求很严格,需要分转义。
        //result = result.replace("\\\"","\"");
        PageResponse<List<Person>> pageResponse = JSON.parseObject(result, new TypeReference<PageResponse<List<Person>>>() {
    
    });
        System.out.println("pageResponse = "+JSON.toJSONString(pageResponse));

    }

}

运行结果:

Exception in thread "main" com.alibaba.fastjson.JSONException: illegal identifier : \pos 12, line 1, column 13{
    
    "result":[{
    
    \"id\":1,,\"name\":\"程成\",\"addr\":\"湖北省武汉市\",\"child\":[12,13]},{\"id\":2,,\"name\":\"武威\",\"addr\":\"湖北省宜昌市\",\"child\":[17,18]}],"count":2,"pageSize":50,"pageNo":1}
	at com.alibaba.fastjson.parser.JSONLexerBase.scanSymbolUnQuoted(JSONLexerBase.java:831)
	at com.alibaba.fastjson.parser.JSONLexerBase.scanSymbol(JSONLexerBase.java:632)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:706)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:1573)
	at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_Person.deserialze(Unknown Source)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:284)
	at com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer.parseArray(ArrayListTypeFieldDeserializer.java:181)
	at com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer.parseField(ArrayListTypeFieldDeserializer.java:69)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:838)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:288)
	at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:686)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:396)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:364)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:278)
	at com.icao.json.JsonTest.main(JsonTest.java:22)

Process finished with exit code 1

3、LinkedHashMap 转成对象 convertValue() 方法

 
       Java中使用Jackson反序列时,部分场景下会转成LinkedHashMap,此时需要将LinkedHashMap转成对象(将任何Object类型转成实体)

       一般来讲Jackson已经满足了大部分的序列化和反序列化工作,但是对于复杂的泛型实体估计未必能如愿的正常反序列,而此时对于一些泛型里面的实体对象就会反序列化成LinkedHashMap类型的。

同样,这个类型不能直接强制转换成想要的实体,此时要解决此类问题的思路如下两种:

  • 1、继续将这个LinkedHashMap进行序列化程JSON,然后再反序列化,这样效率较低。
  • 2、使用com.fasterxml.jackson.databind.ObjectMapper 类的 convertValue 方法将这个LinkedHashMap以Object类型转成想要的实体。


ObjectMapper objectMapper = new ObjectMapper();

Person person = objectMapper.convertValue(singleObject, Person.class);
// or:
List<Person> persons = 
    objectMapper.convertValue(listOfObjects, new TypeReference<List<Person>>() {
    
    });
    

以及
在这里插入图片描述
在这里插入图片描述
 
 
 
 
 
 
 
 
 
.

猜你喜欢

转载自blog.csdn.net/weixin_41922349/article/details/106531400