Gson、FastJson、Jackson、json-lib對(duì)比總結(jié)

一 、各個(gè)JSON技術(shù)的簡(jiǎn)介和優(yōu)劣

  1. json-lib

json-lib最開(kāi)始的也是應(yīng)用最廣泛的json解析工具,json-lib 不好的地方確實(shí)是依賴(lài)于很多第三方包,
包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
對(duì)于復(fù)雜類(lèi)型的轉(zhuǎn)換,json-lib對(duì)于json轉(zhuǎn)換成bean還有缺陷,比如一個(gè)類(lèi)里面會(huì)出現(xiàn)另一個(gè)類(lèi)的list或者map集合,json-lib從json到bean的轉(zhuǎn)換就會(huì)出現(xiàn)問(wèn)題。
json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求。

  1. 開(kāi)源的Jackson

相比json-lib框架,Jackson所依賴(lài)的jar包較少,簡(jiǎn)單易用并且性能也要相對(duì)高些。
而且Jackson社區(qū)相對(duì)比較活躍,更新速度也比較快。
Jackson對(duì)于復(fù)雜類(lèi)型的json轉(zhuǎn)換bean會(huì)出現(xiàn)問(wèn)題,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問(wèn)題。
Jackson對(duì)于復(fù)雜類(lèi)型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式

  1. Google的Gson

Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來(lái),
但自從在2008年五月公開(kāi)發(fā)布第一版后已被許多公司或用戶應(yīng)用。
Gson的應(yīng)用主要為toJson與fromJson兩個(gè)轉(zhuǎn)換函數(shù),無(wú)依賴(lài),不需要例外額外的jar,能夠直接跑在JDK上。
而在使用這種對(duì)象轉(zhuǎn)換之前需先創(chuàng)建好對(duì)象的類(lèi)型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對(duì)應(yīng)的對(duì)象。
類(lèi)里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類(lèi)型的json到bean或bean到j(luò)son的轉(zhuǎn)換,是JSON解析的神器。
Gson在功能上面無(wú)可挑剔,但是性能上面比FastJson有所差距。

  1. 阿里巴巴的FastJson

Fastjson是一個(gè)Java語(yǔ)言編寫(xiě)的高性能的JSON處理器,由阿里巴巴公司開(kāi)發(fā)。
無(wú)依賴(lài),不需要例外額外的jar,能夠直接跑在JDK上。
FastJson在復(fù)雜類(lèi)型的Bean轉(zhuǎn)換Json上會(huì)出現(xiàn)一些問(wèn)題,可能會(huì)出現(xiàn)引用的類(lèi)型,導(dǎo)致Json轉(zhuǎn)換出錯(cuò),需要制定引用。
FastJson采用獨(dú)創(chuàng)的算法,將parse的速度提升到極致,超過(guò)所有json庫(kù)。

綜上4種Json技術(shù)的比較:在項(xiàng)目選型的時(shí)候可以使用Google的Gson和阿里巴巴的FastJson兩種并行使用,
如果只是功能要求,沒(méi)有性能要求,可以使用google的Gson,
如果有性能上面的要求可以使用Gson將bean轉(zhuǎn)換json確保數(shù)據(jù)的正確,使用FastJson將Json轉(zhuǎn)換Bean

二、Google的Gson包的使用簡(jiǎn)介。

2.1 主要類(lèi)介紹
Gson類(lèi):解析json的最基礎(chǔ)的工具類(lèi)
JsonParser類(lèi):解析器來(lái)解析JSON到JsonElements的解析樹(shù)
JsonElement類(lèi):一個(gè)類(lèi)代表的JSON元素
JsonObject類(lèi):JSON對(duì)象類(lèi)型
JsonArray類(lèi):JsonObject數(shù)組
TypeToken類(lèi):用于創(chuàng)建type,比如泛型List<?>

2.2 maven依賴(lài)

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.0</version>
    </dependency>

2.3 bean轉(zhuǎn)換json

Gson gson = new Gson();
String json = gson.toJson(obj);
//obj是對(duì)象

2.4 json轉(zhuǎn)換bean

Gson gson = new Gson();
String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = gson.fromJson(json, Book.class);

