SpringBoot學習--使用jackson返回json數據

目前java json解析工具有阿里的fastjson,google的GSON,以及SpringMVC 默認的解析工具Jackson。SpringBoot默認自帶是jackson,很多json轉換速率的比對,如jackson,阿里的fastjson等,jackson足夠使用了.

使用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依賴包,而這個依賴包會默認引用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<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 如下:

  • 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.序列化

1

2

3

4

5

6

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<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\":\"[email protected]\"}";  
          
        /** 
         * ObjectMapper支持從byte[]、File、InputStream、字符串等數據的JSON反序列化。 
         */  
        ObjectMapper mapper = new ObjectMapper();  
        User user = mapper.readValue(json, User.class);  
        System.out.println(user);  
    }  
}  

複製代碼

 

3.JSON註解

1

2

3

4

5

6

7

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;

/**
 * <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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章