Jackson学习

文档:http://tutorials.jenkov.com/java-json/index.html

https://github.com/FasterXML/jackson/wiki

转载:https://www.cnblogs.com/yangchongxing/p/9153150.html

目录

=================================================================================

0、配置

1、序列化和反序列化,字段名称相同

2、序列化和反序列化,字段名称不同

3、反序列化列表对象List<CompanyLoopPicture>

4、Unrecognized field、反序列化时json中包含bean对象中没有的字段,也就是json中的字段比bean中的多

5、序列化自定义过滤器 - 普通对象

6、序列化自定义过滤器 - List中的对象字段

7、NULL、DEFAULT、EMPTY不参与序列化

8、指定属性命名策略

9、设置序列化包含、即属性显示与否

10、日期格式化

=================================================================================

0、配置

spring:
# jackson 配置
jackson:
# 日期格式化
date-format: yyyy-MM-dd HH:mm:ss
# 时区
time-zone: GMT+
# 序列化
serialization:
# 格式化输出,true格式化了有利于人看
indent-output: false
# 忽略无法转换的对象
fail-on-empty-beans: false
# 反序列化
deserialization:
# 允许对象忽略json中不存在的属性
fail-on-ignored-properties: false
# 设置空如何序列化
default-property-inclusion: non_null
# 转化
parser:
# 允许出现特殊字符和转义符
allow-unquoted-control-chars: true
# 允许出现单引号
allow-single-quotes: true
# 日期格式化
spring.jackson.date-format = yyyy-MM-dd HH:mm:ss
# 时区
spring.jackson.time-zone = GMT+
# 序列化
# 格式化输出,true格式化了有利于人看
spring.jackson.serialization.indent-output = false
# 忽略无法转换的对象
spring.jackson.serialization.fail-on-empty-beans = false
# 反序列化
# 允许对象忽略json中不存在的属性
spring.jackson.deserialization.fail-on-ignored-properties = false
# 设置空如何序列化
spring.jackson.default-property-inclusion = non_null
# 允许出现特殊字符和转义符
spring.jackson.parser.allow-unquoted-control-chars = true
# 允许出现单引号
spring.jackson.parser.allow-single-quotes = true

1、序列化和反序列化,字段名称相同

package com.qq.weixin.mp.result;

import com.fasterxml.jackson.databind.ObjectMapper;

public class AccessTokenResult {
private String accessToken;
private long expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public long getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(long expiresIn) {
this.expiresIn = expiresIn;
}
@Override
public String toString() {
return "AccessTokenResult [accessToken=" + accessToken + ", expiresIn=" + expiresIn + "]";
}
public static void main(String[] args) {
AccessTokenResult bean = new AccessTokenResult();
bean.setAccessToken("2r5fx9eiyapFxEGgHq");
bean.setExpiresIn(7200);
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(bean);//序列化
System.out.println(json);
AccessTokenResult object = mapper.readValue(json, AccessTokenResult.class);//反序列化
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}
}
}

结果

{"accessToken":"2r5fx9eiyapFxEGgHq","expiresIn":7200}
AccessTokenResult [accessToken=2r5fx9eiyapFxEGgHq, expiresIn=7200]

2、序列化和反序列化,字段名称不同

@JsonProperty(value="access_token") 也可以指定在属性字段上,这样就不用分别指定 get 和 set 方法了

package com.qq.weixin.mp.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper; public class AccessTokenResult {
private String accessToken;
private long expiresIn;
@JsonProperty(value="access_token")
public String getAccessToken() {
return accessToken;
}
@JsonProperty(value="access_token")
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
} @JsonProperty(value="expires_in")
public long getExpiresIn() {
return expiresIn;
}
@JsonProperty(value="expires_in")
public void setExpiresIn(long expiresIn) {
this.expiresIn = expiresIn;
}
@Override
public String toString() {
return "AccessTokenResult [accessToken=" + accessToken + ", expiresIn=" + expiresIn + "]";
}
public static void main(String[] args) {
AccessTokenResult bean = new AccessTokenResult();
bean.setAccessToken("2r5fx9eiyapFxEGgHq");
bean.setExpiresIn(7200);
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(bean);//序列化
System.out.println(json);
AccessTokenResult object = mapper.readValue(json, AccessTokenResult.class);//反序列化
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}
}
}

结果

{"access_token":"2r5fx9eiyapFxEGgHq","expires_in":7200}
AccessTokenResult [accessToken=2r5fx9eiyapFxEGgHq, expiresIn=7200]

@JsonProperty注解,作用在get方法将属性名序列化为指定的名称,作用在set方法将指定名称反序列化到属性

 3、反序列化列表对象List<CompanyLoopPicture>

