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; } }