2.5 json轉(zhuǎn)換復(fù)雜的bean,比如List,Set
將json轉(zhuǎn)換成復(fù)雜類(lèi)型的bean,需要使用TypeToken

Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = gson.fromJson(json,new TypeToken<LIST>() {}.getType());
//將json轉(zhuǎn)換成Set
Set set = gson.fromJson(json,new TypeToken<SET>() {}.getType());

2.6 通過(guò)json對(duì)象直接操作json以及一些json的工具

a) 格式化Json

String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(json);
json = gson.toJson(je);

b) 判斷字符串是否是json,通過(guò)捕捉的異常來(lái)判斷是否是json

String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
boolean jsonFlag;
try {
new JsonParser().parse(str).getAsJsonObject();
jsonFlag = true;
} catch (Exception e) {
jsonFlag = false;
}

c) 從json串中獲取屬性

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'id';
String propertyValue = "";
try {
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
propertyValue = jsonObj.get(propertyName).toString();
} catch (Exception e) {
propertyValue = null;
}

d) 除去json中的某個(gè)屬性

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'id';
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
json = jsonObj.toString();

e) 向json中添加屬性

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'desc';
Object propertyValue = "json各種技術(shù)的調(diào)研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();

f) 修改json中的屬性

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'name';
Object propertyValue = "json各種技術(shù)的調(diào)研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();

g) 判斷json中是否有屬性

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
String propertyName = 'name';
boolean isContains = false ;
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
isContains = jsonObj.has(propertyName);

h) json中日期格式的處理

GsonBuilder builder = new GsonBuilder();
builder.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Gson gson = builder.create();

然后使用gson對(duì)象進(jìn)行json的處理,如果出現(xiàn)日期Date類(lèi)的對(duì)象,就會(huì)按照設(shè)置的格式進(jìn)行處理
i) json中對(duì)于Html的轉(zhuǎn)義

Gson gson = new Gson();

這種對(duì)象默認(rèn)對(duì)Html進(jìn)行轉(zhuǎn)義,如果不想轉(zhuǎn)義使用下面的方法

GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
Gson gson = builder.create();

三、阿里巴巴的FastJson包的使用簡(jiǎn)介。

3.1 maven依賴(lài)

    <!-- FastJson將Json轉(zhuǎn)換Bean -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.46</version>
    </dependency>

3.2 基礎(chǔ)轉(zhuǎn)換類(lèi)
同上
3.3 bean轉(zhuǎn)換json
將對(duì)象轉(zhuǎn)換成格式化的json

JSON.toJSONString(obj,true);

將對(duì)象轉(zhuǎn)換成非格式化的json

JSON.toJSONString(obj,false);

obj設(shè)計(jì)對(duì)象
對(duì)于復(fù)雜類(lèi)型的轉(zhuǎn)換,對(duì)于重復(fù)的引用在轉(zhuǎn)成json串后在json串中出現(xiàn)引用的字符,比如 ref":"[0].books[1]

Student stu = new Student();
Set books= new HashSet();
Book book = new Book();
books.add(book);
stu.setBooks(books);
List list = new ArrayList();
for(int i=0;i<5;i++)
list.add(stu);
String json = JSON.toJSONString(list,true);

3.4 json轉(zhuǎn)換bean

String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = JSON.parseObject(json, Book.class);

3.5 json轉(zhuǎn)換復(fù)雜的bean,比如List,Map

String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){});
//將json轉(zhuǎn)換成Set
Set set = JSON.parseObject(json,new TypeReference<HASHSET>(){});

3.6 通過(guò)json對(duì)象直接操作json
a) 從json串中獲取屬性

String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
propertyValue = obj.get(propertyName));

b) 除去json中的某個(gè)屬性

String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
propertyValue = set.remove(propertyName);
json = obj.toString();

c) 向json中添加屬性

String propertyName = 'desc';
Object propertyValue = "json的玩意兒";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();

d) 修改json中的屬性

String propertyName = 'name';
Object propertyValue = "json的玩意兒";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
if(set.contains(propertyName))
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();

e) 判斷json中是否有屬性

String propertyName = 'name';
boolean isContain = false;
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
isContain = set.contains(propertyName);

f) json中日期格式的處理

Object obj = new Date();
String json = JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss.SSS");

