目录

  一、先搞两个测试需要使用的类

  二、简单操作:obj与json互转

    2.1、对象转json字符串

    2.2、json字符串转对象

三、拓展需求

  3.1、对象转json时,忽略某个字段

    3.2、对象转json时,自定义json中的属性名

    3.3、对象转json时,忽略对象中为null或者""的属性

    3.4、json转对象时,忽略json中未知的属性

    3.5、对象转json时,生成格式化的json字符串

一、先搞两个测试需要使用的类

  分别是Staff(员工)和Department(部门)

package cn.ganlixin.demo;

import lombok.Data;

@Data
public class Department { private String depName;
private String addr;
private String superior;
}

  

package cn.ganlixin.demo;

import lombok.Data;

import java.util.List;
import java.util.Map; @Data
public class Staff {
private int id;
private String name;
private boolean isAdult;
private List<String> languages;
private Map<String, Object> scores;
private Department department;
}

  

二、简单操作:obj与json互转

2.1、对象转json字符串

  核心代码段

ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(Object obj);
// Object就是需要序列化(转换为json字符串的对象)

  

  示例

/**
* 对象 转为 json字符串
*/
@Test
public void test1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper(); List<String> languages = new ArrayList<>();
languages.add("Java");
languages.add("PHP");
languages.add("Python");
String languagesJsonStr = mapper.writeValueAsString(languages);
System.out.println(languagesJsonStr);
// ["Java","PHP","Python"] Map<String, Object> scores = new HashMap<>();
scores.put("math", 59);
scores.put("english", 58);
String scoresJsonStr = mapper.writeValueAsString(scores);
System.out.println(scoresJsonStr);
// {"english":58,"math":59} Department department = new Department();
department.setDepName("QA");
department.setAddr("beijing");
department.setSuperior("小强");
String departmentJsonStr = mapper.writeValueAsString(department);
System.out.println(departmentJsonStr);
// {"depName":"QA","addr":"beijing","superior":"小强"}
}

  

2.2、json字符串转对象

  核心代码

ObjectMapper mapper = new ObjectMapper();
Staff staff = mapper.readValue(jsonStr, Staff.class);
// 表示将json字符串的内容转换为Staff类的对象

  

  示例:

/**
* 将json字符串转换为对象
*/
@Test
public void test2() throws IOException {
ObjectMapper mapper = new ObjectMapper(); String languageJsonStr = "[\"Java\",\"PHP\",\"Python\"]";
final List languages = mapper.readValue(languageJsonStr, List.class);
System.out.println(languages);
// [Java, PHP, Python] String scoresJsonStr = "{\"english\":58,\"math\":59}";
Map<String, Object> scores = mapper.readValue(scoresJsonStr, Map.class);
System.out.println(scores);
// {english=58, math=59} String departmentJsonStr = "{\"depName\":\"QA\",\"addr\":\"beijing\",\"superior\":\"小强\"}";
final Department department = mapper.readValue(departmentJsonStr, Department.class);
System.out.println(department);
// Department(depName=QA, addr=beijing, superior=小强)
}

  

三、拓展需求

3.1、对象转json时,忽略某个字段

  有些场景中,某些字段在序列化为json的时候,应该省略掉,比如一个员工的工资,某个用户的密码.....

  案例:假设有一个department对象,在转为json时,superior(上级)这个字段不能出现在转换后的json中

  方案1:在不需要参与json序列化的字段前增加@JsonIgnore注解即可

@Data
public class Department { private String depName;
private String addr; @JsonIgnore // 加了@JsonIgnor字段后,superior字段将不参与json序列化
private String superior;
}

  

  方案2:在类上面使用@JsonIgnoreProperties({"field1", "field2"})来指定哪些字段不参与json序列化

@Data
@JsonIgnoreProperties({"superior"})
// 在@JsonIgnoreProperties注解中指定不参与json序列化的字段即可(接收字符串数组)
public class Department { private String depName;
private String addr;
private String superior;
}

  

  测试

/**
* 对象转json时,忽略某个字段
*/
@Test
public void test3() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper(); Department department = new Department();
department.setDepName("QA");
department.setAddr("beijing");
department.setSuperior("小强"); final String departmentJsonStr = mapper.writeValueAsString(department);
System.out.println(departmentJsonStr);
// {"depName":"QA","addr":"beijing"}
}

  

