问题描述
在使用fastjson调用
JSON.toJSONString(JSON.parseObject(demo), features);
fastJson包版本
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.53</version>
</dependency>
方法将一个String转换成一个对象时,如果对象obj的属性字段有值为null时,该字段会被系列化成"";
传入String对象:
{
"code": "SUCCESS",
"data": {
"amount_of_handling_fees": null,
"associate_amount": 200000,
"associate_currency": "VND",
"associate_risk_review_id": "",
"client_rate": "1.0000000000000000",
"credited_amount": null,
"fx_order_no": "",
"goods_tax": null,
"incoming_payment_id": "SZLS2025021011112568049767730",
"merchant_order_list": [
{
"merchant_order_no": "1889223743019364353",
"order_associate_amount": 200000,
"order_associate_amount_goods": null,
"order_associate_amount_service": null,
"order_currency": "VND",
"order_goods_tax": null,
"order_service_tax": null,
"trade_order_no": "MYDD2025021116124303299021"
}
],
"order_associated_id": "AS202502111632520283768844",
"risk_review_remark": "",
"risk_review_type": "",
"service_tax": null,
"status": "processing",
"tax_amount": null,
"unsettlement_amount": 200000,
"unsettlement_currency": "VND"
},
"message": "success",
"timestamp": "2025-02-12T11:16:13+08:00"
}
使用系列化后
String sortedJson = JSON.toJSONString( parseObject(demo));
{
"code": "SUCCESS",
"data": {
"associate_amount": 200000,
"associate_currency": "VND",
"associate_risk_review_id": "",
"client_rate": "1.0000000000000000",
"fx_order_no": "",
"incoming_payment_id": "SZLS2025021011112568049767730",
"merchant_order_list": [
{
"merchant_order_no": "1889223743019364353",
"order_associate_amount": 200000,
"order_currency": "VND",
"trade_order_no": "MYDD2025021116124303299021"
}
],
"order_associated_id": "AS202502111632520283768844",
"risk_review_remark": "",
"risk_review_type": "",
"status": "processing",
"unsettlement_amount": 200000,
"unsettlement_currency": "VND"
},
"message": "success",
"timestamp": "2025-02-12T11:16:13+08:00"
}
问题描述:
我们可以很明显的看到系列化后null已经修改成""
问题分析
其实fastjson的toJSONString()。
源码分析:
com.alibaba.fastjson.JSON
public static String toJSONString(Object object) {
JSONWriter.Context context = createWriteContext(SerializeConfig.global, DEFAULT_GENERATE_FEATURE);
try (JSONWriter writer = JSONWriter.of(context)) {
if (object == null) {
writer.writeNull();
} else {
writer.setRootObject(object);
Class<?> valueClass = object.getClass();
ObjectWriter objectWriter = context.getObjectWriter(valueClass, valueClass);
objectWriter.write(writer, object, null, null, 0);
}
return writer.toString();
} catch (com.alibaba.fastjson2.JSONException ex) {
Throwable cause = ex.getCause() != null ? ex.getCause() : ex;
throw new JSONException(ex.getMessage(), cause);
} catch (RuntimeException ex) {
throw new JSONException("toJSONString error", ex);
}
}
com.alibaba.fastjson.JSON
static {
int features = 0;
features |= SerializerFeature.QuoteFieldNames.getMask();
features |= SerializerFeature.SkipTransientField.getMask();
features |= SerializerFeature.WriteEnumUsingName.getMask();
features |= SerializerFeature.SortField.getMask();
DEFAULT_GENERATE_FEATURE = features;
}
public static JSONWriter.Context createWriteContext(
SerializeConfig config,
int featuresValue,
SerializerFeature... features
) {
for (SerializerFeature feature : features) {
featuresValue |= feature.mask;
}
ObjectWriterProvider provider = config.getProvider();
provider.setCompatibleWithFieldName(TypeUtils.compatibleWithFieldName);
JSONWriter.Context context = new JSONWriter.Context(provider);
if (config.fieldBased) {
context.config(JSONWriter.Feature.FieldBased);
}
if (config.propertyNamingStrategy != null
&& config.propertyNamingStrategy != PropertyNamingStrategy.NeverUseThisValueExceptDefaultValue
&& config.propertyNamingStrategy != PropertyNamingStrategy.CamelCase1x
) {
NameFilter nameFilter = NameFilter.of(config.propertyNamingStrategy);
configFilter(context, nameFilter);
}
if ((featuresValue & SerializerFeature.DisableCircularReferenceDetect.mask) == 0) {
context.config(JSONWriter.Feature.ReferenceDetection);
}
if ((featuresValue & SerializerFeature.UseISO8601DateFormat.mask) != 0) {
context.setDateFormat("iso8601");
} else {
context.setDateFormat("millis");
}
if ((featuresValue & SerializerFeature.WriteMapNullValue.mask) != 0) {
context.config(JSONWriter.Feature.WriteMapNullValue);
}
if ((featuresValue & SerializerFeature.WriteNullListAsEmpty.mask) != 0) {
context.config(JSONWriter.Feature.WriteNullListAsEmpty);
}
if ((featuresValue & SerializerFeature.WriteNullStringAsEmpty.mask) != 0) {
context.config(JSONWriter.Feature.WriteNullStringAsEmpty);
}
if ((featuresValue & SerializerFeature.WriteNullNumberAsZero.mask) != 0) {
context.config(JSONWriter.Feature.WriteNullNumberAsZero);
}
if ((featuresValue & SerializerFeature.WriteNullBooleanAsFalse.mask) != 0) {
context.config(JSONWriter.Feature.WriteNullBooleanAsFalse);
}
if ((featuresValue & SerializerFeature.BrowserCompatible.mask) != 0) {
context.config(JSONWriter.Feature.BrowserCompatible);
context.config(JSONWriter.Feature.EscapeNoneAscii);
}
if ((featuresValue & SerializerFeature.BrowserSecure.mask) != 0) {
context.config(JSONWriter.Feature.BrowserSecure);
}
if ((featuresValue & SerializerFeature.WriteClassName.mask) != 0) {
context.config(JSONWriter.Feature.WriteClassName);
}
if ((featuresValue & SerializerFeature.WriteNonStringValueAsString.mask) != 0) {
context.config(JSONWriter.Feature.WriteNonStringValueAsString);
}
if ((featuresValue & SerializerFeature.WriteEnumUsingToString.mask) != 0) {
context.config(JSONWriter.Feature.WriteEnumUsingToString);
}
if ((featuresValue & SerializerFeature.WriteEnumUsingName.mask) != 0) {
context.config(JSONWriter.Feature.WriteEnumsUsingName);
}
if ((featuresValue & SerializerFeature.NotWriteRootClassName.mask) != 0) {
context.config(JSONWriter.Feature.NotWriteRootClassName);
}
if ((featuresValue & SerializerFeature.IgnoreErrorGetter.mask) != 0) {
context.config(JSONWriter.Feature.IgnoreErrorGetter);
}
if ((featuresValue & SerializerFeature.WriteDateUseDateFormat.mask) != 0) {
context.setDateFormat(JSON.DEFFAULT_DATE_FORMAT);
}
if ((featuresValue & SerializerFeature.BeanToArray.mask) != 0) {
context.config(JSONWriter.Feature.BeanToArray);
}
if ((featuresValue & SerializerFeature.UseSingleQuotes.mask) != 0) {
context.config(JSONWriter.Feature.UseSingleQuotes);
}
if ((featuresValue & SerializerFeature.MapSortField.mask) != 0) {
context.config(JSONWriter.Feature.MapSortField);
}
if ((featuresValue & SerializerFeature.PrettyFormat.mask) != 0) {
context.config(JSONWriter.Feature.PrettyFormat);
}
if ((featuresValue & SerializerFeature.WriteNonStringKeyAsString.mask) != 0) {
context.config(JSONWriter.Feature.WriteNonStringKeyAsString);
}
if ((featuresValue & SerializerFeature.IgnoreNonFieldGetter.mask) != 0) {
context.config(JSONWriter.Feature.IgnoreNonFieldGetter);
}
if ((featuresValue & SerializerFeature.NotWriteDefaultValue.mask) != 0) {
context.config(JSONWriter.Feature.NotWriteDefaultValue);
}
if ((featuresValue & SerializerFeature.WriteBigDecimalAsPlain.mask) != 0) {
context.config(JSONWriter.Feature.WriteBigDecimalAsPlain);
}
if ((featuresValue & SerializerFeature.QuoteFieldNames.mask) == 0
&& (featuresValue & SerializerFeature.UseSingleQuotes.mask) == 0
) {
context.config(JSONWriter.Feature.UnquoteFieldName);
}
if (defaultTimeZone != null && defaultTimeZone != DEFAULT_TIME_ZONE) {
context.setZoneId(defaultTimeZone.toZoneId());
}
context.config(JSONWriter.Feature.WriteByteArrayAsBase64);
context.config(JSONWriter.Feature.WriteThrowableClassName);
return context;
}
从源码分析我们可以知道,JSON默认是换成""的
解决方法:
SerializerFeature[] features = {
SerializerFeature.MapSortField,
SerializerFeature.WriteMapNullValue
};
String sortedJson = JSON.toJSONString(JSON.parseObject(demo), features);
在使用时,也可以根据自己的需求来添加其他枚举类型,直接在后边添加即可。
最后,希望可以帮助到有需要的码友。