使用JSON.toJSONStringWithDateFormat,該方法可以使用設(shè)置的日期格式對(duì)日期進(jìn)行轉(zhuǎn)換

四、json-lib包的使用簡(jiǎn)介。

4.1 maven依賴(lài)

//json-lib 為官方api,只需java jdk >jdk15即可。需要依賴(lài)一下jar包
      <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.0</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- slf4j日志依賴(lài) -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

4.2 基礎(chǔ)轉(zhuǎn)換類(lèi)
同上
4.3 bean轉(zhuǎn)換json
a)將類(lèi)轉(zhuǎn)換成Json,obj是普通的對(duì)象,不是List,Map的對(duì)象

String json = JSONObject.fromObject(obj).toString();

b) 將List,Map轉(zhuǎn)換成Json

String json = JSONArray.fromObject(list).toString();
String json = JSONArray.fromObject(map).toString();

4.4 json轉(zhuǎn)換bean

String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject jsonObj = JSONObject.fromObject(json);
Book book = (Book)JSONObject.toBean(jsonObj,Book.class);

4.5 json轉(zhuǎn)換List,對(duì)于復(fù)雜類(lèi)型的轉(zhuǎn)換會(huì)出現(xiàn)問(wèn)題

String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"Java技術(shù)\"}]";
JSONArray jsonArray = JSONArray.fromObject(json);
JSONObject jsonObject;
T bean;
int size = jsonArray.size();
List list = new ArrayList(size);
for (int i = 0; i < size; i++) {
jsonObject = jsonArray.getJSONObject(i);
bean = (T) JSONObject.toBean(jsonObject, beanClass);
list.add(bean);
}

4.6 json轉(zhuǎn)換Map

String jsonString = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
JSONObject jsonObject = JSONObject.fromObject(jsonString);
Iterator keyIter = jsonObject.keys();
String key;
Object value;
Map valueMap = new HashMap();
while (keyIter.hasNext()) {
key = (String) keyIter.next();
value = jsonObject.get(key).toString();
valueMap.put(key, value);
}

4.7 json對(duì)于日期的操作比較復(fù)雜,需要使用JsonConfig,比Gson和FastJson要麻煩多了
創(chuàng)建轉(zhuǎn)換的接口實(shí)現(xiàn)類(lèi),轉(zhuǎn)換成指定格式的日期

class DateJsonValueProcessor implements JsonValueProcessor{
public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; 
private DateFormat dateFormat; 
public DateJsonValueProcessor(String datePattern) { 
try { 
dateFormat = new SimpleDateFormat(datePattern); 
} catch (Exception ex) { 
dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN); 
} 
} 
public Object processArrayValue(Object value, JsonConfig jsonConfig) { 
return process(value); 
} 
public Object processObjectValue(String key, Object value, 
JsonConfig jsonConfig) { 
return process(value); 
} 
private Object process(Object value) { 
return dateFormat.format[1];
Map<STRING,DATE> birthDays = new HashMap<STRING,DATE>();
birthDays.put("WolfKing",new Date());
JSONObject jsonObject = JSONObject.fromObject(birthDays, jsonConfig);
String json = jsonObject.toString();
System.out.println(json);
}
}

4.8 JsonObject 對(duì)于json的操作和處理
a) 從json串中獲取屬性

String jsonString = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
Object key = "name";
Object value = null;
JSONObject jsonObject = JSONObject.fromObject(jsonString);
value = jsonObject.get(key);
jsonString = jsonObject.toString();

b) 除去json中的某個(gè)屬性

String jsonString = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
Object key = "name";
Object value = null;
JSONObject jsonObject = JSONObject.fromObject(jsonString);
value = jsonObject.remove(key);
jsonString = jsonObject.toString();

c) 向json中添加和修改屬性,有則修改,無(wú)則添加

String jsonString = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
Object key = "desc";
Object value = "json的好東西";
JSONObject jsonObject = JSONObject.fromObject(jsonString);
jsonObject.put(key,value);
jsonString = jsonObject.toString();

d) 判斷json中是否有屬性

String jsonString = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
boolean containFlag = false;
Object key = "desc";
JSONObject jsonObject = JSONObject.fromObject(jsonString);
containFlag = jsonObject.containsKey(key);

五、注意事項(xiàng)