3.2、对象与json互转时,自定义json中的属性名

  经常会碰到我们的模型类中定义的属性名称,与外部传入的json字符串中的名称不相同的情况,比如Department类中的superior属性,接收到外部系统传过来的json字符串中,对应upLevel字段。

  在序列化时(obj->json)和反序列化时(json->obj)都需要解决上面superior到upLevel的对应问题,Jackson中提供了一个@JsonProperty注解来解决这个问题

@Data
public class Department {
private String depName;
private String addr; @JsonProperty("upLevel")
// 指定序列化与反序列化时,superior属性对应的名称:序列化时,superior对应到upLevel属性,反序列化时,upLevel对应到superior属性
private String superior;
}

  

  示例:

/**
* 对象与json互转时,自定义对应名称
*/
@Test
public void test4() throws IOException {
ObjectMapper mapper = new ObjectMapper(); Department department1 = new Department();
department1.setDepName("QA");
department1.setAddr("beijing");
department1.setSuperior("小强"); // 对象序列化为json字符串,注意superior属性转json时会变为upLevel
String departmentJsonStr = mapper.writeValueAsString(department1);
System.out.println(departmentJsonStr);
// {"depName":"QA","addr":"beijing","upLevel":"小强"} // 利用上面序列化的字符串,反序列为对象,upLevel字段会对应到Department对象的superior属性
Department department2 = mapper.readValue(departmentJsonStr, Department.class);
System.out.println(department2);
// Department(depName=QA, addr=beijing, superior=小强)
}

  

3.3、对象转json时,忽略对象中为null或者""的属性

  这个需求是这样的,对象中,有的属性值是null或者空字符串,此时,我们不希望转换后的json字符串中包含该属性值为null或者空字符串的字段。

  比如Department类中的superior属性,对于老板来说,没有上级,则superior的值为null或者"",此时希望序列化后的json字符串省略superior字段(这与前面的省略某个字段不同)。

  Jackson在将对象序列化为json字符串时,默认是在类级别添加了@JsonInclude(JsonInclude.Include.ALWAYS)注解,表示默认将对象的所有字段都序列化(即使属性值为null或者空字符串)。

  要实现忽略对象中属性值为null或者""的属性值,可以这样做:

  方案1:

    @JsonInclude(JsonInclude.Include.NON_NULL)  可以加在指定的字段前(局部),也可以加在类级别上(全局),当属性值不为null的时候才会参加序列化

    @JsonInclude(JsonInclude.Include.NON_EMPTY) 可以加在指定的字段前(局部),也可以加在类级别上(全局),当设置属性值为null或者""的时候,该属性不会参加序列化;

    注意,对于上面两个注解,如果类中声明该属性有默认值,即使没有为该属性设置属性值,那么该属性仍旧会参加序列化。

@Data
public class Department {
private String depName;
private String addr; @JsonInclude(JsonInclude.Include.NON_NULL) // 加在指定的字段前,当属性值不为null的时候才会参加序列化
private String superior;
}

  

  方案2:

    方案1使用于要序列化的类数量不多的情况,如果要进行序列化的类非常多,并且都需要忽略属性值为null或者""的属性,那么对每一个类进行设置@JsonInclude(xxxx)也是很麻烦的,这个时候,我们可以从ObjectMapper上进行配置,使用配置后的ObjectMapper,那么在序列化的时候,自动回忽略值为null或者""的属性值。 

/**
* 全局设置对象转json时忽略值为null或者""的属性
*/
@Test
public void test7() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
// 设置忽略null和""的属性值,这里的Include与方案1的一致
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); Department department1 = new Department();
department1.setDepName("QA");
department1.setAddr("");
department1.setSuperior(null); String depJsonStr = mapper.writeValueAsString(department1);
System.out.println(depJsonStr);
// {"depName":"QA"}
}

 

3.4、json转对象时,忽略json中未知的属性

  这个场景是指,json中有一个字段,在类中找不多与之对应的属性,此时如果强请转换为指定类,那么就会报错

@Test
public void test8() throws IOException {
// 注意,json串中多了age字段,而Department类中并无该属性(且无属性与之对应,比如使用@JsonProperty进行设置)
String json = "{\"depName\":\"QA\",\"addr\":\"beijing\", \"age\":99}"; ObjectMapper mapper = new ObjectMapper();
final Department department = mapper.readValue(json, Department.class);
System.out.println(department);
}

  上面的运行时会报错:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class cn.ganlixin.demo.Department), not marked as ignorable....

  这个情况,可以通过设置mapper来解决问题

