Gson、FastJson、Jackson、json-lib对比总结

一 、各个JSON技术的简介和优劣

  1. json-lib

json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,
包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
对于复杂类型的转换,json-lib对于json转换成bean还有缺陷,比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。
json-lib在功能和性能上面都不能满足现在互联网化的需求。

  1. 开源的Jackson

相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。
而且Jackson社区相对比较活跃,更新速度也比较快。
Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。
Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式

  1. Google的Gson

Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,
但自从在2008年五月公开发布第一版后已被许多公司或用户应用。
Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。
而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。
类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。
Gson在功能上面无可挑剔,但是性能上面比FastJson有所差距。

  1. 阿里巴巴的FastJson

Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。
无依赖,不需要例外额外的jar,能够直接跑在JDK上。
FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。
FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。

综上4种Json技术的比较:在项目选型的时候可以使用Google的Gson和阿里巴巴的FastJson两种并行使用,
如果只是功能要求,没有性能要求,可以使用google的Gson,
如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean

二、Google的Gson包的使用简介。

2.1 主要类介绍
Gson类:解析json的最基础的工具类
JsonParser类:解析器来解析JSON到JsonElements的解析树
JsonElement类:一个类代表的JSON元素
JsonObject类:JSON对象类型
JsonArray类:JsonObject数组
TypeToken类:用于创建type,比如泛型List<?>

2.2 maven依赖

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

2.3 bean转换json

Gson gson = new Gson();
String json = gson.toJson(obj);
//obj是对象

2.4 json转换bean

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

2.5 json转换复杂的bean,比如List,Set
将json转换成复杂类型的bean,需要使用TypeToken

Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
//将json转换成List
List list = gson.fromJson(json,new TypeToken<LIST>() {}.getType());
//将json转换成Set
Set set = gson.fromJson(json,new TypeToken<SET>() {}.getType());

2.6 通过json对象直接操作json以及一些json的工具

a) 格式化Json

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

b) 判断字符串是否是json,通过捕捉的异常来判断是否是json

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

c) 从json串中获取属性

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
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中的某个属性

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
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技术\"}";
String propertyName = 'desc';
Object propertyValue = "json各种技术的调研";
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技术\"}";
String propertyName = 'name';
Object propertyValue = "json各种技术的调研";
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技术\"}";
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对象进行json的处理,如果出现日期Date类的对象,就会按照设置的格式进行处理
i) json中对于Html的转义

Gson gson = new Gson();

这种对象默认对Html进行转义,如果不想转义使用下面的方法

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

三、阿里巴巴的FastJson包的使用简介。

3.1 maven依赖

    <!-- FastJson将Json转换Bean -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.46</version>
    </dependency>

3.2 基础转换类
同上
3.3 bean转换json
将对象转换成格式化的json

JSON.toJSONString(obj,true);

将对象转换成非格式化的json

JSON.toJSONString(obj,false);

obj设计对象
对于复杂类型的转换,对于重复的引用在转成json串后在json串中出现引用的字符,比如 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转换bean

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

3.5 json转换复杂的bean,比如List,Map

String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
//将json转换成List
List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){});
//将json转换成Set
Set set = JSON.parseObject(json,new TypeReference<HASHSET>(){});

3.6 通过json对象直接操作json
a) 从json串中获取属性

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

b) 除去json中的某个属性

String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
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技术\"}";
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技术\"}";
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技术\"}";
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,该方法可以使用设置的日期格式对日期进行转换

四、json-lib包的使用简介。

4.1 maven依赖

//json-lib 为官方api,只需java jdk >jdk15即可。需要依赖一下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日志依赖 -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

4.2 基础转换类
同上
4.3 bean转换json
a)将类转换成Json,obj是普通的对象,不是List,Map的对象

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

b) 将List,Map转换成Json

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

4.4 json转换bean

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

4.5 json转换List,对于复杂类型的转换会出现问题

String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"Java技术\"}]";
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转换Map

String jsonString = "{\"id\":\"1\",\"name\":\"Json技术\"}";
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对于日期的操作比较复杂,需要使用JsonConfig,比Gson和FastJson要麻烦多了
创建转换的接口实现类,转换成指定格式的日期

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 对于json的操作和处理
a) 从json串中获取属性

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

b) 除去json中的某个属性

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

c) 向json中添加和修改属性,有则修改,无则添加

String jsonString = "{\"id\":\"1\",\"name\":\"Json技术\"}";
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技术\"}";
boolean containFlag = false;
Object key = "desc";
JSONObject jsonObject = JSONObject.fromObject(jsonString);
containFlag = jsonObject.containsKey(key);

五、注意事项

fastjsonjackson 在把对象序列化成json字符串的时候,是通过反射遍历出该类中的所有getter方法;
Gson 是通过反射遍历该类中的所有属性。
所以,在定义POJO中的布尔类型的变量时,不要使用isSuccess这种形式,而要直接使用success

六、示例

以上为网上摘抄,以下为实际项目中使用结果。
实体类为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;// 创建人
    protected String createName;
    protected String createTime;// 流程的创建时间
    protected String endTime;// 流程的结束时间
    protected String reason;
    protected String owner;// 拥有者
    // 申请的标题
    protected String title;
    // 业务类型
    protected String businessType;
    protected String deploymentId;// 流程部署id
    protected String processInstanceId;// 流程实例id
    protected String deleteReason;// 删除原因
    protected String handledTaskId;// 已处理任务id
    protected String handledTaskDefinitionKey;// 已处理节点
    protected String handledTaskName;// 已处理节点名称
    protected String assignedId;// 已处理节点的受理人
    protected String assignedName;// 已处理节点的受理人
    protected String toHandleTaskId;// 当前节点的任务id
    protected String taskDefinitionKey;// 当前节点key
    protected String toHandleTaskName;// 当前节点点名
    protected String assign;// 当前节点的受理人
    protected String assignName;// 当前节点的受理人
    protected String description;// 描述
    protected String businessKey;// 对应业务的id
    protected String startTime;// 任务的开始时间
    protected String operateTime;// 任务的结束时间(处理时间)
    protected String claimTime;// 任务的签收时间
    protected boolean isEnd;// 流程是否结束
    protected boolean isSuspended;// 是否挂起
    protected String processDefinitionId;// 流程定义id
    protected String processDefinitionName;// 流程名称
    protected String processDefinitionKey;// 流程key,任务跳转用
    protected String processStatus;// 流程状态:待审批、审批通过、审批退回、归档、结束
    protected int version;// 流程版本号
    protected JSONObject contentInfo;// 流程的业务相关
    private String candidate_ids;//下一节点执行人,多个用逗号隔开
    private String candidate_names;//下一节点执行人,多个用逗号隔开

    private List<CommentVO> comments;//评论列表
    
    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;
    }

    // 流程任务
    public Task task;

    // 运行中的流程实例
    protected ProcessInstance processInstance;

    // 历史的流程实例
    protected HistoricProcessInstance historicProcessInstance;

    // 历史任务
    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 将该实体类转成json时报以下异常:

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)

原因是:子类和父类有相同的字段属性;
解决方法:
(1)重命名重复字段。因为重复的字段在第三方包中,所以该方法在本例中不可行。
(2)将实体类中需要打印的字段加上注解@Expose,(本例将该类所有有get方法的属性都加上了) :

    @Expose
    protected int id;
    @Expose
    protected String createId;// 创建人
    @Expose
    protected String createName;

新建gson:

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

excludeFieldsWithoutExposeAnnotation排除掉没有Expose注解的属性。

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


    // 流程任务
    public transient Task task;

    // 运行中的流程实例
    protected transient ProcessInstance processInstance;

    // 历史的流程实例
    protected transient HistoricProcessInstance historicProcessInstance;

    // 历史任务
    protected transient HistoricTaskInstance historicTaskInstance;

    // 流程定义
    protected transient ProcessDefinition processDefinition;

用该方式,没有报异常了,解析结果(加注解@Expose或加transient)如下:

{
    "data": [{
        "id": 0,
        "createId": "admin",
        "createName": "系统管理员",
        "createTime": "2019-04-11 17:01:46",
        "reason": "",
        "title": "2019-04-01至2019-04-07工时填报",
        "processInstanceId": "70013",
        "handledTaskId": "70023",
        "handledTaskDefinitionKey": "outsourcerApply",
        "handledTaskName": "外包人员申请",
        "assignedId": "admin",
        "assignedName": "系统管理员",
        "toHandleTaskId": "70039",
        "taskDefinitionKey": "projectManagerAudit",
        "toHandleTaskName": "项目经理审批",
        "assign": "215",
        "assignName": "郭俊杰",
        "description": "您提出2019-04-01至2019-04-07工时填报",
        "businessKey": "monthlyreportForProjectProcess:admin:20190401:20190407",
        "isEnd": false,
        "isSuspended": false,
        "processDefinitionId": "monthlyreportForProjectProcess:1:70012",
        "processDefinitionName": "工时填报(项目外包/行内人员)",
        "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": "系统管理员",
            "content": "发起申请",
            "taskId": "70023",
            "processInstanceId": "70013",
            "time": "2019-04-11 17:01:47",
            "nextAssign": "215",
            "nextAssignName": "郭俊杰"
        }]
    }],
    "type": "success"
}

但从结果来看,那些直接调用第三方api获取值的属性没有解析,因为第三方的类无法加上@Expose注解,导致这些属性为null,而Gson默认的规则不会解析为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。
因为FastJson是通过getter方法获取属性,并把其值序列化成json字符串的,所以这里,我们这个实体类中去掉不想被解析的属性的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序列化对象与get、set以及对象属性之间的关系

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 1.概述2.Gson的目标3.Gson的性能和扩展性4.Gson的使用者5.如何使用Gson 通过Maven来使用...
    人失格阅读 14,196评论 2 18
  • 概况 Gson是一个Java库,它可以用来把Java对象转换为JSON表达式,也可以反过来把JSON字符串转换成与...
    木豚阅读 6,757评论 0 2
  • Json是一种轻量级的数据交换语言,以文字为基础,且易于让人阅读和编写,同时也易于机器解析和生成,因而在客户端与服...
    sunnyaxin阅读 33,732评论 9 42
  • 公司的小伙伴希望能讲一下正则表达式,于是趁着这个机会自己也把正则表达式的重新学习了一下,由于不同语言对正则表达式提...
    Patrick浩阅读 648评论 1 1
  • 愿你不被生活压垮,在平凡的生活中找到一个平衡点,享受生活,哪怕那只是一朵花,一片叶。我总是控制不了安分的心和不稳...
    与君共勉18阅读 458评论 0 6