fastjsonjackson 在把對(duì)象序列化成json字符串的時(shí)候,是通過(guò)反射遍歷出該類(lèi)中的所有g(shù)etter方法;
Gson 是通過(guò)反射遍歷該類(lèi)中的所有屬性。
所以,在定義POJO中的布爾類(lèi)型的變量時(shí),不要使用isSuccess這種形式,而要直接使用success

六、示例

以上為網(wǎng)上摘抄,以下為實(shí)際項(xiàng)目中使用結(jié)果。
實(shí)體類(lèi)為BaseVO.java:

package com.zr.workflow.activiti.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

import com.alibaba.fastjson.JSONObject;
import com.zr.workflow.activiti.util.DateFormatUtil;


public class BaseVO implements Serializable {

    private static final long serialVersionUID = 6165121688276341503L;
    
    protected int id;

    protected String createId;// 創(chuàng)建人
    protected String createName;
    protected String createTime;// 流程的創(chuàng)建時(shí)間
    protected String endTime;// 流程的結(jié)束時(shí)間
    protected String reason;
    protected String owner;// 擁有者
    // 申請(qǐng)的標(biāo)題
    protected String title;
    // 業(yè)務(wù)類(lèi)型
    protected String businessType;
    protected String deploymentId;// 流程部署id
    protected String processInstanceId;// 流程實(shí)例id
    protected String deleteReason;// 刪除原因
    protected String handledTaskId;// 已處理任務(wù)id
    protected String handledTaskDefinitionKey;// 已處理節(jié)點(diǎn)
    protected String handledTaskName;// 已處理節(jié)點(diǎn)名稱(chēng)
    protected String assignedId;// 已處理節(jié)點(diǎn)的受理人
    protected String assignedName;// 已處理節(jié)點(diǎn)的受理人
    protected String toHandleTaskId;// 當(dāng)前節(jié)點(diǎn)的任務(wù)id
    protected String taskDefinitionKey;// 當(dāng)前節(jié)點(diǎn)key
    protected String toHandleTaskName;// 當(dāng)前節(jié)點(diǎn)點(diǎn)名
    protected String assign;// 當(dāng)前節(jié)點(diǎn)的受理人
    protected String assignName;// 當(dāng)前節(jié)點(diǎn)的受理人
    protected String description;// 描述
    protected String businessKey;// 對(duì)應(yīng)業(yè)務(wù)的id
    protected String startTime;// 任務(wù)的開(kāi)始時(shí)間
    protected String operateTime;// 任務(wù)的結(jié)束時(shí)間(處理時(shí)間)
    protected String claimTime;// 任務(wù)的簽收時(shí)間
    protected boolean isEnd;// 流程是否結(jié)束
    protected boolean isSuspended;// 是否掛起
    protected String processDefinitionId;// 流程定義id
    protected String processDefinitionName;// 流程名稱(chēng)
    protected String processDefinitionKey;// 流程key,任務(wù)跳轉(zhuǎn)用
    protected String processStatus;// 流程狀態(tài):待審批、審批通過(guò)、審批退回、歸檔、結(jié)束
    protected int version;// 流程版本號(hào)
    protected JSONObject contentInfo;// 流程的業(yè)務(wù)相關(guān)
    private String candidate_ids;//下一節(jié)點(diǎn)執(zhí)行人,多個(gè)用逗號(hào)隔開(kāi)
    private String candidate_names;//下一節(jié)點(diǎn)執(zhí)行人,多個(gè)用逗號(hào)隔開(kāi)

    private List<CommentVO> comments;//評(píng)論列表
    
    public int getId() {
        return id;
    }

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

    public String getCreateId() {
        return createId;
    }

    public void setCreateId(String createId) {
        this.createId = createId;
    }

    public String getCreateName() {
        return createName;
    }