public static void main(String[] args) {
try {
List<CompanyLoopPicture> list = new ArrayList<CompanyLoopPicture>();
CompanyLoopPicture clp = new CompanyLoopPicture();
clp.setId(1);
clp.setCompanyId(100);
clp.setTitle("google");
clp.setPicture("/upload/images/1.jpg");
clp.setLink("http://www.google.com");
clp.setFlag("modify");
list.add(clp); clp = new CompanyLoopPicture();
clp.setId(2);
clp.setCompanyId(200);
clp.setTitle("intel");
clp.setPicture("/upload/images/2.jpg");
clp.setLink("http://www.intel.com");
clp.setFlag("delete");
list.add(clp); ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(list);
System.out.println(json); JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, CompanyLoopPicture.class);
List<CompanyLoopPicture> newList = mapper.readValue(json, javaType);
或者
List<CompanyLoopPicture> newList = mapper.readValue(json, new TypeReference<List<CompanyLoopPicture>>(){});
System.out.println(newList);
} catch (Exception e) {
e.printStackTrace();
}
}

使用public <T> T readValue(String content, JavaType valueType)

JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, CompanyLoopPicture.class); 指定集合类型以及泛型类型

 4、Unrecognized field、反序列化时json中包含bean对象中没有的字段,也就是json中的字段比bean中的多

ObjectMapper mapper = new ObjectMapper();

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

或者 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

并且给Bean类的顶部追加@JsonIgnoreProperties(ignoreUnknown=true),忽略未知就可解决。

@JsonIgnore注解用来忽略某些字段,可以用在Field或者Getter方法上,用在Setter方法时,和Filed效果一样。这个注解只能用在POJO存在的字段要忽略的情况。
@JsonIgnoreProperties(ignoreUnknown = true),将这个注解写在类上之后,就会忽略类中不存在的字段,。这个注解还可以指定要忽略的字段。使用方法如下:
@JsonIgnoreProperties({ "internalId", "secretKey" })指定的字段不会被序列化和反序列化。

5、序列化自定义过滤器 - 普通对象

package com.yuanxingyuan.weixin.test;
/**
* 测试用对象
* @author 杨崇兴
*
*/
public class Person {
private String name;
private String postAddress;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPostAddress() {
return postAddress;
}
public void setPostAddress(String postAddress) {
this.postAddress = postAddress;
}
}

定义过滤器接口

package com.yuanxingyuan.weixin.test;

import com.fasterxml.jackson.annotation.JsonFilter;

@JsonFilter("MyJacksonFilter")
public interface MyJacksonFilter { }

实现

package com.yuanxingyuan.weixin.test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.yuanxingyuan.weixin.param.AddNewsArticleParam;
import com.yuanxingyuan.weixin.param.AddNewsParam;
import com.yuanxingyuan.weixin.util.JacksonUtil; public class MaterialServiceTest {
public static void main(String[] args) throws JsonProcessingException {
Person person = new Person();
person.setName("杨崇兴");
person.setPostAddress("陕西省 西安市");
person.setAge(18);
// 方式一:定义Filter
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept("age");
// 方式二:或重写 SimpleBeanPropertyFilter的 serializeAsField 方法
SimpleBeanPropertyFilter filter2 = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {
if (!writer.getName().equals("age")) {
writer.serializeAsField(pojo, jgen, provider);
}
}
};
// 定义Provider
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("MyJacksonFilter", filter);// 或者用filter2
// 数据绑定
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Person.class, MyJacksonFilter.class);
mapper.setFilterProvider(filterProvider);
String json = mapper.writeValueAsString(person);
System.out.println(json);
}
}

结果

{"name":"杨崇兴","postAddress":"陕西省 西安市"}

mapper.addMixIn(Person.class, MyJacksonFilter.class);很关键

addMixIn 方法签名如下:
public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource);
addMixIn 方法的作用是用 mixinSource 接口或类的注解会重写 target 或 target 的子类型的注解

6、序列化自定义过滤器 - List中的对象字段

测试Bean

package com.yuanxingyuan.weixin.param;

import java.util.List;

