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. 力扣(LeetCode)从不订购的客户-数据库题 个人题解

    SQL架构 某网站包含两个表,Customers 表和 Orders 表.编写一个 SQL 查询,找出所有从不订购任何东西的客户. Customers 表: +----+-------+ | Id | ...

  2. 解构ffmpeg(二)

    通过比较DirectShow和ffmpeg两者的FilterGraph,分析ffmpeg的FilterGraph运作. 首先FilterGraph是一个图,图由点和边构成.在FilterGraph中的 ...

  3. HTTP,HTTPS,HTTP2笔记

    HTTP 网络协议分层 应用层 -> HTTP FTP 为应用软件提供了很多服务 构建于TCP协议之上 屏蔽网络传输的相关细节 传输层 -> TCP UDP 向用户提供可靠的端对端的服务( ...

  4. ubuntu 16.04源码编译OpenCV教程 | compile opencv on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/15f5c3e8/,欢迎阅读! compile opencv on ubuntu 16.04 Series Part 1: comp ...

  5. 串烧 JavaCAS相关知识

    JMM与问题引入 为啥先说JMM,因为CAS的实现类中维护的变量都被volatile修饰, 这个volatile 是遵循JMM规范(不是百分百遵循,下文会说)实现的保证多线程并发访问某个变量实现线程安 ...

  6. Django--导出项目依赖库requirements.txt

    虚拟环境下: 1.导出项目依赖库: pip freeze > requirements.txt 2.使用 pip 一次性安装项目的所有依赖项,方法是在命令行中输入:  pip install - ...

  7. day 49

    今日内容 标签操作 样式操作 样式类操作 addClass(); // 添加指定的CSS类名. removeClass(); // 移除指定的CSS类名. hasClass(); // 判断样式存不存 ...

  8. 安装iris框架

    1.导语 目前Go语言已经为大多数人所熟知,越来越多的开发人员选择使用Go语言来进行开发,但是如何使用 Go来进行web开发,在其他编程语言中都有对应的开发框架,当然在Go中也有,就是即将要介绍的-- ...

  9. 【数据结构】之队列(C语言描述)

    队列(Queue)是编程中最常用的数据结构之一. 队列的特点是“先进先出”,就像食堂排队买饭一样,先来的人排在前面,后来的人排在后面:前面的人先买饭,买完饭后离开这个队列.这就是队列的原理,它可以进行 ...

  10. MySQL 库、表、记录、相关操作(3)

    MySQL 库.表.记录.相关操作(3) 单表查询 """ 增: insert [into] [数据库名.]表名[(字段1[, ..., 字段n])] values (数 ...