    public void setCreateName(String createName) {
        this.createName = createName;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public String getOwner() {
        if (this.owner == null) {
            this.owner = (null == task) ? "" : task.getOwner();
        }
        return owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getEndTime() {
        if (this.endTime == null) {
            Date endDate = (null == historicProcessInstance) ? null : historicProcessInstance.getEndTime();
            endTime = endDate == null ? "" : DateFormatUtil.format(endDate);
        }
        return endTime;
    }

    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBusinessType() {
        return businessType;
    }

    public void setBusinessType(String businessType) {
        this.businessType = businessType;
    }

    public String getDeploymentId() {
        if (this.deploymentId == null) {
            this.deploymentId = (null == processInstance) ? "" : processInstance.getDeploymentId();
        }
        return deploymentId;
    }

    public void setDeploymentId(String deploymentId) {
        this.deploymentId = deploymentId;
    }

    public String getProcessInstanceId() {
        if (this.processInstanceId == null || "".equals(this.processInstanceId)) {
            if (historicTaskInstance != null) {
                this.processInstanceId = historicTaskInstance.getProcessInstanceId();
            } else if (processInstance != null) {
                this.processInstanceId = processInstance.getId();
            } else {
                this.processInstanceId = (null == historicProcessInstance) ? "" : historicProcessInstance.getId();
            }
        }
        return processInstanceId;
    }

    public void setProcessInstanceId(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    public String getDeleteReason() {
        if (this.deleteReason == null) {
            this.deleteReason = (null == historicTaskInstance) ? "" : historicTaskInstance.getDeleteReason();
        }
        return deleteReason;
    }

    public void setDeleteReason(String deleteReason) {
        this.deleteReason = deleteReason;
    }

    public String getHandledTaskId() {
        if (this.handledTaskId == null) {
            this.handledTaskId = (null == historicTaskInstance) ? "" : historicTaskInstance.getId();
        }
        return handledTaskId;
    }

    public void setHandledTaskId(String handledTaskId) {
        this.handledTaskId = handledTaskId;
    }

    public String getHandledTaskDefinitionKey() {
        if (this.handledTaskDefinitionKey == null) {
            this.handledTaskDefinitionKey = (null == historicTaskInstance) ? ""
                    : historicTaskInstance.getTaskDefinitionKey();
        }
        return handledTaskDefinitionKey;
    }

    public void setHandledTaskDefinitionKey(String handledTaskDefinitionKey) {
        this.handledTaskDefinitionKey = handledTaskDefinitionKey;
    }

    public String getHandledTaskName() {
        if (this.handledTaskName == null) {
            this.handledTaskName = (null == historicTaskInstance) ? "" : historicTaskInstance.getName();
        }
        return handledTaskName;
    }

    public void setHandledTaskName(String handledTaskName) {
        this.handledTaskName = handledTaskName;
    }

    public String getAssignedId() {
        if (this.assignedId == null) {
            this.assignedId = (null == historicTaskInstance) ? "" : historicTaskInstance.getAssignee();
        }
        return assignedId;
    }

    public void setAssignedId(String assignedId) {
        this.assignedId = assignedId;
    }

    public String getAssignedName() {
        return assignedName;
    }

    public void setAssignedName(String assignedName) {
        this.assignedName = assignedName;
    }

    public String getToHandleTaskId() {

        if (this.toHandleTaskId == null) {
            this.toHandleTaskId = (null == task) ? "" : task.getId();
        }
        return toHandleTaskId;
    }

    public void setToHandleTaskId(String toHandleTaskId) {
        this.toHandleTaskId = toHandleTaskId;
    }

    public String getTaskDefinitionKey() {
        if (this.taskDefinitionKey == null) {
            this.taskDefinitionKey = (null == task) ? "" : task.getTaskDefinitionKey();
        }
        return taskDefinitionKey;
    }

    public void setTaskDefinitionKey(String taskDefinitionKey) {
        this.taskDefinitionKey = taskDefinitionKey;
    }

    public String getToHandleTaskName() {
        if (this.toHandleTaskName == null) {
            this.toHandleTaskName = (null == task) ? "" : task.getName();
        }
        return toHandleTaskName;
    }

    public void setToHandleTaskName(String toHandleTaskName) {
        this.toHandleTaskName = toHandleTaskName;
    }

    public String getAssign() {
        if (this.assign == null) {
            this.assign = (null == task) ? "" : task.getAssignee();
        }
        return assign;
    }

    public void setAssign(String assign) {
        this.assign = assign;
    }

    public String getAssignName() {
        return assignName;
    }

    public void setAssignName(String assignName) {
        this.assignName = assignName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getBusinessKey() {
        return businessKey;
    }

    public void setBusinessKey(String businessKey) {
        this.businessKey = businessKey;
    }

    public String getStartTime() {
        if (this.startTime == null) {
            Date startDate = null;
            if (historicTaskInstance != null) {
                startDate = historicTaskInstance.getStartTime();
            } else {
                startDate = (null == historicProcessInstance) ? null : historicProcessInstance.getStartTime();
            }
            startTime = startDate == null ? "" : DateFormatUtil.format(startDate);
        }
        return startTime;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    public String getOperateTime() {
        if (this.operateTime == null) {
            Date operateDate = (null == historicTaskInstance) ? null : historicTaskInstance.getEndTime();
            operateTime = operateDate == null ? "" : DateFormatUtil.format(operateDate);
        }
        return operateTime;
    }

    public void setOperateTime(String operateTime) {
        this.operateTime = endTime;
    }

    public String getClaimTime() {
        if (this.claimTime == null) {
            Date claimDate = (null == historicTaskInstance) ? null : historicTaskInstance.getClaimTime();
            claimTime = claimDate == null ? "" : DateFormatUtil.format(claimDate);
        }
        return claimTime;
    }

    public void setClaimTime(String claimTime) {
        this.claimTime = claimTime;
    }

    public boolean isEnd() {
        return isEnd;
    }

    public void setEnd(boolean isEnd) {
        this.isEnd = isEnd;
    }

    public boolean isSuspended() {
        this.isSuspended = (null == processInstance) ? isSuspended : processInstance.isSuspended();
        return isSuspended;
    }

    public void setSuspended(boolean isSuspended) {
        this.isSuspended = isSuspended;
    }

    public String getProcessDefinitionId() {
        if (processDefinitionId == null) {
            if (processInstance != null) {
                this.processDefinitionId = processInstance.getProcessDefinitionId();
            } else {
                this.processDefinitionId = (null == historicProcessInstance) ? ""
                        : historicProcessInstance.getProcessDefinitionId();

            }
        }
        return processDefinitionId;
    }

    public void setProcessDefinitionId(String processDefinitionId) {
        this.processDefinitionId = processDefinitionId;
    }

    public String getProcessDefinitionName() {
        if (processDefinitionName == null) {
            this.processDefinitionName = (null == processDefinition) ? "" : processDefinition.getName();
        }
        return processDefinitionName;
    }

    public void setProcessDefinitionName(String processDefinitionName) {
        this.processDefinitionName = processDefinitionName;
    }

    public String getProcessDefinitionKey() {
        if (processDefinitionKey == null) {
            this.processDefinitionKey = (null == processDefinition) ? "" : processDefinition.getKey();
        }
        return processDefinitionKey;
    }

    public void setProcessDefinitionKey(String processDefinitionKey) {
        this.processDefinitionKey = processDefinitionKey;
    }

    public String getProcessStatus() {
        return processStatus;
    }

    public void setProcessStatus(String processStatus) {
        this.processStatus = processStatus;
    }

    public int getVersion() {
        if(version <= 0) {
            version = (null == processDefinition) ? 0 : processDefinition.getVersion();
        }
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public JSONObject getContentInfo() {
        return contentInfo;
    }

    public void setContentInfo(JSONObject contentInfo) {
        this.contentInfo = contentInfo;
    }

    public String getCandidate_ids() {
        return null == candidate_ids ? null : candidate_ids.replaceAll("\\[", "").replaceAll("\"", "").replaceAll("\\]", "");
    }
    
    public void setCandidate_ids(String candidate_ids) {
        this.candidate_ids = candidate_ids;
    }

    public String getCandidate_names() {
        return null == candidate_names ? null : candidate_names.replaceAll("\\[", "").replaceAll("\"", "").replaceAll("\\]", "");
    }
    
    public void setCandidate_names(String candidate_names) {
        this.candidate_names = candidate_names;
    }

    public void setComments(List<CommentVO> commentList) {
        this.comments = commentList;
    }

    public List<CommentVO> getComments(){
        return comments;
    }

    // 流程任務(wù)
    public Task task;

    // 運(yùn)行中的流程實(shí)例
    protected ProcessInstance processInstance;

    // 歷史的流程實(shí)例
    protected HistoricProcessInstance historicProcessInstance;

    // 歷史任務(wù)
    protected HistoricTaskInstance historicTaskInstance;

    // 流程定義
    protected ProcessDefinition processDefinition;


    public void setTask(Task task) {
        this.task = task;
    }

    public void setProcessInstance(ProcessInstance processInstance) {
        this.processInstance = processInstance;
    }

    public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
        this.historicProcessInstance = historicProcessInstance;
    }

    public void setProcessDefinition(ProcessDefinition processDefinition) {
        this.processDefinition = processDefinition;
    }

    public void setHistoricTaskInstance(HistoricTaskInstance historicTaskInstance) {
        this.historicTaskInstance = historicTaskInstance;
    }

}

用Gson 將該實(shí)體類(lèi)轉(zhuǎn)成json時(shí)報(bào)以下異常:

java.lang.IllegalArgumentException: class org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity declares multiple JSON fields named key
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:170)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
    at com.google.gson.Gson.getAdapter(Gson.java:423)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:115)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:164)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
    at com.google.gson.Gson.getAdapter(Gson.java:423)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.java:53)
    at com.google.gson.Gson.getAdapter(Gson.java:423)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:115)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:164)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
    at com.google.gson.Gson.getAdapter(Gson.java:423)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:56)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:125)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:243)
    at com.google.gson.internal.bind.ObjectTypeAdapter.write(ObjectTypeAdapter.java:107)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:208)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:145)
    at com.google.gson.Gson.toJson(Gson.java:669)
    at com.google.gson.Gson.toJson(Gson.java:648)
    at com.google.gson.Gson.toJson(Gson.java:603)
    at com.google.gson.Gson.toJson(Gson.java:583)
    at net.northking.activiti.util.JsonUtil.toJson(JsonUtil.java:47)