public class AddNewsParam {
/**
* 文章
*/
private List<AddNewsArticleParam> articles; public List<AddNewsArticleParam> getArticles() {
return articles;
} public void setArticles(List<AddNewsArticleParam> articles) {
this.articles = articles;
}
} package com.yuanxingyuan.weixin.param; public class AddNewsArticleParam {
/**
* 标题
*/
private String title;
/**
* 图文消息的封面图片素材id(必须是永久mediaID)
*/
private String thumbMediaId;
/**
* 作者
* 【非必须】
*/
private String author;
/**
* 图文消息的摘要,仅有单图文消息才有摘要,多图文此处为空。如果本字段为没有填写,则默认抓取正文前64个字。
* 【非必须】
*/
private String digest;
/**
* 是否显示封面,0为false,即不显示,1为true,即显示
*/
private boolean showCoverPic;
/**
* 图文消息的具体内容,支持HTML标签,必须少于2万字符,小于1M,
* 且此处会去除JS,涉及图片url必须来源 "上传图文消息内的图片获取URL"接口获取。
* 外部图片url将被过滤。
*/
private String content;
/**
* 图文消息的原文地址,即点击“阅读原文”后的URL
*/
private String contentSourceUrl; public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getThumbMediaId() {
return thumbMediaId;
}
public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDigest() {
return digest;
}
public void setDigest(String digest) {
this.digest = digest;
}
public boolean getShowCoverPic() {
return showCoverPic;
}
public void setShowCoverPic(boolean showCoverPic) {
this.showCoverPic = showCoverPic;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getContentSourceUrl() {
return contentSourceUrl;
}
public void setContentSourceUrl(String contentSourceUrl) {
this.contentSourceUrl = contentSourceUrl;
}
}

过滤对象AddNewsArticleParam中的非必需字段,author,digest

package com.yuanxingyuan.weixin.test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.yuanxingyuan.weixin.param.AddNewsArticleParam;
import com.yuanxingyuan.weixin.param.AddNewsParam;
import com.yuanxingyuan.weixin.util.JacksonUtil; public class MaterialServiceTest {
public static void main(String[] args) throws JsonProcessingException {
AddNewsArticleParam article = new AddNewsArticleParam();
article.setTitle("Title");
article.setThumbMediaId("MediaId");
article.setShowCoverPic(true);
article.setContent("content");
article.setContentSourceUrl("url");
article.setAuthor("Author");
article.setDigest("Digest");
List<AddNewsArticleParam> articles = new ArrayList<AddNewsArticleParam>();
articles.add(article);
AddNewsParam news = new AddNewsParam();
news.setArticles(articles); String json1 = JacksonUtil.toJson(AddNewsArticleParam.class, news, new String[]{"author","digest"});
System.out.println(json1);
}
    /**
* 序列化(自定义过滤器)
* @param clazz
* @param value
* @param filterFields
* @return
*/
public static String toJson(Class<?> clazz, Object value, String[] filterFields) {
try {
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(filterFields);
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("MyJacksonFilter", filter);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(clazz, MyJacksonFilter.class);
mapper.setFilterProvider(filterProvider);
return mapper.writeValueAsString(value);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}

特别注意:addMixIn中的class是List中对象的class

7、NULL、DEFAULT、EMPTY不参与序列化

方式一、使用@JsonInclude注解

放在属性上仅对该属性起作用,放在类上对整个类的属性起作用包含继承来的属性

@JsonInclude(Include.NON_NULL) ,属性为NULL时不参与序列化

方式二、使用代码

ObjectMapper mapper = new ObjectMapper();

mapper.setSerializationInclusion(Include.NON_NULL);

可设置的值:

Include.Include.ALWAYS (默认)属性都序列化
Include.NON_DEFAULT 属性为默认值不序列化
Include.NON_EMPTY 属性为空或者为NULL不序列化
Include.NON_NULL 属性为NULL不序列化

8、指定属性命名策略

Company c = new Company();
c.setName("apple");
c.setPostalCode("100000");
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
try {
String json = mapper.writeValueAsString(c);// 序列化
System.out.println(json);
Company company = mapper.readValue(json, Company.class);//反序列化
System.out.println(company.toString());
} catch (Exception e) {
e.printStackTrace();
}

PropertyNamingStrategy 的常量值

命名策略 序列化结果
SNAKE_CASE {"name":"apple","postal_code":"100000"}
UPPER_CAMEL_CASE {"Name":"apple","PostalCode":"100000"}
LOWER_CAMEL_CASE {"name":"apple","postalCode":"100000"}
LOWER_CASE "name":"apple","postalcode":"100000"}
KEBAB_CASE {"name":"apple","postal-code":"100000"}

9、设置序列化包含、即属性显示与否

name 设置为空 postalCode 设置为null

Company c = new Company();
c.setName("");
c.setPostalCode(null);
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
try {
String json = mapper.writeValueAsString(c);// 序列化
System.out.println(json);
Company company = mapper.readValue(json, Company.class);//反序列化
System.out.println(company.toString());
} catch (Exception e) {
e.printStackTrace();
}

JsonInclude.Include

序列化包含 序列化结果
ALWAYS {"name":"","postalCode":null}   不管是空还是null都包含在序列化结果中
NON_NULL {"name":""} 不包含值为null的属性
NON_DEFAULT {}
NON_EMPTY {}  不包含值为空或null的属性
NON_ABSENT {"name":""}  不包含值为null或absent like Java 8 `Optional`, or {link java.utl.concurrent.atomic.AtomicReference}的属性
USE_DEFAULTS {"name":"","postalCode":null}
CUSTOM 被 JsonInclude#valueFilter 和 JsonInclude#contentFilter 指定的

10、日期格式化

import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@TableField("time_")
private String time;

【Jackson】使用学习的更多相关文章

  1. JackSon fasterxml学习

    概述 Jackson框架是基于Java平台的一套数据处理工具,被称为"最好的JavaJson解析器".  Jackson框架包含了3个核心库:streaming,databind, ...

  2. jackson 注脚学习参考

    (1)初级我们从几个简单的使用场景开始:重命名属性,忽略属性,以及修改属性所使用的类型.注意:下面的例子仅仅显示了成员属性(field properties),注解同样也可以用在成员方法(getter ...

  3. Jackson注解学习参考(转)

    转:http://wong-john.iteye.com/blog/1753402 以下内容摘录.翻译自https://github.com/FasterXML/jackson-annotations ...

  4. Java中常见的json序列化类库 - Jackson

    Jackson 介绍 Jackson框架是基于Java平台的一套数据处理工具,被称为"最好的Java Json解析器". Jackson框架包含了3个核心库:streaming,d ...

  5. spring学习笔记---Jackson的使用和定制

      前言: JAVA总是把实体对象(数据库/Nosql等)转换为POJO对象再处理, 虽然有各类框架予以强力支持. 但实体对象和POJO, 由于"饮食习惯", "民族特色 ...

  6. jackson学习----解析豆瓣的图书信息

      异常一. org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple ...

  7. JackSon学习笔记(一)

    概述 Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”. Jackson框架包含了3个核心库:streaming,databind,annotation ...

  8. jackson学习之一:基本信息

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. jackson学习之二:jackson-core

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. nyoj 198-数数 (python, string[::-1])

    198-数数 内存限制:64MB 时间限制:3000ms 特判: No 通过数:16 提交数:25 难度:2 题目描述: 我们平时数数都是喜欢从左向右数的,但是我们的小白同学最近听说德国人数数和我们有 ...

  2. 022.掌握Pod-Pod升级和回滚

    一 deploymentPod升级和回滚 1.1 deployment升级 若Pod是通过Deployment创建的,可以在运行时修改Deployment的Pod定义(spec.template)或镜 ...

  3. Netty创建服务器与客户端

    Netty 创建Server服务端 Netty创建全部都是实现自AbstractBootstrap.客户端的是Bootstrap,服务端的则是ServerBootstrap. 创建一个 HelloSe ...

  4. Grid表格的js触发事件

    没怎么接触过Grid插件: 解决的问题是:点击Grid表行里的内容触发js方法弹出模态框,用以显示选中内容的详细信息. 思路:给准备要触发的列加上一个css属性,通过这个css属性来获取元素并触发js ...

  5. static declaration follows non-static declaration

    前段时间工作中要为android编译跨平台的第三方库,遇到了arc4random有关函数的“static declaration follows non-static declaration”问题,那 ...

  6. 7. SOFAJRaft源码分析—如何实现一个轻量级的对象池?

    前言 我在看SOFAJRaft的源码的时候看到了使用了对象池的技术,看了一下感觉要吃透的话还是要新开一篇文章来讲,内容也比较充实,大家也可以学到之后运用到实际的项目中去. 这里我使用Recyclabl ...

  7. 20190926-2 选题 Scrum立会报告+燃尽图05

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8678 一.小组情况组长:迟俊文组员:宋晓丽 梁梦瑶 韩昊 刘信鹏队名:扛 ...

  8. 【JavaEE】之MyBatis与原生JDBC、Hibernate访问数据库的比较

    首先来看一下原生JDBC访问数据库的代码: public static void main(String[] args) { // 数据库连接 Connection connection = null ...

  9. 文件系统之LVM 逻辑卷管理

    1. LVM介绍 LVM 是 Logical Volume Manager 的简称,中文就是逻辑卷管理. 物理卷(PV,Physical Volume):就是真正的物理硬盘或分区. 卷组(VG,Vol ...

  10. Process用法与进程详解

    僵尸与孤儿进程 僵尸进程:父进程的子进程结束的时候父进程没有wait()情况下子进程会变成僵尸进程 孤儿进程(无害) 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿 ...