Jackson & fastJson的使用
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-jsr310
的maven
配置,SpringBoot
的web
模块会自动引入。
(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
就是返回Map
的key
,value
就是Map
的value
。
@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
版本新加的enable
和disable
方法则直接启用和禁用相应属性,推荐使用后面两个方法。
// 美化输出
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]]
Jackson & fastJson的使用的更多相关文章
- jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解
jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如 ...
- Gson/Jackson/FastJson工具类
import java.util.ArrayList; import java.util.List; import java.util.Map; import com.google.gson.Gson ...
- Jackson替换fastjson
为什么要替换fastjson 工程里大量使用了fastjson作为序列化和反序列化框架,甚至ORM在处理部分字段也依赖fastjson进行序列化和反序列化.那么作为大量使用的基础框架,为什么还要进行替 ...
- SpringBoot(2) Json框架 -- Jackson返回结果处理
一.常用框架 阿里 fastjson,谷歌gson等 JavaBean序列化为Json,性能:Jackson > FastJson > Gson > Json-lib 同个结构 Ja ...
- 废弃fastjson!大型项目迁移Gson保姆级攻略
前言 大家好,又双叒叕见面了,我是天天放大家鸽子的蛮三刀. 在被大家取关之前,我立下一个"远大的理想",一定要在这周更新文章.现在看来,flag有用了... 本篇文章是我这一个多月 ...
- Json Serialize 忽略特定属性
Json Serialize 忽略特定属性 Json Serialize SerializeFilter 忽略特定属性 key words:Json Serialize jackson fastjso ...
- JSon实体类快速生成插件 GsonFormat 1.2.0
写在前头:本插件只适用 android studio和 Intellij IDEA 工具,eclipse 的少年无视我吧!!! 这是一个根据JSONObject格式的字符串,自动生成实体类参数. gi ...
- 介绍4款json的java类库 及 其性能测试
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...
- SpringBoot企业级框架
Zebra 微服务框架 springBoot GitHub地址:https://github.com/ae6623/Zebra OSCGit地址:http://git.oschina.net/ae66 ...
随机推荐
- contos 安装 nginx
参考链接https://blog.csdn.net/u011159417/article/details/80081992 https://blog.csdn.net/wangxy_job/artic ...
- Jmeter监控技术实战
性能测试中监控的意义 为性能分析提供依据 监控方案 serverAgent jmeter的插件,监控颗粒度不高,界面简陋 服务器中启动 jmeter中添加插件 Nmon Grafana 优秀监控方案所 ...
- pycharm向GitHub提交代码
设置为自动add commit代码 push代码 查看github,看到提交记录
- iGuard6.0 — 各适其用的网站防护体系
随着互联网新技术的涌现,网站的架构技术和涉及的资源也日益多样且复杂化.这对网站各类资源的防护工作也提出了更高的挑战和更细粒度的需求. 我们经常碰到的用户真实需求包括: 我的 CMS 制作系统,会不会 ...
- Git:分布式版本控制系统
参考廖雪峰的 Git 教程:https://www.liaoxuefeng.com/wiki/896043488029600 讲解很详细,这里只做一些个人笔记: 各系统安装 Git :https:/ ...
- 鸿蒙内核源码分析(进程回收篇) | 老父亲如何向老祖宗临终托孤 ? | 百篇博客分析OpenHarmony源码 | v47.01
百篇博客系列篇.本篇为: v47.xx 鸿蒙内核源码分析(进程回收篇) | 临终前如何向老祖宗托孤 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管 ...
- 基于AM3352/AM3354/AM3358/AM3359的Linux 开发环境搭建(上)
遇到不少人新手小白问,前辈如何搭建一个优良的Linux 开发环境?之前一直都是在用win开发,现在想要尝试用Linux做开发等等一系列的问题.开源一直是给电子行业工作者提供了一种向技术更深处进发的机遇 ...
- Mybatis-Plus 全局Update更新策略,和insert插入查询策略
前言 最近在使用mybatis-plus做项目的时候,发现使用updatById方法的时候,更新某个字段时候出现了问题,一般业务操作都是更新不为空的字段,结果发现更新了所有字段,这是由于mybatis ...
- 升级sudo版本
1.查看sudo版本 sudo -V 2.下载sudo最新安装文件 sudo官方地址: https://www.sudo.ws/ 下载地址:https://www.sudo.ws/dist/ 3.解压 ...
- P4544 [USACO10NOV]Buying Feed G
part 1 暴力 不难发现有一个 $\mathcal O(K^2n)$ 的基础 dp: $$f_{i,j+l}=\min(f_{i,j+l},f_{i-1,j}+(x_i-x_{i-1})\time ...