Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >用好Jackson,操作Json节省一半时间

用好Jackson,操作Json节省一半时间

作者头像
Java识堂
发布于 2019-05-22 15:00:23
发布于 2019-05-22 15:00:23
1.1K01
代码可运行
举报
文章被收录于专栏:Java识堂Java识堂
运行总次数:1
代码可运行

前言

目前解析Json的工具包有,Gson,FastJson,Jackson,Json-lib。综合来看,Jackson的性能较优,稳定性也比较高,而且spring-boot-starter-web默认会引入Jackson包。因此介绍一下Jackson的使用。

Jackson目前有2个版本 1.x版本包名为org.codehaus.jackson 2.x版本包名为com.fasterxml.jackson

使用

在pom中加入如下依赖即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.2</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.2</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.2</version>
</dependency>

前文说过,当使用spring-boot-starter-web模块时,会默认引入Jackson包,不必在pom中再次引入上面依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

序列化

java对象序列化成json,@Data注解是用lombok插件来自动生成get和set方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Student {

    /** 名字 */
    private String name;
    /** 年龄 */
    private Integer age;
    /** 头像 */
    private String profileImageUrl;
}

将常用的方法封装成一个常用的工具类,如下所示,有2个好处

  1. ObjectMapper 类只会生成一个,节省空间
  2. 可以定义统一的配置(后面细说)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Slf4j
public class JsonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();

    /** 将对象转为string */
    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.warn("Parse Object to String error",e);
            return null;
        }
    }

}

先简单介绍一下封装的工具类

1. 将对象转为json

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.warn("Parse Object to String error",e);
        return null;
    }
}

各种类型均可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void obj2String() throws Exception {

    Student student = new Student();
    student.setAge(10);
    student.setName("name");
    student.setProfileImageUrl("link");
    String result = JsonUtil.obj2String(student);
    // {"name":"name","age":10,"profileImageUrl":"link"}
    System.out.println(result);

    Map<String, List<Integer>> map = new HashMap<>();
    map.put("a", Arrays.asList(1, 2, 3));
    map.put("b", Arrays.asList(1, 2, 3));
    String result1 = JsonUtil.obj2String(map);
    // {"a":[1,2,3],"b":[1,2,3]}
    System.out.println(result1);
}

2. 将对象转为json,并格式化的输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.warn("Parse Object to String error",e);
        return null;
    }
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void obj2StringPretty() throws Exception {
    Student student = new Student();
    student.setAge(10);
    student.setName("name");
    student.setProfileImageUrl("link");
    String result = JsonUtil.obj2StringPretty(student);

    /*
    {
        "name" : "name",
        "age" : 10,
        "profileImageUrl" : "link"
    }
    */
    System.out.println(result);

    Map<String, List<Integer>> map = new HashMap<>();
    map.put("a", Arrays.asList(1, 2, 3));
    map.put("b", Arrays.asList(1, 2, 3));
    String result1 = JsonUtil.obj2StringPretty(map);

    /*
    {
        "a" : [ 1, 2, 3 ],
        "b" : [ 1, 2, 3 ]
    }
    */
    System.out.println(result1);
}

反序列化

将json转为java对象

方式1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 (Exception e) {
        log.warn("Parse String to Object error",e);
        return null;
    }
}

基本类型的转换

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void string2Obj() throws Exception {
    String str = "{\"name\":\"name\",\"age\":10,\"profileImageUrl\":\"link\"}";
    Student student = JsonUtil.string2Obj(str, Student.class);
    // Student(name=name, age=10, profileImageUrl=link)
    System.out.println(student);
}

各种复杂类型的转换,示例1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void string2Obj1() throws Exception {

    Student student1 = new Student();
    student1.setAge(10);
    student1.setName("name1");
    student1.setProfileImageUrl("link1");

    Student student2 = new Student();
    student2.setAge(20);
    student2.setName("name2");
    student2.setProfileImageUrl("link2");

    List<Student> studentList = new ArrayList<>();
    studentList.add(student1);
    studentList.add(student2);
    String result = JsonUtil.obj2String(studentList);
    // [{"name":"name1","age":10,"profileImageUrl":"link1"},{"name":"name2","age":20,"profileImageUrl":"link2"}]
    System.out.println(result);

    List<Student> finalList = JsonUtil.string2Obj(result, List.class);
    // [{name=name1, age=10, profileImageUrl=link1}, {name=name2, age=20, profileImageUrl=link2}]
    System.out.println(finalList);
}

