中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

如何構(gòu)建一個JSON字符串

本篇文章給大家分享的是有關(guān)如何構(gòu)建一個JSON字符串,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

主要從事網(wǎng)頁設(shè)計、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、自適應(yīng)網(wǎng)站建設(shè)、程序開發(fā)、微網(wǎng)站、微信平臺小程序開發(fā)等,憑借多年來在互聯(lián)網(wǎng)的打拼,我們在互聯(lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的網(wǎng)站制作、成都網(wǎng)站制作、網(wǎng)絡(luò)營銷經(jīng)驗,集策劃、開發(fā)、設(shè)計、營銷、管理等多方位專業(yè)化運(yùn)作于一體,具備承接不同規(guī)模與類型的建設(shè)項目的能力。

一、alibaba 的 Fastjson

1.Fastjson 是一個以 Java 語言編寫的 JSON 處理器,由阿里巴巴公司開發(fā),功能強(qiáng)大。

要使用第三方的工具當(dāng)然要導(dǎo)入 jar 包了,只需導(dǎo)入 fastjson-1.2.8.jar 即可,jar 包的獲取,大家可以直接去網(wǎng)上下載 ,也可以聯(lián)系本人。

先來一個 fastjson 的簡單實(shí)例吧,如下代碼構(gòu)造了一個 Customer 的實(shí)例,并將此實(shí)例轉(zhuǎn)化成為 JSON 字符串,調(diào)用了 com.alibaba.fastjson.JSON 的 toJSONString() 方法,將 Customer 實(shí)例傳入

@Test
public void test1() {
 
 Customer customer = new Customer();
 customer.setId(1);
 customer.setCustName("Tom");
 customer.setAddress("BeiJing");
 
 String jsonStr = JSON.toJSONString(customer);
 System.out.println(jsonStr);
}

打印結(jié)果:{"address":"BeiJing","custName":"Tom","id":1}

再來一個小測試,將一個 List 的 Customer 的集合轉(zhuǎn)換為 JSON 字符串,22 行還是直接調(diào)用 JSON 的 toJSONString() 方法,將 List 集合傳入即可

/**
* 將 List 集合轉(zhuǎn)換為 JSON 字符串
*/
@Test
public void test2() {
 List<Customer> lists = new ArrayList<>();
 
 Customer customer = new Customer();
 customer.setId(1);
 customer.setCustName("Tom");
 customer.setAddress("BeiJing");
 
 lists.add(customer);
 
 Customer customer2 = new Customer();
 customer2.setId(1);
 customer2.setCustName("Bob");
 customer2.setAddress("ShangHai");
 
 lists.add(customer2);
 
 String jsonStr = JSON.toJSONString(lists);
 System.out.println(jsonStr);
}

打印結(jié)果:[{"address":"BeiJing","custName":"Tom","id":1},{"address":"ShangHai","custName":"Bob","id":1}]

2. 深入研究一下,我們看下面這種情況:3 行創(chuàng)建了一個 List 的 Customer 集合,10 和 11 行進(jìn)行了一個重復(fù)的 add 操作,那么打印結(jié)果是什么樣的呢?

@Test
public void test3() {
 List<Customer> lists = new ArrayList<>();

 Customer customer = new Customer();
 customer.setId(1);
 customer.setCustName("Tom");
 customer.setAddress("BeiJing");

 lists.add(customer);
 lists.add(customer);
 
 String jsonStr = JSON.toJSONString(lists);
 System.out.println(jsonStr);

}

打印結(jié)果:[{"address":"BeiJing","custName":"Tom","id":1},{"$ref":"$[0]"}],大家看,第二個 Customer 實(shí)例沒有打印出,這就證明了 fastjson 默認(rèn)禁止循環(huán)的引用,如果想改變這種情況,需要在 JSON 的 toJSONString() 方法中傳遞第二個參數(shù) SerializerFeature.DisableCircularReferenceDetect 即可解決,如下:

@Test
public void test3() {
  List<Customer> lists = new ArrayList<>();

  Customer customer = new Customer();
  customer.setId(1);
  customer.setCustName("Tom");
  customer.setAddress("BeiJing");

  lists.add(customer);
  lists.add(customer);
 
  String jsonStr = JSON.toJSONString(lists, SerializerFeature.DisableCircularReferenceDetect);
  System.out.println(jsonStr);

}

此時的打印結(jié)果為:[{"address":"BeiJing","custName":"Tom","id":1},{"address":"BeiJing","custName":"Tom","id":1}],建議以后再使用 JSON 的 toJSONString() 方法時將第二個參數(shù)添加上

3.再深入一點(diǎn),來看一個常見的問題,Department 和 Manager 類維護(hù)雙向一對一的關(guān)聯(lián)關(guān)系,Department 類中有 Manager 類的引用,Manager 類中有 Department 類的引用,來看如下代碼:在 11 和 12 行設(shè)置了關(guān)聯(lián)關(guān)系,14 行和 15 行進(jìn)行 JSON 字符串的轉(zhuǎn)換,結(jié)果會怎樣呢?

  @Test
 public void test4() {
 Manager mgr = new Manager();
 mgr.setMgrId(1);
 mgr.setMgrName("Tom");
 
 Department dept = new Department();
 dept.setDeptId(2);
 dept.setDeptName("DEV");
 
 mgr.setDept(dept);
 dept.setManager(mgr);
 
 String jsonStr = JSON.toJSONString(dept, SerializerFeature.DisableCircularReferenceDetect);
// String jsonStr = JSON.toJSONString(mgr, SerializerFeature.DisableCircularReferenceDetect);
 System.out.println(jsonStr);
 }

答案是,拋出了異常,常見的 java.lang.StackOverflowError,拋異常的原因是雙方都維護(hù)關(guān)聯(lián)關(guān)系進(jìn)入了死循環(huán),那么如何解決這個問題呢?可以在一方添加 @JSONField(serialize=false)注解,7 行所示,即可解決

public class Department {
 
 private Integer deptId;
 
 private String deptName;
 
 @JSONField(serialize=false)
 private Manager manager;

 public Integer getDeptId() {
 return deptId;
 }

 public void setDeptId(Integer deptId) {
 this.deptId = deptId;
 }

 public String getDeptName() {
 return deptName;
 }

 public void setDeptName(String deptName) {
 this.deptName = deptName;
 }

 public Manager getManager() {
 return manager;
 }

 public void setManager(Manager manager) {
 this.manager = manager;
 }
 
}

打印結(jié)果為:{"dept":{"deptId":2,"deptName":"DEV"},"mgrId":1,"mgrName":"Tom"},結(jié)果也很令人滿意。

4.最后提供一個 fastjson 的工具類,開發(fā)時可以直接使用,供大家參考

package qi.ssh.utils;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class FastJsonUtil {
 
 /**
 * 將對象轉(zhuǎn)成json串
 * @param object
 * @return
 */
 public static String toJSONString(Object object){
 //DisableCircularReferenceDetect來禁止循環(huán)引用檢測
 return JSON.toJSONString(object,SerializerFeature.DisableCircularReferenceDetect);
 }
 
 //輸出json
 public static void write_json(HttpServletResponse response,String jsonString)
 {
 response.setContentType("application/json;utf-8");
 response.setCharacterEncoding("UTF-8");
 try {
  response.getWriter().print(jsonString);
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } 
 }
 /**
 * ajax提交后回調(diào)的json字符串
 * @return
 */
 public static String ajaxResult(boolean success,String message)
 {
 Map map=new HashMap();
 map.put("success", success);//是否成功
 map.put("message", message);//文本消息
 String json= JSON.toJSONString(map); 
 return json;
 }
 

 /**
 * JSON串自動加前綴
 * @param json 原json字符串
 * @param prefix 前綴
 * @return 加前綴后的字符串
 */

 public static String JsonFormatterAddPrefix(String json,String prefix,Map<String,Object> newmap)
 {
 if(newmap == null){
  newmap = new HashMap();
 }
 Map<String,Object> map = (Map) JSON.parse(json);

 for(String key:map.keySet())
 {
  Object object=map.get(key);
  if(isEntity(object)){
  String jsonString = JSON.toJSONString(object);
  JsonFormatterAddPrefix(jsonString,prefix+key+".",newmap);
  
  }else{
  newmap.put(prefix+key, object);
  }
  
 }
 return JSON.toJSONString(newmap); 
 }
 /**
 * 判斷某對象是不是實(shí)體
 * @param object
 * @return
 */
 private static boolean isEntity(Object object)
 {
 if(object instanceof String )
 {
  return false;
 }
 if(object instanceof Integer )
 {
  return false;
 }
 if(object instanceof Long )
 {
  return false;
 }
 if(object instanceof java.math.BigDecimal )
 {
  return false;
 }
 if(object instanceof Date )
 {
  return false;
 }
 if(object instanceof java.util.Collection )
 {
  return false;
 }
 return true;
 
 }
}

二、Jackson

1.同樣也需要導(dǎo)入 jar 包,Jackson 導(dǎo)入的 jar 包有三個

如何構(gòu)建一個JSON字符串

具體使用也通過一個小例子說明:

package com.software.jackson;

import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Customer {

 private int id;

 private String name;

 public Customer(int id, String name) {
  super();
  this.id = id;
  this.name = name;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 
 public String getCity(){
  return "BeiJing";
 }
 
 @JsonIgnore
 public String getSchool(){
  return "School";
 }
 
 public static void main(String[] args) throws JsonProcessingException {
  //創(chuàng)建ObjectMapper對象
  ObjectMapper mapper = new ObjectMapper();
  
  Customer customer = new Customer(1, "Tom");
  List<Customer> lists = Arrays.asList(customer, new Customer(2, "Bob"));
  
  //調(diào)用 ObjectMapper 的 writeValueAsString(xxx) 方法,把一個對象或幾個傳入,轉(zhuǎn)為一個 JSON 字符串
  String jsonStr = mapper.writeValueAsString(lists);
  System.out.println(jsonStr);
  
 }

}

定義了一個 Customer 類,38 行和 43 行定義了兩個額外的 get 方法并直接賦值,main 方法中創(chuàng)建 ObjectMapper的對象,調(diào)用其 writeValueAsString()方法,傳入單個對象或?qū)ο蟮募?,便會返回對?yīng)的 JSON 字符串,打印結(jié)果為:[{"id":1,"name":"Tom","city":"BeiJing"},{"id":2,"name":"Bob","city":"BeiJing"}],大家可能會發(fā)現(xiàn),我們 43 行定義的 getSchool() 方法中的 School 沒有被打印出,這是因為我們在此方法上添加了 @JsonIgnore注解,添加了此注解,在構(gòu)造 JSON 字符串時便忽略此屬性,細(xì)想一下 ,此注解添加到 get 方法上,這也說明 Jackson 構(gòu)造 JSON 字符串時基于 getter 方法的。

