Json已經成爲當前服務器與 WEB 應用之間數據傳輸的公認標準。目前java json解析工具備阿里的fastjson,google的GSON,以及SpringMVC 默認的解析工具Jackson。SpringBoot默認自帶是jackson,晚上有不少json轉換速率的比對,如jackson,阿里的fastjson等,不過jackson足夠使用了.html
使用jackson
1.pom.xml文件中引用依賴包.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
通常狀況下,SpringBoot開發web應用會引用spring-boot-starter-web依賴包,而這個依賴包會默認引用前端
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
Jackson 主要有三部分組成,除了三個模塊之間存在依賴,不依賴任何外部 jar 包。三個模塊的 做用及 artifactId
以下:java
jackson-core
: 核心包
jackson-annotations
: 註解包
jackson-databind
: 數據綁定(依賴 core
和 annotations
)
而 jackson-databind 依賴另外兩個,因此單獨引用時,只引用 jackson-databind 就可使用了.node
2.使用
實體類:web
//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("xiaomin@sina.com");
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":"xiaomin@sina.com"}
String json = mapper.writeValueAsString(user);
System.out.println(json);
//Java集合轉JSON
//輸出結果:[{"name":"小民","age":20,"birthday":844099200000,"email":"xiaomin@sina.com"}]
List<User> users = new ArrayList<User>();
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\":\"xiaomin@sina.com\"}";
/**
* 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提供了兩種方法:spring
1.單獨格式化
在對象屬性上,或者在屬性的 getter 方法上,以下代碼所示:
增長到屬性上:數據庫
/**更新時間 用戶能夠點擊更新,保存最新更新的時間。**/
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
增長到 getter 方法上:json
@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("xiaomin@sina.com");
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":"xiaomin@sina.com"}
}
}
在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;
/**
* <b>Description:</b> json轉換工具類 <br>
*
* @author luozhen
* @version 1.0
* @Note <b>ProjectName:</b> MySpringBoot <br>
* <b>PackageName:</b> com.luozhen.util <br>
* <b>ClassName:</b> JacksonActivity <br>
* <b>Date:</b> 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);
}
/**
*
* <b>Description:</b> 將一個object轉換爲json, 可使一個java對象,也可使集合<br>
* <b>Title:</b> ObjectToJson<br>
*
* @param obj
* - 傳入的數據
* @return
* @Note <b>Author:</b> luozhen <br>
* <b>Date:</b> 2018年5月24日 下午1:26:53 <br>
* <b>Version:</b> 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反序列化。
*/
/**
*
* <b>Description:</b> 將json結果集轉化爲對象<br>
* <b>Title:</b> jsonToClass<br>
*
* @param json
* - json數據
* @param beanType
* - 轉換的實體類型
* @return
* @Note <b>Author:</b> luozhen <br>
* <b>Date:</b> 2018年5月24日 下午3:26:18 <br>
* <b>Version:</b> 1.0
*/
public static <T> T jsonToClass(String json, Class<T> beanType) {
T t = null;
try {
t = mapper.readValue(json, beanType);
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
/**
*
* <b>Description:</b> 將json數據轉換成Map<br>
* <b>Title:</b> jsonToMap<br>
*
* @param json
* - 轉換的數據
* @return
* @Note <b>Author:</b> luozhen <br>
* <b>Date:</b> 2018年5月24日 下午3:29:37 <br>
* <b>Version:</b> 1.0
*/
public static Map<String, Object> jsonToMap(String json) {
Map<String, Object> map = null;
try {
map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
*
* <b>Description:</b> 將json數據轉換成list <br>
* <b>Title:</b> jsonToList<br>
*
* @param json
* - 轉換的數據
* @return
* @Note <b>Author:</b> luozhen <br>
* <b>Date:</b> 2018年5月24日 下午3:28:35 <br>
* <b>Version:</b> 1.0
*/
public static <T> List<T> jsonToList(String json, Class<T> beanType) {
List<T> list = null;
try {
JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType);
list = mapper.readValue(json, javaType);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
*
* <b>Description:</b> 獲取json對象數據的屬性<br>
* <b>Title:</b> findValue<br>
*
* @param resData
* - 請求的數據
* @param resPro
* - 請求的屬性
* @return 返回String類型數據
* @Note <b>Author:</b> luozhen <br>
* <b>Date:</b> 2018年5月31日 上午10:00:09 <br>
* <b>Version:</b> 1.0
*/
public static String findValue(String resData, String resPro) {
String result = null;
try {
JsonNode node = mapper.readTree(resData);
JsonNode resProNode = node.get(resPro);
result = JsonUtils.objectToJson(resProNode);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}