fastjson-对象转json字符串时保留空字段SerializerFeature无效的问题

需求简述

将java实体类转换为json字符串,空字段也需要转换。

问题说明

用fastjson将java对象转json字符串时默认去除空字段,网上查阅一番,都说转的时候添加SerializerFeature.WriteNullStringAsEmpty参数就行,亲测了一下,没有达到效果(原因未知)。
如下例子:AssessReq 还有个caseId字段特意不设置值

AssessReq ar= new AssessReq();
ar.setAge(11);
ar.setUsername("test");
logger.info("Json =>> " + JSON.toJSONString(ar, SerializerFeature.WriteNullStringAsEmpty);

输出结果:

testJson =>> {"age":11,"username":"test"}

结果可见,caseId字段并有保留。SerializerFeature.WriteMapNullValue 也试过了也是不不行。

解决方案

后面换了种方法才解决的,解决方法如下:

// 自定义空字段处理规则
ValueFilter filter = (obj, s, v) -> {
	if (v == null) {
	        logger.info("s =>> "+s);
	        return "";
	    }
	    return v;
	};
AssessReq ar= new AssessReq();
ar.setAge(11);
ar.setUsername("test");
logger.info("testJson =>> " + JSON.toJSONString(ar, filter));

输出结果:

testJsonn =>> {"age":11,"caseId":"","username":"test"}

结果可见,是可以实现预期的效果的。

—————————————————————————————————————————————————————————
—————————————————————————————————————————————————————————
2021-04-21补充:
评论区大佬说的做法更好,亲测有效!
User:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
    private Address address;
}

Address:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
    private String privince;
    private String city;
}

测试:

Addressaddress= new Address();
address.setCity("深圳");

User user = new User();
user.setName("小明");
user.setAddress(address);

// 直接输出json
System.out.println("user =>> " + JSON.toJSONString(user));
// 转json时加SerializerFeature参数
SerializerFeature[] feature= {SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero};
System.out.println("user =>> " + JSON.toJSONString(user, feature));

输出结果:

user =>> {"address":{"city":"深圳"},"name":"小明"}
user =>> {"address":{"city":"深圳","privince":""},"age":0,"hobbys":null,"name":"小明"}

由上可见,这种方法更好更简洁,推荐使用!!

<think>嗯,用户问的是如何仅将非字段Fastjson。首先,我需要确认用户的需求是什么。他们可能在处理Java对象JSON候,希望过滤掉那些值为字段,只保留有值的部分。Fastjson是阿里巴巴的一个JSON库,所以用户可能在用这个库进行序列化。 接下来,我得回想一下Fastjson的相关配置。记得Fastjson有一个SerializerFeature的枚举类,里面有很多序列化的选项。比如,WriteMapNullValue这个特性是用来控制是否输出值的。默认情况下,Fastjson不会序列化null值的字段,所以用户可能发现即使字段是null,也没有被包含在JSON中。不过,用户提到的是“非字段”,可能需要确认是否包括字符串或者集合为的情况。 然后,我需要考虑用户可能遇到的例外情况。比如,如果用户确实需要保留某些null值,但排除其他类型的值,可能需要更复杂的处理。比如,使用过滤器(NameFilter或ValueFilter)或者自定义的序列化器。这候需要举例说明如何通过自定义过滤器来判断字段值是否为,并决定是否序列化。 另外,用户可能对“非”有不同的定义。比如,字符串集合、数组是否也被视为字段。这候可能需要明确处理这些情况,提供相应的解决方案。例如,在自定义的过滤器里,检查字符串是否为null或,集合是否为等。 还要考虑Fastjson的版本问题,不同版本可能有不同的配置方式。确保提供的代码示例在主流版本中都能使用,比如1.2.x之后的版本。 可能用户已经尝试过默认配置,但发现某些值仍然被序列化,或者他们需要更灵活的控制。这候需要分情况讨论,给出不同的解决方案,比如全局配置、注解方式或者在具体序列化指定特性。 总结一下,回答需要涵盖以下几点:默认行为、使用SerializerFeature、自定义过滤器处理更复杂的值判断,以及处理不同数据类型的值情况。确保步骤清晰,示例代码正确,并且解释每种方法的适用场景,这样用户可以根据自己的需求选择合适的方法。</think>将Java对象中非字段Fastjson,可以通过以下步骤实现: 一、Fastjson默认行为 1. Fastjson默认会忽略以下字段- `null`值字段 - 字符串`""`(需特别处理) - 集合/数组(需特别处理) 二、基础配置方案 ```java // 全局配置(推荐方案) static { // 关闭null值输出(默认已关闭) SerializerConfig.getGlobalInstance().setSerializerFeatures( SerializerFeature.WriteMapNullValue.getMask() ); } ``` 三、精准控制非字段(3种常用方法) 1. 使用@JSONField注解 ```java public class User { // 仅当name非序列化 @JSONField(serialize = false) private String name; public String getName() { return StringUtils.isEmpty(name) ? null : name; } } ``` 2. 序列化指定过滤规则 ```java String json = JSON.toJSONString(obj, new SimplePropertyPreFilter() { @Override public boolean apply(JSONSerializer serializer, Object source, String name) { Object value = ((FieldSerializer)serializer.getObjectSerializer(source.getClass())) .getFieldValue(source, name); return !isEmpty(value); // 自定义值判断 } } ); ``` 3. 自定义ValueFilter(推荐复杂场景) ```java ValueFilter nonEmptyFilter = (obj, key, value) -> { if (isEmpty(value)) { return null; // 返回null会被Fastjson过滤 } return value; }; String json = JSON.toJSONString(user, nonEmptyFilter); ``` 四、值判断工具方法 ```java private static boolean isEmpty(Object value) { if (value == null) return true; if (value instanceof String) return ((String) value).trim().isEmpty(); if (value instanceof Collection) return ((Collection<?>) value).isEmpty(); if (value instanceof Map) return ((Map<?,?>) value).isEmpty(); if (value.getClass().isArray()) return Array.getLength(value) == 0; return false; } ``` 五、注意事项 1. 日期类型:`new Date(0)`会被视为非 2. 数值类型:`0`会被视为有效值 3. Boolean类型:`false`会被保留 4. 使用`@JSONField(format="...")`可控制日期格式 建议根据实际业务需求选择最合适的过滤策略,复杂对象建议结合`@JSONField`注解和自定义Filter配合使用。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值