2.與之前一樣,我們想看一看 Jackson 有沒有禁止循環(huán)的引用,類似的代碼:

  @Test
 public void test2() throws JsonProcessingException {
  List<Customer> lists = new ArrayList<>();

  Customer customer = new Customer();
  customer.setId(1);
  customer.setCustName("Tom");
  customer.setAddress("BeiJing");

  lists.add(customer);
  lists.add(customer);
  
  ObjectMapper mapper = new ObjectMapper();
  String jsonStr = mapper.writeValueAsString(lists);
  System.out.println(jsonStr);
 }

來看一下輸出結(jié)果:[{"id":1,"custName":"Tom","address":"BeiJing"},{"id":1,"custName":"Tom","address":"BeiJing"}],結(jié)果顯而易見。

3.我們再來看一看如果像 Fastjson 中測試的 Department 和 Manager 雙向一對一映射的例子,Jackson 會表現(xiàn)的怎么樣:

  @Test
 public void test1() throws JsonProcessingException {
  Manager mgr = new Manager();
  mgr.setMgrId(1);
  mgr.setMgrName("Tom");
  
  Department dept = new Department();
  dept.setDeptId(2);
  dept.setDeptName("DEV");
  
  mgr.setDept(dept);
  dept.setManager(mgr);
  
  ObjectMapper mapper = new ObjectMapper();
  String jsonStr = mapper.writeValueAsString(dept);
  System.out.println(jsonStr);
 }