/**
* 忽略json中未知的字段名
*/
@Test
public void test9() throws IOException {
String json = "{\"depName\":\"QA\",\"addr\":\"beijing\", \"age\":99}"; ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 表示遇到未知属性时,不会报错
final Department department = mapper.readValue(json, Department.class);
System.out.println(department);
// Department(depName=QA, addr=beijing, superior=null)
}

  

3.5、对象转json时,生成格式化的json字符串

  在writeValueAsString(Object obj)之前,mapper先调用writerWithDefaultPrettyPrinter()方法即可

@Test
public void test6() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper(); Department department1 = new Department();
department1.setDepName("QA");
department1.setAddr("beijing");
department1.setSuperior("小强");
final String depJsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(department1);
System.out.println(depJsonStr);
/*
{
"depName" : "QA",
"addr" : "beijing",
"superior" : "小强"
}
*/
}

  

  

Jackson的基本用法与拓展的更多相关文章

  1. Jackson的简单用法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1简介 Jackson具有比较高的序列化和反序列化效率,据测试,无论是 ...

  2. Jackson最简单用法

    jackson的包在:https://yunpan.cn/cu2b6eMaBjFpz  访问密码 753f 代码: ObjectMapper objectMapper = new ObjectMapp ...

  3. Jackson 的 基本用法

    Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架.Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson ...

  4. (转)关于Jackson2.x中com.fasterxml.jackson包的用法

    Jackson应该是目前最好的json解析工具了,之前一直用的是org.codehaus.jackson包中的工具,使用的 包是jackson-all-1.9.11.jar. 最近发现Jackson升 ...

  5. Looooops(求解同余方程、同余方程用法)【拓展欧几里得】

    Looooops(点击) A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; ...

  6. 补一篇关于Jackson和Gson的文章

    一.关于Gson的问题 问题1. 如果对象属性里有[],表示它是一个列表,需要用List对象进行封装,不能用String来定义,不然转不了 问题2. Gson在解析的时候,如果json中有转义字符 \ ...

  7. Android Jackson 概述

    原文地址 本文内容 JSON 的三种方式 示例 完全数据绑定(POJO)示例 "Raw"数据绑定示例 用泛型数据绑定 树模型(Tree Model)示例 流(Streaming)A ...

  8. Jackson的高级应用(转)

    Jackson 是当前用的比较广泛的,用来序列化和反序列化 JSON 的 Java 的开源框架.Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson ...

  9. Jackson 框架的高阶应用

    Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架.Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson ...

随机推荐

  1. 算法——dfs 判断是否为BST

    95. 验证二叉查找树 中文English 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值 ...

  2. 指针数组(int *a[])和数组指针 (int (*a)[])

    1.对指针有关的表达式阅读遵循的规则是“从右到左.由近到远.括号优先”. int *a[10]   从字符a开始,右侧是[10],表示a 为一个包含10个元素的数组,左侧为指针标记,表示这个数组中保存 ...

  3. mysql-mysqldump

    备份(导出)所有数据库的数据和结构(注意:这种方式备份,还原时,无需先创建数据库,可直接导入) mysqldump -u root -p 'password' --all-databases > ...

  4. python应用-判断回文素数

    from math import sqrt number=int(input('请输入一个整数:')) def is_prime(num): for rea in range(2,int(sqrt(n ...

  5. Brief Introduction to SDK – JRE – JVM – JIT

    Brief Introduction to SDK – JRE – JVM – JIT SDK This is complete collection of Java stuff, as it has ...

  6. 本地部署Easy Mock

    最近在自己捣腾个vue的项目,苦于没有接口测试.网上搜寻一遍,基本上是使用mock.js模拟数据.研究mock.js 过程中,发现很多人提到了Easy Mock,发现它更加的方便.但是访问Eash M ...

  7. Linux软件安装——软件包分类、RPM包管理

    1.软件包分类: (1)源码包: 优点:开源,即用户可以看到源代码,用户可以修改源代码:可以自由选择所需的功能:软件是编译安装,效率更高. 缺点:需要手动安装,安装慢. (2)二进制包(RPM包.系统 ...

  8. Odds calculation required for the python strategy library

    Bet Class class strats.Bet(inp)[source] Here is an example of the expected string input on instantia ...

  9. CGLIB和Java动态代理的区别(笔记)

    java常用知识点: 1.Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承):CGLIB能够代理普通类:2.Jav ...

  10. java8 新特性parallelStream 修改默认多线程数量

    parallelStream默认使用了fork-join框架,其默认线程数是CPU核心数. 通过测试实践,发现有两种方法来修改默认的多线程数量: 1.全局设置 在运行代码之前,加入如下代码: Syst ...