复杂类型的转换,示例2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void string2Obj2() throws Exception {

    Map<String, List<Integer>> testMap = new HashMap<>();
    testMap.put("1", Arrays.asList(1, 2, 3));
    testMap.put("2", Arrays.asList(2, 3, 4));

    String result = JsonUtil.obj2String(testMap);
    // {"1":[1,2,3],"2":[2,3,4]}
    System.out.println(result);

    Map<String, List<Integer>> finalMap = JsonUtil.string2Obj(result, Map.class);
    // {1=[1, 2, 3], 2=[2, 3, 4]}
    System.out.println(finalMap);
}

到现在为止,你可以用这3个函数进行序列化和反序列化操作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/** 将对象转为json */
public static <T> String obj2String(T obj) 

/** 将对象转为json,并格式化显示 */
public static <T> String obj2StringPretty(T obj)

/** 将json转为对象 */
public static <T> T string2Obj(String str, Class<T> clazz)

可能你还看过其他类型的解析方式,如下所示,但是没有必要,上面3个函数完全能满足你的需求,我这里演示一下

方式2

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static <T> T string2Obj(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 (Exception e) {
        log.warn("Parse String to Object error",e);
        return null;
    }
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void string2Obj3() throws Exception {

    Student student1 = new Student();
    student1.setAge(10);
    student1.setName("name1");
    student1.setProfileImageUrl("link1");

    Student student2 = new Student();
    student2.setAge(20);
    student2.setName("name2");
    student2.setProfileImageUrl("link2");

    List<Student> studentList = new ArrayList<>();
    studentList.add(student1);
    studentList.add(student2);
    String result = JsonUtil.obj2String(studentList);
    // [{"name":"name1","age":10,"profileImageUrl":"link1"},{"name":"name2","age":20,"profileImageUrl":"link2"}]
    System.out.println(result);

    List<Student> finalList = JsonUtil.string2Obj(result, new TypeReference<List<Student>>() {});
    // [{name=name1, age=10, profileImageUrl=link1}, {name=name2, age=20, profileImageUrl=link2}]
    System.out.println(finalList);
}

方式3

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static <T> T string2Obj(String str, Class<?> collectionClass, Class<?>... elementClasses){
    JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
    try {
        return objectMapper.readValue(str,javaType);
    } catch (Exception e) {
        log.warn("Parse String to Object error",e);
        return null;
    }
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void string2Obj4() throws Exception {

    Student student1 = new Student();
    student1.setAge(10);
    student1.setName("name1");
    student1.setProfileImageUrl("link1");

    Student student2 = new Student();
    student2.setAge(20);
    student2.setName("name2");
    student2.setProfileImageUrl("link2");

    List<Student> studentList = new ArrayList<>();
    studentList.add(student1);
    studentList.add(student2);
    String result = JsonUtil.obj2String(studentList);
    // [{"name":"name1","age":10,"profileImageUrl":"link1"},{"name":"name2","age":20,"profileImageUrl":"link2"}]
    System.out.println(result);

    List<Student> finalList = JsonUtil.string2Obj(result, List.class, Student.class);
    // [{name=name1, age=10, profileImageUrl=link1}, {name=name2, age=20, profileImageUrl=link2}]
    System.out.println(finalList);
}

常用注解及配置

@JsonIgnore忽略属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Student {

    /** 名字 */
    private String name;
    /** 年龄 */
    private Integer age;
    /** 头像 */
    @JsonIgnore
    private String profileImageUrl;
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void jsonIgnore() throws Exception {
    Student student = new Student();
    student.setAge(10);
    student.setName("name");
    student.setProfileImageUrl("link");
    String result = JsonUtil.obj2String(student);
    // {"name":"name","age":10}
    System.out.println(result);

    String str = "{\"name\":\"name\",\"age\":10,\"profileImageUrl\":\"link\"}";
    Student student1 = JsonUtil.string2Obj(str, Student.class);
    // Student(name=name, age=10, profileImageUrl=null)
    System.out.println(student1);
}

@JsonProperty

当Json的属性值和Java的属性值不一样时,会映射失败,用这个注解指定映射关系,在属性上用这个注解,则序列化和反序列化都会用这个值。如果序列化和反序列化的属性不一致,可以在get方法或者set方法上用这个注解,set方法影响反序列化,get方法影响序列化。

去掉@Data注解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Student {

    /** 名字 */
    private String name;
    /** 年龄 */
    private Integer age;
    /** 头像 */
    private String profileImageUrl;

    @JsonProperty("getImage")
    public String getProfileImageUrl() {
        return profileImageUrl;
    }

    @JsonProperty("setImage")
    public void setProfileImageUrl(String profileImageUrl) {
        this.profileImageUrl = profileImageUrl;
    }

}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void jsonProperty() throws Exception {

    String str = "{\"name\":\"name\",\"age\":10,\"setImage\":\"link\"}";
    Student student1 = JsonUtil.string2Obj(str, Student.class);
    // name
    System.out.println(student1.getName());
    // 10
    System.out.println(student1.getAge());
    // link
    System.out.println(student1.getProfileImageUrl());
    // {"name":"name","age":10,"getImage":"link"}
    System.out.println(JsonUtil.obj2String(student1));
}

@JsonFormat

日期格式化注解,不再演示

@JsonIgnoreProperties(ignoreUnknown = true)

如果json字符串中的属性个数小于java对象中的属性个数,可以顺利转换,java中多的那个属性为null

如果json字符串中出现java对象中没有的属性,则在将json转换为java对象时会报错:Unrecognized field, not marked as ignorable

解决方法1: 在目标对象的类级别上添加注解:@JsonIgnoreProperties(ignoreUnknown = true)

解决方法2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Slf4j
public class JsonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();

    static {
        //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

}

这样就不用在目标类上加@JsonIgnoreProperties属性了,体现了全局配置的优势,配置项很多,包括格式化显示日期等,不再详细介绍,百度配置即可

用Tree Mode方式解析JSON

除了将json转为对象外,还可以用Tree Mode方式解析JSON,全程无脑操作,除了一些特别复杂的JSON,或者只取JSON中的一部分,千万不要用这种二B方式解析JSON。正确的方式是将JSON直接转为对象。我这里演示一下解析的方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "name": "zhansan", 
    "age": 100, 
    "schools": [
        {
            "name": "tsinghua", 
            "location": "beijing"
        }, 
        {
            "name": "pku", 
            "location": "beijing"
        }
    ]
}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void parseJson() throws Exception {
    String jsonStr = "{\"name\":\"zhansan\",\"age\":100,\"schools\":[{\"name\":\"tsinghua\",\"location\":\"beijing\"},{\"name\":\"pku\",\"location\":\"beijing\"}]}";

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readTree(jsonStr);

    String name = jsonNode.get("name").asText();
    int age = jsonNode.get("age").asInt();
    // name is zhansan age is 100
    System.out.println("name is " + name + " age is " + age);

    JsonNode schoolsNode = jsonNode.get("schools");
    for (int i = 0; i < schoolsNode.size(); i++) {
        String schooleName = schoolsNode.get(i).get("name").asText();
        String schooleLocation = schoolsNode.get(i).get("location").asText();
        // schooleName is tsinghua schooleLocation is beijing
        // schooleName is pku schooleLocation is beijing
        System.out.println("schooleName is " + schooleName + " schooleLocation is " + schooleLocation);
    }
}

推荐阅读:

【漫画】TCP连接为什么是三次握手,而不是两次握手,也不是四次握手?

装饰者模式在JDK和Mybatis中是怎么应用的?

MySQL索引优化实战

Java识堂

一个有干货的公众号


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java识堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
竟然有一半的人不知道 for 与 foreach 的区别???
之前有一个同事突然我问了我一个问题,说在foreach当中能不能删除list里面的元素,我当时大概说了一下是否能删除,以及原因;接下来我们来探讨一下是否能够如此; 遍历元素 首先,我们一一段代码为例: String[] array = {"1", "2", "3"}; for (String i : array) {     System.out.println(i); } ArrayList<String> list = new ArrayList<>(); list.add("111"); list.
程序猿DD
2022/05/10
2960
Java集合常见面试题集锦
1、介绍Collection框架的结构 集合是Java中的一个非常重要的一个知识点,主要分为List、Set、Map、Queue三大数据结构。它们在Java中的结构关系如下: Collection接口
陈树义
2018/04/13
9300
Java集合常见面试题集锦
简单实现_实体类与Json字符串互相转换
ha_lydms
2023/08/09
4640
简单实现_实体类与Json字符串互相转换
E027Web学习笔记-Ajax和JSON
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML);
訾博ZiBo
2025/01/06
1580
E027Web学习笔记-Ajax和JSON
【安全研究】Jackson 学习笔记
Jackson框架是基于Java平台的一套数据处理工具,被称为"最好的Java Json解析器",目前Jackson主要有1.x和2.x两个分支版本,其中1.x的类库中包命名以org.codehaus.jackson.xxx开头,2.x类库中包命令com.fastxml.jackson.xxx开头,Jackson框架包含以下3个核心库:
Al1ex
2023/03/29
2K0
【安全研究】Jackson 学习笔记
java进阶|比较器Comparable和Comparator
一,可能对于java的coder来说,这个点很简单,但对于我来说又是很难,想写这篇文章也是很久了,今天就以自己的理解来看下这两个接口,首先我们先看下Comparable接口的结构图。
码农王同学
2020/07/06
7460
《JSON笔记之二》----封装JSONUtil
许多java开发人员对于fastjson再也熟悉不过了,这是alibaba开源的依赖,使用fastjson可以使我们很容易的把请求json串转换成为我们所需要的对象、list、map等对象格式,对于开发带来了很多的遍历,具体的详细操作就不详细介绍了。
沁溪源
2020/09/03
6730
Json的FastJson与Jackson
JSON协议使用方便,越来越流行,JSON的处理器有很多,这里我介绍一下FastJson,FastJson是阿里的开源框架,被不少企业使用,是一个极其优秀的Json框架;
全栈程序员站长
2022/08/04
1.8K0
Json的FastJson与Jackson
Apache httpClient+Jackson学习笔记
HTMLUnit可以用来做爬虫的。Jsoup比他跟简洁。使用python语言进行爬虫.开箱即用。
全栈程序员站长
2022/06/30
2.6K0
Apache httpClient+Jackson学习笔记
java list 转json 字符串_JSON的String字符串与Java的List列表对象的相互转换
2.如果是需要把前端的List对象转换为json传到后台,param是ajax的参数,那么转换如下所示:
全栈程序员站长
2022/11/02
9.8K0
Ajax与Json的学习
AJAX: 1. 概念: * Asynchronous Javascript And XML”(异步 JavaScript 和 XML) * 异步和同步:客户端和服务器端相互通信的基础上 * 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。 * 客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。 Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 通过在后台与服务
Rochester
2020/09/01
2.7K0
【json】Jackson的使用
首先定义一个实例: ObjectMapper mapper = new ObjectMapper();
全栈程序员站长
2022/07/21
6630
Java中lambda表达式详解
上面的代码中,e是一个lambda的对象,根据java的继承的特性,我们可以说e对象的类型是继承自eat接口。而e1是一个正常的匿名类的对象.
付威
2018/12/05
4.8K0
Java中lambda表达式详解
Jackson,最牛掰的 Java JSON 解析器
在当今的编程世界里,JSON 已经成为将信息从客户端传输到服务器端的首选协议,可以好不夸张的说,XML 就是那个被拍死在沙滩上的前浪。
沉默王二
2020/12/15
2K0
Carson带你学序列化:深入分析JSON多种解析方式(Gson、AS自带org.json、Jackson)
步骤1:创建一个与JSON数据对应的JavaBean类(用作存储需要解析的数据) Gson解析的关键 = 根据JSON数据 写出一个对应的JavaBean,规则是:
Carson.Ho
2022/03/24
1.1K0
Carson带你学序列化:深入分析JSON多种解析方式(Gson、AS自带org.json、Jackson)
Jackson详解
其中 jackson-databind内部依赖了jackson-annotations与ackson-core,故只导入jackson-databind即可
Java微观世界
2025/01/21
4050
Jackson详解
使用 jackson 解析 json 演示样例「建议收藏」
首先须要下载3个包,下载地址在Github FasterXML,这三个核心模块各自是:
全栈程序员站长
2022/07/11
3840
Java学习之jackson篇
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/119934.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/13
8850
JavaWeb——JSON语法讲解与Jackson解析器完成JSON数据与Java对象的转换(应用Ajax与JSON实现校验用户名是否在的功能)
JSON,全名为JavaScript Object Notation,JavaScript对象表示法。Java中我们为了封装一些数据,可以定义一个对象,用对象作为参数传递数据会很方便,比如,一个Person对象:
Winter_world
2020/09/25
3.2K0
JavaWeb——JSON语法讲解与Jackson解析器完成JSON数据与Java对象的转换(应用Ajax与JSON实现校验用户名是否在的功能)
JSON介绍及Android最全面解析方法(Gson、AS自带org.son、Jackson解析)
JavaScript Object Notation,JavaScript的对象表示法,是一种轻量级的文本数据交换格式。
Carson.Ho
2019/02/22
3.4K0
推荐阅读
相关推荐
竟然有一半的人不知道 for 与 foreach 的区别???
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验