直接運(yùn)行還是會出相同的異常 Caused by: java.lang.StackOverflowError,我們的思路與測試 Fastjson 一樣,為 Department 中的 Manager 引用添加 @JsonIgnore 注解,異常解決了,但打印結(jié)果是很滿意,結(jié)果為:{"deptId":2,"deptName":"DEV"} ,遠(yuǎn)不如 Fastjson 的輸出結(jié)果。由此可以看出 Fastjson 功能之強(qiáng)大。

三、Google Gson

1.看看如何使用:jar 包呢只需要一個 gson-2.2.4.jar ,普通對象與集合轉(zhuǎn)為 JSON 沒有什么可說的,簡單演示一下將 List 集合轉(zhuǎn)為 JSON 字符串吧,直接 new 出 Gson 的對象,調(diào)用其 toJson() 方法傳入需要轉(zhuǎn)換的對象即可。

  @Test
 public void test2() {
  List<Customer> lists = new ArrayList<>();

  Customer customer = new Customer();
  customer.setId(1);
  customer.setCustName("Tom");
  customer.setAddress("BeiJing");

  lists.add(customer);

  Customer customer2 = new Customer();
  customer2.setId(1);
  customer2.setCustName("Bob");
  customer2.setAddress("ShangHai");

  lists.add(customer2);

  Gson gson = new Gson();
  String jsonStr = gson.toJson(lists);
  System.out.println(jsonStr);
 }