原因是:子類(lèi)和父類(lèi)有相同的字段屬性;
解決方法:
(1)重命名重復(fù)字段。因?yàn)橹貜?fù)的字段在第三方包中,所以該方法在本例中不可行。
(2)將實(shí)體類(lèi)中需要打印的字段加上注解@Expose,(本例將該類(lèi)所有有g(shù)et方法的屬性都加上了) :

    @Expose
    protected int id;
    @Expose
    protected String createId;// 創(chuàng)建人
    @Expose
    protected String createName;

新建gson:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(obj);

excludeFieldsWithoutExposeAnnotation排除掉沒(méi)有Expose注解的屬性。

或者在不需要解析的字段前面加上transient:


    // 流程任務(wù)
    public transient Task task;

    // 運(yùn)行中的流程實(shí)例
    protected transient ProcessInstance processInstance;

    // 歷史的流程實(shí)例
    protected transient HistoricProcessInstance historicProcessInstance;

    // 歷史任務(wù)
    protected transient HistoricTaskInstance historicTaskInstance;

    // 流程定義
    protected transient ProcessDefinition processDefinition;

用該方式,沒(méi)有報(bào)異常了,解析結(jié)果(加注解@Expose或加transient)如下:

{
    "data": [{
        "id": 0,
        "createId": "admin",
        "createName": "系統(tǒng)管理員",
        "createTime": "2019-04-11 17:01:46",
        "reason": "",
        "title": "2019-04-01至2019-04-07工時(shí)填報(bào)",
        "processInstanceId": "70013",
        "handledTaskId": "70023",
        "handledTaskDefinitionKey": "outsourcerApply",
        "handledTaskName": "外包人員申請(qǐng)",
        "assignedId": "admin",
        "assignedName": "系統(tǒng)管理員",
        "toHandleTaskId": "70039",
        "taskDefinitionKey": "projectManagerAudit",
        "toHandleTaskName": "項(xiàng)目經(jīng)理審批",
        "assign": "215",
        "assignName": "郭俊杰",
        "description": "您提出2019-04-01至2019-04-07工時(shí)填報(bào)",
        "businessKey": "monthlyreportForProjectProcess:admin:20190401:20190407",
        "isEnd": false,
        "isSuspended": false,
        "processDefinitionId": "monthlyreportForProjectProcess:1:70012",
        "processDefinitionName": "工時(shí)填報(bào)(項(xiàng)目外包/行內(nèi)人員)",
        "processDefinitionKey": "monthlyreportForProjectProcess",
        "processStatus": "WAITING_FOR_APPROVAL",
        "version": 0,
        "contentInfo": {
            "contentInfoId": "39a14c350fa64a3ca26a50b4531307c6",
            "ssoUser": "1",
            "reportId": "39a14c350fa64a3ca26a50b4531307c6",
            "createTime": "2019-04-11",
            "reportRemark": "",
            "reportStatus": "1",
            "project": [{
                "hoursTime": "5",
                "percentTime": "0",
                "managerId": "215",
                "projectName": "其他",
                "projectId": "other"
            }],
            "startTime": "2019-04-01",
            "endTime": "2019-04-07",
            "flowFlag": "create",
            "userId": "admin"
        },
        "candidate_ids": "",
        "candidate_names": "",
        "comments": [{
            "id": "70024",
            "userId": "admin",
            "userName": "系統(tǒng)管理員",
            "content": "發(fā)起申請(qǐng)",
            "taskId": "70023",
            "processInstanceId": "70013",
            "time": "2019-04-11 17:01:47",
            "nextAssign": "215",
            "nextAssignName": "郭俊杰"
        }]
    }],
    "type": "success"
}

