Json已经成为当前服务器与 WEB 应用之间数据传输的公认标准。目前java json解析工具有阿里的fastjson,google的GSON,以及SpringMVC 默认的解析工具Jackson。SpringBoot默认自带是jackson,晚上有很多json转换速率的比对,如jackson,阿里的fastjson等,不过jackson足够使用了.
使用jackson
1.pom.xml文件中引用依赖包.
com.fasterxml.jackson.core
jackson-databind
2.9.5
一般情况下,SpringBoot开发web应用会引用spring-boot-starter-web依赖包,而这个依赖包会默认引用
com.fasterxml.jackson.core
jackson-annotations
2.8.0
com.fasterxml.jackson.core
jackson-core
2.8.7
com.fasterxml.jackson.core
jackson-databind
2.8.7
Jackson 主要有三部分组成,除了三个模块之间存在依赖,不依赖任何外部 jar 包。三个模块的 作用及 artifactId
如下:
-
jackson-core
: 核心包 -
jackson-annotations
: 注解包 -
jackson-databind
: 数据绑定(依赖core
和annotations
)
而 jackson-databind 依赖另外两个,所以单独引用时,只引用 jackson-databind 就可以使用了.
2.使用
实体类:
//JSON序列化和反序列化使用的User类
import java.util.Date;
public class User {
private String name;
private Integer age;
private Date birthday;
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
1.序列化
ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。
ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。
writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。
writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。
writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。
writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
使用的示例:
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonDemo {
public static void main(String[] args) throws ParseException, IOException {
User user = new User();
user.setName("小民");
user.setEmail("[email protected]");
user.setAge(20);
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(dateformat.parse("1996-10-01"));
ObjectMapper mapper = new ObjectMapper();
//User类转JSON
//输出结果:{"name":"小民","age":20,"birthday":844099200000,"email":"[email protected]"}
String json = mapper.writeValueAsString(user);
System.out.println(json);
//Java集合转JSON
//输出结果:[{"name":"小民","age":20,"birthday":844099200000,"email":"[email protected]"}]
List users = new ArrayList();
users.add(user);
String jsonlist = mapper.writeValueAsString(users);
System.out.println(jsonlist);
}
}
2.反序列化
import java.io.IOException;
import java.text.ParseException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonDemo {
public static void main(String[] args) throws ParseException, IOException {
String json = "{\"name\":\"小民\",\"age\":20,\"birthday\":844099200000,\"email\":\"[email protected]\"}";
/**
* ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。
*/
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user);
}
}
3.JSON注解
Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。
@JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。
@JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。
@JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty("name")。
注:关于日期格式的格式化,jackson提供了两种方法:
1.单独格式化
在对象属性上,或者在属性的 getter 方法上,如下代码所示:
增加到属性上:
/**更新时间 用户可以点击更新,保存最新更新的时间。**/
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
增加到 getter 方法上:
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
public Date getUpdateTime() {
return updateTime;
}
以上结果输出都是一样的。这个没有什么好说明的。具体输出格式,自己调整 pattern 。
@JsonFormat 相差8小时问题
上面直接这么使用,在我们中国来讲和我们的北京时间,会相差8个小时,因为我们是东八区(北京时间)。
所以我们在格式化的时候要指定时区(timezone ),代码如下:
/**更新时间 用户可以点击更新,保存最新更新的时间。**/
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date updateTime;
也就是增加一个属性,timezone="GMT+8" 即可,getter 方法我就不写了,一样的。
2.统一格式化
数据库里面查出来的时间是时间错格式,前端需要处理才能展示相应的格式,自己一个个转的话太麻烦,所以可以在apllication.properties加入下面配置就可以
注意:
前置条件:
使用resultMap作为结果返回集
#时间戳统一转换
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
其中time-zone是时区偏移设置,如果不指定的话时间和北京时间会差八个小时。
上述的方法都是针对出参,还有一个日期格式化,不过这个是针对传入的参数,放在Date类型属性或setter方法上,两者可以同时使用,
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date updateTime;
标签的使用如下:
import java.util.Date;
import com.fasterxml.jackson.annotation.*;
public class User {
private String name;
//不JSON序列化年龄属性
@JsonIgnore
private Integer age;
//格式化日期属性
@JsonFormat(pattern = "yyyy年MM月dd日")
private Date birthday;
//序列化email属性为mail
@JsonProperty("mail")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonDemo {
public static void main(String[] args) throws ParseException, IOException {
User user = new User();
user.setName("小民");
user.setEmail("[email protected]");
user.setAge(20);
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(dateformat.parse("1996-10-01"));
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
System.out.println(json);
//输出结果:{"name":"小民","birthday":"1996年09月30日","mail":"[email protected]"}
}
}
4.readTree
在jackson中, 有些场景下,在实现一些基础服务和拦截器的时候,我们可能需要在不知道JSON字符串所属对象类型的情况下,对JSON字符串中的某些属性进行遍历和修改,比如,设置或查询一些报文头字段。
在jackson中,使用最多的JsonNode抽象类并没有提供修改节点值的方法,而是在ObjectNode节点中提供修改接口,这个节点在官方的说明中,一般用于创建新的节点。
在ObjectNode节点中提供修改接口(put),JsonNode提供查询的接口;
JsonNode rootNode = mapper.readTree(jsonStr);//jsonStr是一个json字符串
JsonNode targetNode = null;
targetNode = rootNode.findValue("rpcMsgId"); // 查找第一级的rpcMsgId属性,如果属性不存在,则返回null,属性值如果为明确的null,返回NullNode,否则返回正常的JsonNode
// 注:JsonNode还提供了find/path/get等获取节点的方法,但是这三种方法都不能明确的区分节点不存在、为明确的null。所以,应该使用findValue方法。
如果只是纯粹的遍历和类似JsonTree的构造,网上各种文章一堆,主要是对原json中属性的修改。可通过如下方式进行修改:
((ObjectNode)targetNode).put("rpcMsgId","abcdefg1234567890");
// 通过强制转换为ObjectNode,就可以对当前节点进行修改,其他的XXXNode均没有提供相关的API接口 String modifiedJsonStr = mapper.writeValueAsString(rootNode); // 最后重新生成json字符串,这跟dom4j修改xml一样,只能重新生成,内置不支持直接修改原文件
//完整的代码
JsonNode node = mapper.readTree(jsonStr);
JsonNode node1 = node.findValue("spiderPacketHead");
ObjectNode node2 = (ObjectNode) node1;
node2.put("rpcMsgId", "abc");
原文:https://www.cnblogs.com/zhjh256/p/6049663.html
示例:http://lijingshou.iteye.com/blog/2003112
jackson中各种属性总结:https://www.cnblogs.com/jian-xiao/p/6009435.html?utm_source=itdadao&utm_medium=referral
jackson中的使用方式:https://blog.csdn.net/java_huashan/article/details/46375857
在这里贴上我自己更改后的工具类JsonUtils代码:
package com.luozhen.util.jackson;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
/**
* Description: json转换工具类
*
* @author luozhen
* @version 1.0
* @Note ProjectName: MySpringBoot
* PackageName: com.luozhen.util
* ClassName: JacksonActivity
* Date: 2018年5月24日 下午12:50:59
*/
public class JsonUtils {
/**
* ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。
* ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。
* writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。
* writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。
* writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。
* writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
*/
/**
* 初始化变量
*/
private static ObjectMapper mapper = new ObjectMapper();
static {
// 解决实体未包含字段反序列化时抛出异常
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 对于空的对象转json的时候不抛出错误
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 允许属性名称没有引号
mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 允许单引号
mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
}
/**
*
* Description: 将一个object转换为json, 可以使一个java对象,也可以使集合
* Title: ObjectToJson
*
* @param obj
* - 传入的数据
* @return
* @Note Author: luozhen
* Date: 2018年5月24日 下午1:26:53
* Version: 1.0
*/
public static String objectToJson(Object obj) {
String json = null;
try {
json = mapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
/**
* ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。
*/
/**
*
* Description: 将json结果集转化为对象
* Title: jsonToClass
*
* @param json
* - json数据
* @param beanType
* - 转换的实体类型
* @return
* @Note Author: luozhen
* Date: 2018年5月24日 下午3:26:18
* Version: 1.0
*/
public static T jsonToClass(String json, Class beanType) {
T t = null;
try {
t = mapper.readValue(json, beanType);
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
/**
*
* Description: 将json数据转换成Map
* Title: jsonToMap
*
* @param json
* - 转换的数据
* @return
* @Note Author: luozhen
* Date: 2018年5月24日 下午3:29:37
* Version: 1.0
*/
public static Map jsonToMap(String json) {
Map map = null;
try {
map = mapper.readValue(json, new TypeReference