Jackson常用操作

Jackson常用操作

导包

官方原生包

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

spring官网提供的整合包

spring官方提供的整合包跟原生包使用上没什么区别,只是更换了包名而已。spring官方默认的Json序列化就是使用Jackson。并且springboot starter web默认就使用Jackson来做前端参数的json序列化。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
</dependency>

Jackson Json树模型

JsonNode

JsonNode类,完整路径为com.fasterxml.jackson.databind.JsonNode,是Jackson的json树模型(对象图模型)。JsonNode是抽象类,我们是无法直接创建,并且通过JsonNode来改变json树里面的值。

JsonNode的子类有:ObjectNode,TextNode,IntNode等等。所以在将JsonNode做转换为各种子类时要判断对象类型再进行转换。

ObjectNode

ObjectNode类是JsonNode的子类,可以对json树模型的节点进行写操作。

ObjectMapper objectMapper = new ObjectMapper();
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
ObjectNode objectNode = objectMapper.valueToTree(new User("jack", 20));
//添加一个json k,v对
objectNode.put("xxx",123);
System.out.println(objectNode);
//遍历等等
objectNode.forEach(jsonNode -> {
    System.out.println(jsonNode);
});

TextNode

TextNode类是文本节点,TextNode也是JsonNode的子类。

IntNode

一个Int节点,IntNode也是JsonNode的子类。

一些要注意的方法

valueToTree

valueToTree函数如下:

public <T extends JsonNode> T valueToTree(Object fromValue) throws IllegalArgumentException

valueToTree返回的对象是泛型T,并且该泛型T继承于JsonNode。如何确定valueToTree返回的值取决于你传的对象是字符串还是普通的Java对象。如:

当传入值为Java对象

//当传入普通Java对象时,返回值应该是ObjectNode
ObjectNode objectNode = objectMapper.valueToTree(new User("jack", 20));
//也可以使用JsonNode来接收(但是对象是ObjectNode,多态)
JsonNode jsonNode = objectMapper.valueToTree(new User("jack", 20));

当传入值为字符串

无论是否为Json格式的字符串,valueToTree都会返回TextNode对象

TextNode textNode = objectMapper.valueToTree("123");
//注意valueToTree方法如果输入的是字符串,返回的是TextNode,无论是否为Json格式的字符串
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
TextNode textNode = objectMapper.valueToTree(userJson);

//也可以使用JsonNode来接收(但是对象是TextNode,多态)
JsonNode jsonNode = objectMapper.valueToTree(userJson);

readTree

readTree返回的是JsonNode,但是值得注意的是,跟valueToTree相识,实际返回的对象不一定是ObjectNode(JsonNode)。

返回对象是ObjectNode

String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
JsonNode jsonNode = objectMapper.readTree(userJson);
System.out.println(jsonNode.getClass());  //结果是:ObjectNode

返回对象是IntNode

String s = "123";
JsonNode jsonNode = objectMapper.readTree(s);
System.out.println(jsonNode.getClass());  //结果是:ObjectNode

其他返回类型为JsonNode的方法

Jackson有很多方法返回类型是JsonNode,但是实际返回的是JsonNode的子类,所以但其子类是无法直接强行转换的,所以在使用这些方法时,要做类型判断,判断属于哪个子类,然后在对JsonNode做类型转换,否则很有可能会抛出强转失败异常。

常用操作转换操作

JSON字符串->Java对象

ObjectMapper objectMapper = new ObjectMapper();
//字符串
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
User user = objectMapper.readValue(userJson, User.class);

//文件
File file = new File("data/user.json");
User user = objectMapper.readValue(file, User.class);

//输入流
InputStream input = new FileInputStream("data/user.json");
User user = objectMapper.readValue(input, User.class);
//....

JSON数组字符串->Java对象数组

ObjectMapper objectMapper = new ObjectMapper();
String usersJson = "[{\"name\": \"jack\",\"age\": \"20\"},{\"name\": \"tom\",\"age\": \"21\"}]";
User[] users = objectMapper.readValue(usersJson, User[].class);
Arrays.stream(users).forEach(System.out::println);

JSON数组字符串->Java List

ObjectMapper objectMapper = new ObjectMapper();
String usersJson = "[{\"name\": \"jack\",\"age\": \"20\"},{\"name\": \"tom\",\"age\": \"21\"}]";

//转成普通的List(List里面其实LinkedHashMap)
List list = objectMapper.readValue(usersJson, List.class);
list.forEach(System.out::println);

//转成有泛型的List
List<User> users = objectMapper.readValue(usersJson, new TypeReference<List<User>>() {});
users.forEach(System.out::println);

