JSON转换工具类

本文深入探讨了基于Jackson、FastJson及Google Gson三种主流框架的JSON数据转换技巧,涵盖POJO类与JSON串互转、JSON数据解析及键值存储表创建等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON转换工具类

上一期写的是关于时间的处理,这一期玩点有意思的,
第一部分 : 讲解基于jackson的POJO类与Json串互转的具体方法,
第二部分 : 讲解基于FastJson解析Json数据
第三部分 : 讲解基于Google Gson解析Json数据
第四部分 : 讲解基于以上写的工具类创建灵活的可扩展的键值存储表

第一部分 基于jackson的POJO类与Jason串互转

1. jackson简介

2. 引入依赖

添加依赖

jackson依赖

<!--jackson-->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>

其它常用的工具包依赖

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-guava</artifactId>
        <version>2.9.4</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.5</version>
    </dependency>

3. 具体实现代码

package core.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

public class JsonTools {

    private static final Logger log = LoggerFactory.getLogger(JsonTools.class);

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 对象字段全部列入
        objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
        // 取消默认转换timestamps形式
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        // 忽略空bean转json的错误
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

        // 统一日期格式yyyy-MM-dd HH:mm:ss
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        // 忽略在json字符串中存在,但是在java对象中不存在对应属性的情况
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * object转Json字符串
     *
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> String obj2String(T obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("Parse object to String error "+ " obj : " + obj.toString(),e);
            return null;
        }
    }

    /**
     * Object转json字符串并格式化美化
     *
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> String obj2StringPretty(T obj) {
        if (obj == null) {
            return null;
        }
        try {
            return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (Exception e) {
            log.error("Parse object to String error "+ " obj : " + obj.toString(),e);
            return null;
        }
    }

    /**
     * string转object
     *
     * @param str   json字符串
     * @param clazz 被转对象class
     * @param <T>
     * @return
     */
    public static <T> T string2Obj(String str, Class<T> clazz) {
        if (StringUtils.isEmpty(str) || clazz == null) {
            return null;
        }
        try {
            return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
        } catch (IOException e) {
            log.error("Parse object to String error "+ " str : " + str.toString() + " clazz : "+clazz.toString(),e);
            return null;
        }
    }

    /**
     * string转object
     *
     * @param str  json字符串
     * @param typeReference 被转对象引用类型
     * @param <T>
     * @return
     */
    public static <T> T string2ObjRef(String str, TypeReference<T> typeReference) {
        if (StringUtils.isEmpty(str) || typeReference == null) {
            return null;
        }
        try {
            return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
        } catch (IOException e) {
            log.error("Parse String to Object error " + " str : "+str.toString() + " typeReference : "+typeReference.toString() , e );
            return null;
        }
    }

    /**
     * string转collection 用于转为集合对象
     *
     * @param str  json字符串
     * @param collectionClass 被转集合class
     * @param elementClasses  被转集合中对象类型class
     * @param <T>
     * @return
     */
    public static <T> T string2Collection(String str, Class<?> collectionClass, Class<?>... elementClasses) {
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
        try {
            return objectMapper.readValue(str, javaType);
        } catch (IOException e) {
            log.error("Parse String to Collection error" + " str : "+str.toString() +
                    " collectionClass : "+collectionClass.toString() + " elementClasses : "+elementClasses.toString() , e);
            return null;
        }
    }

       /**
     * 将对象以json写入流
     * @param object
     * @param out
     * @throws IOException
     */
    public static void writeJsonToSteam(Object object , OutputStream out) {
        try {
            objectMapper.writeValue( out , object);
        } catch (IOException e) {
            log.error("Parse String to Collection error" + " object: " +object.toString()+ " out: "+out , e);
        }
    }

    /**
     * 流的方式反序列化pojo对象
     * @param input
     * @param cls
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T>T inputSteamToObject (InputStream input , Class<T> cls ) {
        try {
            return objectMapper.readValue( input , cls);
        } catch (IOException e) {
            log.error("Parse String to Collection error" + " object: " +input.toString()+ " out: "+cls , e);
            return null;
        }
    }

    /**
     * 流的方式反序列化集合
     * @param input
     * @param cls
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T>T inputSteamToObject (InputStream input , TypeReference<T> cls ) {
        try {
            return objectMapper.readValue( input , cls);
        } catch (IOException e) {
            log.error("Parse String to Collection error" + " object: " +input.toString()+ " out: "+cls , e);
            return null;
        }
    }

 static class Student {
        //不JSON序列化年龄属性
        @JsonIgnore
        private Integer id;
        @JsonProperty("NickName")
        private String name;
        private String sex;
        private Integer grade;
        //格式化日期属性
        @JsonFormat(pattern = "yyyy-MM-DD HH:mi:ss")
        private Date date;
        private List<String> like;
        private Map<String , Object> data;

        public Student() {
        }

        public Student(Integer id, String name, String sex, Integer grade, Date date) {
            this.id = id;
            this.name = name;
            this.sex = sex;
            this.grade = grade;
            this.date = date;
        }
        ......
}

4. Test测试类

@Test
    public void obj2StringAndString2Obj() {
        Student student = new Student(1001, "xiaoming", "M", 80 ,new Date());
        List<String> list = new ArrayList<>();
        list.add("语文");
        list.add("数学");
        list.add("英语");
        student.setLike( list );
        Map< String , Object> map = new HashMap<>();
        map.put("key1" , "key1");
        map.put("key2" , "key2");
        map.put("keyOfLike" , list);
        student.setData( map );
        System.out.println( "student : " +student);

        String obj2StringPretty= JsonTools.obj2StringPretty(student);
        System.out.println( "obj2StringPretty : " +obj2StringPretty);

        Student string2Obj = JsonTools.string2Obj(obj2StringPretty, Student.class);
        System.out.println(" string2Obj : "+string2Obj);

        Map result = JsonTools.string2Obj(obj2StringPretty, Map.class);
        System.out.println(" result : "+result);
    }


##**执行结果:**
student : Student{id=1001, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 00:41:57 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}
obj2StringPretty : {
  "sex" : "M",
  "grade" : 80,
  "date" : "2018-11-18 00:41:57",
  "like" : [ "语文", "数学", "英语" ],
  "data" : {
    "key1" : "key1",
    "key2" : "key2",
    "keyOfLike" : [ "语文", "数学", "英语" ]
  },
  "NickName" : "xiaoming"
}
 string2Obj : Student{id=null, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 00:41:57 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}
 
 result : {sex=M, grade=80, date=2018-11-18 00:41:57, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}, NickName=xiaoming}

从以上的结果可以看出:
obj2StringPretty 中 name取得是 NickName 注解 @JsonProperty("NickName") 在 POJO转JSON生效
obj2StringPretty 中 date 为 "2018-11-18 00:41:57"  注解 @JsonFormat(pattern = "yyyy-MM-DD HH:mi:ss") 在 POJO转JSON生效
obj2StringPretty 中 没有 id 值 注解 @JsonIgnore 在 POJO转JSON生效
 @Test
    public void string2ObjRef() {
        Student xiaoming = new Student(1001, "xiaoming", "M", 80 ,new Date());
        List<String> list = new ArrayList<>();
        list.add("语文");
        list.add("数学");
        list.add("英语");
        xiaoming.setLike( list );
        Map< String , Object> map = new HashMap<>();
        map.put("key1" , "key1");
        map.put("key2" , "key2");
        map.put("keyOfLike" , list);
        xiaoming.setData( map );

        Student xiaowang = new Student(1002, "xiaowang", "F", 80 ,new Date());
        xiaowang.setData( map );

        List<Student> studentList = new ArrayList<>();
        studentList.add(xiaoming);
        studentList.add(xiaowang);

        System.out.println( "studentList : " +studentList);
        String obj2StringPretty = JsonTools.obj2StringPretty(studentList);
        System.out.println( "obj2StringPretty : " +obj2StringPretty);

        List<Student> string2ObjRef = JsonTools.string2ObjRef(obj2StringPretty, new TypeReference<List<Student>>() { });
        System.out.println("string2ObjRef : " + string2ObjRef.toString());
    }


##**执行结果:**
studentList : [Student{id=1001, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 00:48:17 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}, Student{id=1002, name='xiaowang', sex='F', grade=80, date=Sun Nov 18 00:48:17 CST 2018, like=null, data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}]

obj2StringPretty : [ {
  "sex" : "M",
  "grade" : 80,
  "date" : "2018-11-18 00:48:17",
  "like" : [ "语文", "数学", "英语" ],
  "data" : {
    "key1" : "key1",
    "key2" : "key2",
    "keyOfLike" : [ "语文", "数学", "英语" ]
  },
  "NickName" : "xiaoming"
}, {
  "sex" : "F",
  "grade" : 80,
  "date" : "2018-11-18 00:48:17",
  "data" : {
    "key1" : "key1",
    "key2" : "key2",
    "keyOfLike" : [ "语文", "数学", "英语" ]
  },
  "NickName" : "xiaowang"
} ]

string2ObjRef : [Student{id=null, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 00:48:17 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}, Student{id=null, name='xiaowang', sex='F', grade=80, date=Sun Nov 18 00:48:17 CST 2018, like=null, data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}]


 @Test
    public void string2Collection() {
        Student xiaoming = new Student(1001, "xiaoming", "M", 80 ,new Date());
        List<String> list = new ArrayList<>();
        list.add("语文");
        list.add("数学");
        list.add("英语");
        xiaoming.setLike( list );
        Map< String , Object> map = new HashMap<>();
        map.put("key1" , "key1");
        map.put("key2" , "key2");
        map.put("keyOfLike" , list);
        xiaoming.setData( map );

        Student xiaobai = new Student(1002, "xiaobai", "F", 80 ,new Date());
        xiaobai.setData( map );

        List<Student> studentList = new ArrayList<>();
        studentList.add(xiaoming);
        studentList.add(xiaobai);
        String studentListStr = JsonTools.obj2StringPretty(studentList);
        //List<Student> studentListObj = JsonTools.string2ObjRef(studentListStr, new TypeReference<List<Student>>(){});
        // 依次传入集合以及集合中对象类型的class
        List<Student> studentListObj = JsonTools.string2Collection(studentListStr, List.class, Student.class);
        System.out.println(studentListObj.toString());
    }


##**执行结果:**
studentListObj [Student{id=null, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 00:54:02 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}, Student{id=null, name='xiaobai', sex='F', grade=80, date=Sun Nov 18 00:54:02 CST 2018, like=null, data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}]


5. jackson 处理XML请看 jackson处理XML

第二部分 基于FastJson解析Json数据

1. FastJson简介

fastjson 是一个性能极好的用 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。

主要特点:
快速FAST (比其它任何基于Java的解析器和生成器更快,包括jackson)
强大(支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum)

零依赖(没有依赖其它任何类库除了JDK)

2. 代码实现

还是基于上面的pojo类

 @Test
    public void obj2StringAndString2Obj() {
        Student student = new Student(1001, "xiaoming", "M", 80 ,new Date());
        List<String> list = new ArrayList<>();
        list.add("语文");
        list.add("数学");
        list.add("英语");
        student.setLike( list );
        Map< String , Object> map = new HashMap<>();
        map.put("key1" , "key1");
        map.put("key2" , "key2");
        map.put("keyOfLike" , list);
        student.setData( map );
        System.out.println( "student : " +student);

//        String obj2StringPretty= JsonTools.obj2StringPretty(student);
//        System.out.println( "obj2StringPretty : " +obj2StringPretty);
//
//        Student string2Obj = JsonTools.string2Obj(obj2StringPretty, Student.class);
//        System.out.println(" string2Obj : "+string2Obj);
//		  Map result = JsonTools.string2Obj(obj2StringPretty, Map.class);
//        System.out.println(" result : "+result);

		 String jsonString = JSON.toJSONString(student);
        System.out.println( "jsonString : " +jsonString);
        Student parseObject = JSON.parseObject(jsonString, Student.class);
        System.out.println(" parseObject : "+parseObject);

        Map result = JSON.parseObject(jsonString, Map.class);
        System.out.println(" result : "+result);
    }
    
##**执行结果:**
student : Student{id=1001, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 01:06:26 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=[语文, 数学, 英语]}}

jsonString : {"data":{"key1":"key1","key2":"key2","keyOfLike":["语文","数学","英语"]},"date":1542474386634,"grade":80,"id":1001,"like":["语文","数学","英语"],"name":"xiaoming","sex":"M"}

 parseObject : Student{id=1001, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 01:06:26 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=["语文","数学","英语"]}}
 
 result : {date=1542474386634, data={"key1":"key1","key2":"key2","keyOfLike":["语文","数学","英语"]}, like=["语文","数学","英语"], grade=80, sex=M, name=xiaoming, id=1001}

从FastJson解析Json数据的结果可以看出 , 之前POJO类中加入的所有注解对FastJson解析为JSON的过程中并没有影响
@Test
    public void string2ObjRef() {
        Student xiaoming = new Student(1001, "xiaoming", "M", 80 ,new Date());
        List<String> list = new ArrayList<>();
        list.add("语文");
        list.add("数学");
        list.add("英语");
        xiaoming.setLike( list );
        Map< String , Object> map = new HashMap<>();
        map.put("key1" , "key1");
        map.put("key2" , "key2");
        map.put("keyOfLike" , list);
        xiaoming.setData( map );

        Student xiaowang = new Student(1002, "xiaowang", "F", 80 ,new Date());
        xiaowang.setData( map );

        List<Student> studentList = new ArrayList<>();
        studentList.add(xiaoming);
        studentList.add(xiaowang);

//        System.out.println( "studentList : " +studentList);
//        String obj2StringPretty = JsonTools.obj2StringPretty(studentList);
//        System.out.println( "obj2StringPretty : " +obj2StringPretty);
//        List<Student> string2ObjRef = JsonTools.string2ObjRef(obj2StringPretty, new TypeReference<List<Student>>() { });
//        System.out.println("string2ObjRef : " + string2ObjRef.toString());

        String jsonString = JSON.toJSONString(studentList);
        System.out.println( "jsonString : " +jsonString);
        List<Student> string2ObjRef=JSON.parseArray(jsonString, Student.class);
        System.out.println("string2ObjRef : " + string2ObjRef.toString());
    }
    
##**执行结果:**
jsonString : [{"data":{"key1":"key1","key2":"key2","keyOfLike":["语文","数学","英语"]},"date":1542475554692,"grade":80,"id":1001,"like":["语文","数学","英语"],"name":"xiaoming","sex":"M"},{"data":{"$ref":"$[0].data"},"date":1542475554692,"grade":80,"id":1002,"name":"xiaowang","sex":"F"}]

string2ObjRef : [Student{id=1001, name='xiaoming', sex='M', grade=80, date=Sun Nov 18 01:25:54 CST 2018, like=[语文, 数学, 英语], data={key1=key1, key2=key2, keyOfLike=["语文","数学","英语"]}}, Student{id=1002, name='xiaowang', sex='F', grade=80, date=Sun Nov 18 01:25:54 CST 2018, like=null, data={$ref=$[0].data}}]

3. FastJson还有如下方法,部分上文已有测试案例

1 、生成Json:

JavaBean、List<JavaBean>、List<String>、List<Map<String,Object>>    
String jsonString = JSON.toJSONString(obj);

2、解析Json:

(1)JavaBean

Class class= JSON.parseObject(jsonString, Class.class);

(2)List

List<Class> class=JSON.parseArray((jsonString, Class.class);

(3)List

List<String> listString = JSON.parseArray(jsonString, String.class);

(4)List<Map<String,Object>>

List<Map<String, Object>> listMap = JSON.parseObject(jsonString, new TypeReference<List<Map<String,Object>>>(){});

3 .获取json中指定数据:

现有这样的json数据:

{"totalRecords":2615,
"result":{"code":"200","status":"success"},
"list":[{"unuAbnId":"0bcd930f-014c-1000-e003-5f160a0d0114",
"entNo":"1c2e4ca8-00fa-1000-e000-74590a76bf0f",
"regNO":"442000600169663",
"entName":"x",
"entType":"9910  ",
"speCause":"3",
"abnTime":"Mar 13, 2015 12:00:00 AM",
"decOrg":"442020",
"entNameUrl":"<a href=\".. ",
"auditingFileNo":"15000684990326",
"abnormalID":"fd74013d-014b-1000-e00a-72970a0d0114"},{...},{...},...],
"pageNo":1,
"pageSize":8,
"url":"main/abnInfoPage",
"selList":[{"unuAbnId":"0bcd930f-014c-1000-e003-5f0f0a0d0114",
"entNo":"16da9629-0131-1000-e005-3effc0a803a8",
"regNO":"442000602187424",
"entName":"x",
"entType":"9910  ",
"speCause":"3",
"abnTime":"Mar 13, 2015 12:00:00 AM",
"decOrg":"442020",
"entNameUrl":"<a href=\"..\">",
"auditingFileNo":"15000684990319",
"abnormalID":"fd74013d-014b-1000-e00a-72970a0d0114"},{...},{...},...],
"topPageNo":1,
"totalPages":327,
"previousPageNo":0,
"nextPageNo":2,
"bottomPageNo":327
}

其中list含有2615条数据,selList含有8条数据,目标是提取selList中entNameUrl的链接(不含a href=)

外层是JSONObject,里面的list和selList是JSONArrary,再里面是JSONObject。其中的result也是JSONObject

JSONObject jsonObj = JSON.parseObject(rawText);
JSONArray result = jsonObj.getJSONArray("selList");
List<Link> links= JSON.parseArray(result.toJSONString(),Link.class);

其中Link类中要有entNameUrl这个属性,并且setter和getter方法。
在setter方法中可以进一步进行处理

 public void setEntNameUrl(String entNameUrl) {
     this.entNameUrl =Html.create(entNameUrl).links().get();
}

这里使用了自定方法,其功能就是取出字符串中的链接。

Link类中可以包含abnTime、entName、regNO等属性和对应的getter和setter方法,FastJson能自动映射。

通过下面的方法也可以处理:

JSONObject jsonObj = new JSONObject(rawText);
JSONArray jsonArray = result .getJSONArray("selList");
for (int i = 0; i < jsonArray.length; i++) {

 }

此处转载自 : https://blog.youkuaiyun.com/G1Apassz/article/details/44456293

4. FastJson使用的扩展

java中,通过FastJson对海量数据的Json文件,边读取边解析
fastjson(七)处理超大对象和超大JSON文本

第三部分 基于Google Gson解析Json数据

1. Google Gson简介

Gson类:解析json的最基础的工具类
JsonParser类:解析器来解析JSON到JsonElements的解析树
JsonElement类:一个类代表的JSON元素
JsonObject类:JSON对象类型
JsonArray类:JsonObject数组
TypeToken类:用于创建type,比如泛型List<?>

maven 依赖:

<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.7</version>
</dependency>

具体测试用例看链接:
Google Gson的使用方法及JSON 技术对比

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值