但從結(jié)果來(lái)看,那些直接調(diào)用第三方api獲取值的屬性沒(méi)有解析,因?yàn)榈谌降念?lèi)無(wú)法加上@Expose注解,導(dǎo)致這些屬性為null,而Gson默認(rèn)的規(guī)則不會(huì)解析為null的屬性,比如:

    public String getEndTime() {
        if (this.endTime == null) {
            Date endDate = (null == historicProcessInstance) ? null : historicProcessInstance.getEndTime();
            endTime = endDate == null ? "" : DateFormatUtil.format(endDate);
        }
        return endTime;
    }

(3)換解析方式:使用FastJson。
因?yàn)镕astJson是通過(guò)getter方法獲取屬性,并把其值序列化成json字符串的,所以這里,我們這個(gè)實(shí)體類(lèi)中去掉不想被解析的屬性的get方法,變成如下:


    public void setTask(Task task) {
        this.task = task;
    }

    public void setProcessInstance(ProcessInstance processInstance) {
        this.processInstance = processInstance;
    }

    public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
        this.historicProcessInstance = historicProcessInstance;
    }

    public void setProcessDefinition(ProcessDefinition processDefinition) {
        this.processDefinition = processDefinition;
    }

    public void setHistoricTaskInstance(HistoricTaskInstance historicTaskInstance) {
        this.historicTaskInstance = historicTaskInstance;
    }

