Jackson

import lombok.Data;
@Data
public class Student {
private Long id;
private String name;
private Integer age;
private String sex;
private String[] interest;
}
public class Test {
public static void main(String[] args) throws IOException {
Student student = new Student();
student.setId(1L);
student.setName("zhangsan");
student.setAge(20);
student.setInterest(new String[]{"music", "coding"}); ObjectMapper mapper = new ObjectMapper();
//测试代码......
}
}

JavaBean转JSON字符串

String studentStr = mapper.writeValueAsString(student);
System.out.println(studentStr);
//{"id":1,"name":"zhangsan","age":20,"sex":null,"interest":["music","coding"]}

JSON字符串转JavaBean

Student stu = mapper.readValue(studentStr, Student.class);
System.out.println(stu);
//Student(id=1, name=zhangsan, age=20, sex=null, interest=[music, coding])

JSON字符串转Map集合

//对泛型的反序列化,使用TypeReference可以明确的指定反序列化的类型。
//import com.fasterxml.jackson.core.type.TypeReference;
Map<String, Object> map = mapper.readValue(studentStr, new TypeReference<Map<String, Object>>(){});
System.out.println(map);
//{id=1, name=zhangsan, age=20, sex=null, interest=[music, coding]}

注解使用

@JsonProperty

使用在JavaBean的字段上,指定一个字段用于JSON映射,默认情况下映射的JSON字段与注解的字段名称相同。该注解有三个属性:

(1)value:用于指定映射的JSON的字段名称。常用。

(2)index:用于指定映射的JSON的字段顺序。

(3)defaultValue:定义为元数据的文本默认值。注意:core databind不使用该属性,它目前只公开给扩展模块使用。

@JsonProperty(value = “user_name”)

@JsonIgnore

可用于字段、getter/setter、构造函数参数上,作用相同,都会对相应的字段产生影响。使相应字段不参与序列化和反序列化。也就是说,向“getter”添加注释会禁用“setter”。除非setter有@JsonProperty注解,在这种情况下,这被认为是一个“分割属性”,启用了“setter”,但没有“getter”(“只读”,因此属性可以从输入读取,但不是写输出)。

@JsonIgnoreProperties

该注解是类注解。该注解在Java类和JSON不完全匹配的时候使用。

(1)在序列化为JSON的时候,@JsonIgnoreProperties({"prop1", "prop2"})会忽略pro1和pro2两个属性。

(2)在从JSON反序列化为Java类的时候,@JsonIgnoreProperties(ignoreUnknown=true)会忽略所有没有Getter和Setter的属性,也就是忽略类中不存在的字段。

@JsonIgnoreType

该注解是类注解,序列化为JSON的时候会排除所有指定类型的字段。

@JsonInclude

用于定义在序列化时是否不应包含某些“非值”(null值或空值)的注解。可以用于每个字段上,也可以用于类上(表示用于类的所有属性)。

//忽略类中值为null的字段
@JsonInclude(value = JsonInclude.Include.NON_NULL)
//忽略类中值为空的字段。对于字符串,即忽略null或空字符串
@JsonInclude(Include.NON_EMPTY)

@JsonFormat

用于字段上,预期类型行为的通用注释;例如,可以用来指定序列化日期/时间值时使用的格式。

