[alibaba/fastjson]一串json字符串,转换成java对象,javaBean中无默认构造函数时,其余字段值转换丢失

2025-10-31 142 views
1

如题,有如下实体类

public class IvsAPIResult implements Serializable {
@JsonProperty("success")
private Boolean success;
@JsonProperty("reason_code")
private String reasonCode;
@JsonProperty("reason_desc")
private String reasonDesc;
@JsonProperty("custom_id")
private String customId;
@JsonProperty("decision_id")
private String decisionId;
@JsonProperty("result_desc")
private JSONObject resultDesc;

public IvsAPIResult(Boolean success) {
    this.setSuccess(success);
}

public IvsAPIResult setReason(ReasonCodeEnum reason) {
    this.setReasonCode(reason.getCode());
    this.setReasonDesc(reason.getDesc());
    return this;
}

public static IvsAPIResult failureResult(ReasonCodeEnum reasonCodeEnum) {
    return (new IvsAPIResult(Boolean.FALSE)).setReason(reasonCodeEnum);
}

public static IvsAPIResult failureResult(String code, String desc) {
    IvsAPIResult result = new IvsAPIResult(Boolean.FALSE);
    result.setReasonCode(code);
    result.setReasonDesc(desc);
    return result;
}

public Boolean getSuccess() {
    return this.success;
}

public void setSuccess(Boolean success) {
    this.success = success;
}

public String getReasonCode() {
    return this.reasonCode;
}

public void setReasonCode(String reasonCode) {
    this.reasonCode = reasonCode;
}

public String getReasonDesc() {
    return this.reasonDesc;
}

public void setReasonDesc(String reasonDesc) {
    this.reasonDesc = reasonDesc;
}

public String getCustomId() {
    return this.customId;
}

public void setCustomId(String customId) {
    this.customId = customId;
}

public String getDecisionId() {
    return this.decisionId;
}

public void setDecisionId(String decisionId) {
    this.decisionId = decisionId;
}

public JSONObject getResultDesc() {
    return this.resultDesc;
}

public void setResultDesc(JSONObject resultDesc) {
    this.resultDesc = resultDesc;
}
} 

有如下json字符串与实体类对应

{
"customId": "WF2018101018152610126468",
"decisionId": "1539052159989116750",
"resultDesc": {
"questionLibrary": "income",
"decision": "review",
"desc": "恭喜答题通过"
},
"success": true
}

对上述字符串转换成IvsApiResult进行测试,发现转换后字段内容全部丢失,但Gson是成功的

public static void main(String[] args) {
    String s = "{\"customId\":\"WF2018101018152610126468\",\"decisionId\":\"1539052159989116750\",\"resultDesc\":{\"questionLibrary\":\"income\",\"decision\":\"review\",\"desc\": \"恭喜答题通过\"},\"success\":true}";
    Gson gson = new Gson();
    IvsAPIResult ivsAPIResult = gson.fromJson(s, IvsAPIResult.class);
    System.out.println(ivsAPIResult.getCustomId() + "==" + JSON.toJSONString(ivsAPIResult));

    System.out.println("-----");
    IvsAPIResult apiResult = JSON.parseObject(s, IvsAPIResult.class);
    System.out.println(apiResult.getCustomId() + "==" + JSON.toJSONString(apiResult));
}

上述main函数运行结果如下

WF2018101018152610126468=={"customId":"WF2018101018152610126468","decisionId":"1539052159989116750","resultDesc":{"questionLibrary":"income","decision":"review","desc":"恭喜答题通过"},"success":true}
-----
null=={"success":true}

回答

3

请使用JSONField,而不是JsonProperty

9

请使用JSONField,而不是JsonProperty

这个试过了,换成JSONFiled也是一样的问题,没有解决

8

@decode-life 反序列化的过程中,需要通过默认构造函数创建实例,一旦构造方法被重写了,创建实例就会失败(可以使用Jackson-databind测试,没有默认构造函数解析的时候直接报错)。 正如wiki中介绍的: 7.fastjson序列化的需要像json-lib一样配置java bean的序列化么?

不需要,fastjson的序列化和反序列化都不需要做特别配置,唯一的要求是,你序列化的类符合java bean规范

而JavaBean规范是要求必须有默认构造函数的。所以建议创建JavaBean的时候手动配置一个显示的无参构造函数。

GSON之所以可以成功解析,是因为它封装了一个UnsafeAllocator类,使用sun.misc.Unsafe的allocateInstance方法来绕过了构造方法限制创建实例,这并不是常规的处理方式。