JSON字符串->Java Map

ObjectMapper objectMapper = new ObjectMapper();
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";

//转成普通的Map(其实是Map<Object,Object>)
Map map = objectMapper.readValue(userJson, Map.class);

//转成带泛型约束的Map
Map<String, Object> user = objectMapper.readValue(userJson, new TypeReference<Map<String, Object>>() {});

JSON字符串->JsonNode

ObjectMapper objectMapper = new ObjectMapper();
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
//对象其实是ObjectNode
JsonNode jsonNode = objectMapper.readTree(userJson);
//ObjectNode jsonNode = objectMapper.readTree(userJson);

JSON字符串->ObjectNode

String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
//如果传入的json字符串结构不完整,可能会解析成其他类型,而非ObjectNode
JsonNode jsonNode = objectMapper.readTree(userJson);
//必须是ObjectNode对象才能转
if (jsonNode instanceof ObjectNode){
    ObjectNode objectNode = (ObjectNode)jsonNode;
}

字符串->TextNode

TextNode textNode = objectMapper.valueToTree("123");
//注意valueToTree方法如果输入的是字符串,返回的是TextNode,如果是对象,返回的是JsonNode
String userJson = "{\"name\": \"jack\",\"age\": \"20\"}";
TextNode textNode = objectMapper.valueToTree(userJson);

JsonNode->Java对象

User user = objectMapper.treeToValue(jack, User.class);

JsonNode->Json字符串

JsonNode jack = objectMapper.valueToTree(new User("jack", 20));
String s = jack.toString();

JsonNode->ObjectNode

//通过方法deepCopy()(只有引用指向的对象是ObjectNode才能拷贝)
if (jsonNode instanceof ObjectNode){
    ObjectNode objectNode = jsonNode.deepCopy();
}

//或者直接参试强转(只有引用指向的对象是ObjectNode才能强转类型)
if (jsonNode instanceof ObjectNode){
    ObjectNode objectNode = (ObjectNode)jsonNode;
}

JsonNode->TextNode

if (jsonNode instanceof TextNode){
    TextNode textNode = (TextNode)jsonNode;
}

Java对象->JSON字符串

//Java对象转JSON字符串
String jack = objectMapper.writeValueAsString(new User("jack", 20));

//转二进制数组
byte[] jacks = objectMapper.writeValueAsBytes(new User("jack", 20));

//数组转JSON字符串
List<User> list = new ArrayList<>();
list.add(new User("jack",20));
list.add(new User("tom",21));
String s = objectMapper.writeValueAsString(list);

Java对象->JsonNode

JsonNode jack = objectMapper.valueToTree(new User("jack", 20));

Java对象->ObjectNode

//注意valueToTree方法如果输入的是字符串,返回的是TextNode,如果是对象,返回的是JsonNode
ObjectNode objectNode = objectMapper.valueToTree(new User("jack", 20));

填充忽略未知JSON字段

在使用JSON字段填充成Java对象时,可以选择是否忽略未知的字段,默认是不忽略的。那就代表了如果JSON字符串中有字段sex,而填充的对象中没有该字段,那么就会保存。

为了解决这个问题,jackson很贴心的可以让我们去选择进行字段填充的控制,可以设置为忽略未知JSON字段。

注解方式

可以在类的上方使用注解来声明该类的字段可以忽略@JsonIgnoreProperties(ignoreUnknown = true)

/**
 * @author liangwy 
 * @since 2022-5-7
 */
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
    private String name;
    private Integer age;
}

代码配置方式

我们可以对ObjectMapper进行配置,使其在填充时忽略未知字段。spring boot web就是使用忽略未知字段。

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

ObjectMapper配置

我们可以对ObjectMapper对象进行配置来控制其行为。主要从一下三个方面进行配置:

  • SerializationFeature:序列化特征(对象->JSON)
  • DeserializationFeature:反序列化特征(JSON->对象)
  • JsonGenerator.Feature:json生成器特征

官方文档位置:

【2.7.0 SerializationFeature API文档】

【2.7.0 DeserializationFeature API文档】

【2.7.0 JsonGenerator.Feature API文档】

//配置填充行为(忽略未知字段)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

//配置浮点数反序列化为BIGDECIMAL类型
//If enabled such values will be deserialized as BigDecimals; if disabled, will be deserialized as Doubles.
objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,true);

n%2Fcore%2FJsonGenerator.Feature.html)

//配置填充行为(忽略未知字段)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

//配置浮点数反序列化为BIGDECIMAL类型
//If enabled such values will be deserialized as BigDecimals; if disabled, will be deserialized as Doubles.
objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,true);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值