java.util.Date使用如下,java.sql.Date类似。(注意时区问题,这里添加了timezone = "GMT+8"

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class DateModel {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date date; public Date getDate() {return date;}
public void setDate(Date date) {this.date = date;}
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Date;
public class Test {
public static void main(String[] args) throws JsonProcessingException {
DateModel dateModel = new DateModel();
dateModel.setDate(new Date());
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(dateModel));
//{"date":"2020-01-01 12:16:54"}
}
}

但是注意如果JavaBean中的时间字段使用的是JDK8新增的时间日期(LocalDate / LocalTime / LocalDateTime)字段的话,直接这样使用是不起作用的。我们需要添加其他匹配,具体可参考GitHub上的说明:Jackson格式化JDK8日期

(1)添加jackson-datatype-jsr310maven配置,SpringBootweb模块会自动引入。

(2)需要进行模块注册。具体看下面的示例代码。

import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
public class DateModel {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime date; public LocalDateTime getDate() {return date;}
public void setDate(LocalDateTime date) {this.date = date;}
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.LocalDateTime;
public class Test {
public static void main(String[] args) throws JsonProcessingException {
DateModel dateModel = new DateModel();
dateModel.setDate(LocalDateTime.now());
ObjectMapper mapper = new ObjectMapper();
//自动发现并注册模块
mapper.findAndRegisterModules();
System.out.println(mapper.writeValueAsString(dateModel));
//{"date":"2020-01-01 12:40:08"}
}
}

@JsonPropertyOrder

和@JsonProperty的index属性类似,指定属性序列化时的顺序。

@JsonRootName

类注解。用于指定JSON根属性的名称。生成的JSON如下所示:

{"Teacher":{"id":2,"name":"wangwu","age":35}}

示例代码:

@JsonRootName("Teacher")
public class Teacher {
private Long id;
private String name;
private Integer age;
@JsonIgnore//转换为JSON时不需要的字段,用在属性上。
private String sex; //省略Setter/Getter方法 @Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
        Teacher teacher = new Teacher();
teacher.setId(2L);
teacher.setName("wangwu");
teacher.setAge(35);
teacher.setSex("男"); ObjectMapper mapper = new ObjectMapper();
//开启包装根植的配置
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); //将Java对象转换为JSON字符串
String teacherStr = mapper.writeValueAsString(teacher);
System.out.println(teacherStr);
//{"Teacher":{"id":2,"name":"wangwu","age":35}} //开启了根包装之后,生成的json字符串和java类不对应了,
//所以在反序列化为java类的时候会报错,关闭该属性不会报错,但是值会为空
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); //将JSON字符串转换为Java对象
Teacher tea = mapper.readValue(teacherStr, Teacher.class);
System.out.println(tea);
//Teacher{id=null, name='null', age=null, sex='null'}

@JsonAnySetter和@JsonAnyGetter

这两个属性是用来在序列化和反序列化的时候多余字段可以通过Map来回转换。也就是JSON中的字段比对应的JavaBean中的字段多,可以在JavaBean中使用一个Map字段来接收多余的JSON字段。

@JsonAnyGetter

(1)用在非静态方法上,没有参数,方法名随意(可以直接写在Getter方法上)。

(2)方法返回值必须是Map类型。

(3)在一个实体类中仅仅用在一个方法上。

(4)序列化的时候JSON字段的key就是返回Mapkeyvalue就是Mapvalue

@JsonAnySetter

(1)用在非静态方法上,注解的方法必须有两个参数,第一个是JSON字段中的key,第二个是value,方法名随意(注意这个方法不是Setter方法)。

(2)也可以用在Map对象属性上面,建议用在Map对象属性上面。

(3)反序列化的时候将对应不上的字段全部放到Map里面。

示例代码

import com.fasterxml.jackson.annotation.*;
import lombok.Data;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* @author wangbo
* @date 2019/11/16 10:47
*/
@Data
public class Student {
private Long id;
private String name;
private Integer age;
//自定义字段
private Map<String, Object> other = new HashMap(); @JsonAnyGetter
public Map<String, Object> getOther() {
return other;
} @JsonAnySetter
public void setOther(String key, Object value) {
this.other.put(key, value);
}
}
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map; /**
* @author wangbo
* @date 2019/11/16 16:54
*/
public class Test {
public static void main(String[] args) throws IOException {
Map<String,Object> map = new HashMap<>();
map.put("id", 1L);
map.put("name", "菲菲");
map.put("age", 20);
map.put("score", 90);
map.put("sex", "女"); ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(map);//序列化
System.out.println(s);
//{"score":90,"sex":"女","name":"菲菲","id":1,"age":20} Student student = mapper.readValue(s, Student.class);//反序列化
System.out.println(student);
//Student(id=1, name=菲菲, age=20, other={score=90, sex=女})
String s1 = mapper.writeValueAsString(student);//序列化
System.out.println(s1);
//{"id":1,"name":"菲菲","age":20,"score":90,"sex":"女"}
}
}

@JsonNaming

该注解放在类上。序列化的时候该注解可将驼峰命名的字段名转换为下划线分隔的小写字母命名方式的key。反序列化的时候可以将下划线分隔的小写字母key转换为驼峰命名的字段名。

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

代码示例:

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;
/**
* @author wangbo
* @date 2019/11/16 10:47
*/
@Data
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Student {
private Long appId;
private String nickName;
private Integer nowAge;
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
/**
* @author wangbo
* @date 2019/11/16 16:54
*/
public class Test {
public static void main(String[] args) throws IOException {
Student student = new Student();
student.setAppId(1L);
student.setNickName("zhangsan");
student.setNowAge(20); ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(student);//序列化
System.out.println(s);
//{"app_id":1,"nick_name":"zhangsan","now_age":20}
Student student1 = mapper.readValue(s, Student.class);//反序列化
System.out.println(student1);
//Student(appId=1, nickName=zhangsan, nowAge=20)
}
}

Jackson配置

这里有三个方法,configure方法接受配置名和要设置的值,Jackson 2.5版本新加的enabledisable方法则直接启用和禁用相应属性,推荐使用后面两个方法。

// 美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// 强制JSON空字符串("")转换为null对象值
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); // 允许序列化空的POJO类(否则会抛出异常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 把java.util.Date, Calendar输出为数字(时间戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 在遇到未知属性的时候不抛出异常
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 在JSON中允许C/C++ 样式的注释(非标准,默认禁用)
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
// 允许没有引号的字段名(非标准)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 允许单引号(非标准)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 强制转义非ASCII字符
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
// 将内容包裹为一个JSON属性,属性名由@JsonRootName注解指定
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

fastJson

package test;

import java.util.ArrayList;
import java.util.List; import com.alibaba.fastjson.JSON; class User {
private String name;
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;
} @Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}; class UserGroup {
private String name;
private List<User> users = new ArrayList<User>(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public List<User> getUsers() {
return users;
} public void setUsers(List<User> users) {
this.users = users;
} @Override
public String toString() {
return "UserGroup [name=" + name + ", users=" + users + "]";
}
} class FastJsonTest {
public static void main(String[] args) {
// 构建用户geust
User guestUser = new User();
guestUser.setName("guest");
guestUser.setAge(28);
// 构建用户root
User rootUser = new User();
rootUser.setName("root");
guestUser.setAge(35);
// 构建用户组对象
UserGroup group = new UserGroup();
group.setName("admin");
group.getUsers().add(guestUser);
group.getUsers().add(rootUser);
// 用户组对象转JSON串
String jsonString = JSON.toJSONString(group);
System.out.println("jsonString:" + jsonString);
// JSON串转用户组对象
UserGroup group2 = JSON.parseObject(jsonString, UserGroup.class);
System.out.println("group2:" + group2); // 构建用户对象数组
User[] users = new User[2];
users[0] = guestUser;
users[1] = rootUser;
// 用户对象数组转JSON串
String jsonString2 = JSON.toJSONString(users);
System.out.println("jsonString2:" + jsonString2);
// JSON串转用户对象列表
List<User> users2 = JSON.parseArray(jsonString2, User.class);
System.out.println("users2:" + users2);
}
}

输出结果如下:

jsonString:{"name":"admin","users":[{"age":35,"name":"guest"},{"age":0,"name":"root"}]}
group2:UserGroup [name=admin, users=[User [name=guest, age=35], User [name=root, age=0]]]
jsonString2:[{"age":35,"name":"guest"},{"age":0,"name":"root"}]
users2:[User [name=guest, age=35], User [name=root, age=0]]

FastJson参考文档

Jackson & fastJson的使用的更多相关文章

  1. jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解

    jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如 ...

  2. Gson/Jackson/FastJson工具类

    import java.util.ArrayList; import java.util.List; import java.util.Map; import com.google.gson.Gson ...

  3. Jackson替换fastjson

    为什么要替换fastjson 工程里大量使用了fastjson作为序列化和反序列化框架,甚至ORM在处理部分字段也依赖fastjson进行序列化和反序列化.那么作为大量使用的基础框架,为什么还要进行替 ...

  4. SpringBoot(2) Json框架 -- Jackson返回结果处理

    一.常用框架 阿里 fastjson,谷歌gson等 JavaBean序列化为Json,性能:Jackson > FastJson > Gson > Json-lib 同个结构 Ja ...

  5. 废弃fastjson!大型项目迁移Gson保姆级攻略

    前言 大家好,又双叒叕见面了,我是天天放大家鸽子的蛮三刀. 在被大家取关之前,我立下一个"远大的理想",一定要在这周更新文章.现在看来,flag有用了... 本篇文章是我这一个多月 ...

  6. Json Serialize 忽略特定属性

    Json Serialize 忽略特定属性 Json Serialize SerializeFilter 忽略特定属性 key words:Json Serialize jackson fastjso ...

  7. JSon实体类快速生成插件 GsonFormat 1.2.0

    写在前头:本插件只适用 android studio和 Intellij IDEA 工具,eclipse 的少年无视我吧!!! 这是一个根据JSONObject格式的字符串,自动生成实体类参数. gi ...

  8. 介绍4款json的java类库 及 其性能测试

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...

  9. SpringBoot企业级框架

    Zebra 微服务框架 springBoot GitHub地址:https://github.com/ae6623/Zebra OSCGit地址:http://git.oschina.net/ae66 ...

随机推荐

  1. python3之工程中必须依赖的__init__.py

    1.  __init__.py 1.1  什么是__init__.py 在Python3工程里,当python3检测到一个目录下存在__init__.py文件时,Python3就会把它当成一个模块(m ...

  2. Excel备忘录

    1. 导入文本文件(.txt) 2. 排序 3. 批量填充空白 选定区域,Ctrl+G,定位,空值. 输入内容,Ctrl+Enter. 4. 清除无法修改的背景色. 5. 身份证号 数字精度为15位, ...

  3. Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单

    Jetpack Compose学习(7)--MD样式架构组件Scaffold及导航底部菜单 | Stars-One的杂货小窝 Compose给我们提供了一个Material Design样式的首页组件 ...

  4. 5.深入TiDB:Insert 语句

    本文基于 TiDB release-5.1进行分析,需要用到 Go 1.16以后的版本 我的博客地址:https://www.luozhiyun.com/archives/605 这篇文章我们看一下 ...

  5. 实现js读取Excel数据

    如何通过js去读取excel中的数据 <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  6. 2019 年 CNCF 中国云原生调查报告

    中国 72% 的受访者生产中使用 Kubernetes 在 CNCF,为更好地了解开源和云原生技术的使用,我们定期调查社区.这是第三次中国云原生调查,以中文进行,以便更深入地了解中国云原生技术采用的步 ...

  7. SphereEx 获数百万美元天使融资,接力 ShardingSphere 开启 Database Plus 新篇章

    5月14日,数据前沿技术领域初创公司 SphereEx 获得来自红杉中国种子基金.初心资本的数百万美元天使轮融资. SphereEx是一家致力于构建新型分布式数据基础设施的公司,秉承开源.共享.生态. ...

  8. SPOJ16636 Journey IE2

    SPOJ16636 Journey IE2 更好的阅读体验 在Byteland有n个城市,编号从1到n.这些城市由m条双向道路网络连接.众所周知,每一对城市最多只能由一条道路连接. Byteman最近 ...

  9. HTTP标签

    系统的http状态码知识,我是在<图解http里学习的>. 状态码的职责是告知从服务器端返回的请求结果. 分类如下: 2XX --> 成功 200 OK(一般情况) 204 No C ...

  10. django-admin和django-admin.py的区别

    问题 django初学者在使用django-admin创建项目时容易出现无法创建的错误,这是因为网上很多教程用的都是django-admin.py创建的项目,不出意外的话,你输入相同的命令会发现项目没 ...