fastJson、JackJson以及Gson序列化對(duì)象與get、set以及對(duì)象屬性之間的關(guān)系

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1.概述2.Gson的目標(biāo)3.Gson的性能和擴(kuò)展性4.Gson的使用者5.如何使用Gson 通過(guò)Maven來(lái)使用...
    人失格閱讀 14,328評(píng)論 2 18
  • 概況 Gson是一個(gè)Java庫(kù),它可以用來(lái)把Java對(duì)象轉(zhuǎn)換為JSON表達(dá)式,也可以反過(guò)來(lái)把JSON字符串轉(zhuǎn)換成與...
    木豚閱讀 6,832評(píng)論 0 2
  • Json是一種輕量級(jí)的數(shù)據(jù)交換語(yǔ)言,以文字為基礎(chǔ),且易于讓人閱讀和編寫(xiě),同時(shí)也易于機(jī)器解析和生成,因而在客戶端與服...
    sunnyaxin閱讀 33,838評(píng)論 9 42
  • 公司的小伙伴希望能講一下正則表達(dá)式,于是趁著這個(gè)機(jī)會(huì)自己也把正則表達(dá)式的重新學(xué)習(xí)了一下,由于不同語(yǔ)言對(duì)正則表達(dá)式提...
    Patrick浩閱讀 654評(píng)論 1 1
  • 愿你不被生活壓垮,在平凡的生活中找到一個(gè)平衡點(diǎn),享受生活,哪怕那只是一朵花,一片葉。我總是控制不了安分的心和不穩(wěn)...
    與君共勉18閱讀 500評(píng)論 0 6