打印結(jié)果:[{"address":"BeiJing","custName":"Tom","id":1},{"address":"ShangHai","custName":"Bob","id":1}]

2. 那有沒有禁止循環(huán)引用呢?

  @Test
 public void test3() {
  List<Customer> lists = new ArrayList<>();

  Customer customer = new Customer();
  customer.setId(1);
  customer.setCustName("Tom");
  customer.setAddress("BeiJing");

  lists.add(customer);
  lists.add(customer);
  
  Gson gson = new Gson();
  String jsonStr = gson.toJson(lists);
  System.out.println(jsonStr);

 }

輸出結(jié)果:[{"id":1,"custName":"Tom","address":"BeiJing"},{"id":1,"custName":"Tom","address":"BeiJing"}],顯而易見是沒有的。

3.若有雙向一對一的關(guān)聯(lián)關(guān)系映射的話,Google Gson 也是會有死循環(huán)問題造成 java.lang.StackOverflowError 異常,但是 Gson 并沒有為我們提供一個注解,要解決此問題LZ提供一個解決方案的思路,Google Gson 使用的是 ExclusionStrategy 策略進(jìn)行某個字段或某個域的序列化,可以通過此接口自定義一個 注解來解決此問題。但是建議大家如果涉及到雙向關(guān)聯(lián)關(guān)系的對象轉(zhuǎn)換為 JSON 的需求是,使用 Fastjson。

四、三種方式的簡單比較

LZ 從以下幾個方面來比較構(gòu)造 JSON 字符串的三種方式:

1. jar 包方面:顯然是 Fastjson 和 Google Gson 勝出,Jackson 需要加入 3 個 jar 包。

2. 簡單對象或集合轉(zhuǎn)為 JSON:若是普通的簡單對象或集合進(jìn)行轉(zhuǎn)換,可能 Jackson 和 Google Gson 要勝出一些了,起碼構(gòu)造比較方便。

3. 涉及到雙向關(guān)聯(lián)關(guān)系的轉(zhuǎn)換:毫無疑問阿里巴巴的 Fastjson 將勝出。

建議大家在實(shí)際的開發(fā)中根據(jù)自己的需求合理選擇某一方式。

以上就是如何構(gòu)建一個JSON字符串,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享名稱:如何構(gòu)建一個JSON字符串
本文網(wǎng)址:http://www.rwnh.cn/article10/jeesdo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗網(wǎng)站改版、App設(shè)計、營銷型網(wǎng)站建設(shè)、軟件開發(fā)、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)
平顺县| 雅安市| 海宁市| 洛川县| 英吉沙县| 吉林省| 双柏县| 阿拉善右旗| 句容市| 弋阳县| 南部县| 德兴市| 广汉市| 格尔木市| 新竹市| 斗六市| 宁河县| 鄢陵县| 青阳县| 彭阳县| 九寨沟县| 汪清县| 阳信县| 额尔古纳市| 奉化市| 平和县| 叶城县| 滕州市| 从化市| 房产| 天津市| 桃园市| 左贡县| 北流市| 资讯| 加查县| 仙居县| 虎林市| 鸡东县| 绥江县| 和田县|