Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fastjson 能否提供字段级别的null输出控制,类似Jackson2 的 @JsonInclude(value=Include.NON_NULL) 注解 #1730

Open
ldcsaa opened this issue Aug 11, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@ldcsaa
Copy link

ldcsaa commented Aug 11, 2023

需求或者改进建议

fastjson2 的 JSONWriter.Feature.WriteMapNullValue 是对象级别的,序列化对象时null字段要么全部输出,要么不输出。
我现在有一个场景:校验错误字段validationErrors在有值的时候才输出,没有值就不输出,无论是否设置了 JSONWriter.Feature.WriteMapNullValue
Jackson2 的 @JsonInclude(value=Include.NON_NULL) 能很好实现这个需求,但fastjson2 我没看到类似的功能

附加信息

源码示例

public class Response<T> implements Serializable
{
	public static final String MSG_OK = "ok";	

	@Schema(title="状态码", example="0", requiredMode=RequiredMode.REQUIRED, nullable=false)
	private Integer statusCode = OK;
	
	@Schema(title="状态描述", example=MSG_OK, requiredMode=RequiredMode.NOT_REQUIRED, nullable=true)
	private String msg = MSG_OK;

	/* fastjson2 如何实现??? */
	@JsonInclude(value=Include.NON_NULL)
	@Schema(title="参数校验错误列表", example="name is empty", requiredMode=RequiredMode.NOT_REQUIRED, nullable=true)
	private Map<String, List<String>> validationErrors;
	
	@Schema(title="业务模型对象", example="Any Object", requiredMode=RequiredMode.NOT_REQUIRED, nullable=true)
	private T result;
}

目前的解决办法

我目前是通过自定义 PropertyFilter 实现,每个属性判断都要经过这个Filter,还涉及到反射操作,不知对运行效率有多大影响

@Documented
@Retention(RUNTIME)
@Target(ElementType.FIELD)
public @interface JSONFieldExclude
{
	Exclude value() default Exclude.ALWAYS;
	
	public static enum Exclude
	{
		NULL,
		ABSENT,
		EMPTY,
		ALWAYS
	}
}
public class FastJsonExcludePropertyFilter implements PropertyFilter
{
	@Override
	public boolean apply(Object object, String name, Object value)
	{
		if(object  == null)
			return true;
		
		Class<?> clazz = object.getClass();
		
		if(Map.class.isAssignableFrom(clazz) || Collection.class.isAssignableFrom(clazz) || clazz.isArray())
			return true;
		
		try
		{
			Field field = clazz.getDeclaredField(name);
			
			JSONFieldExclude annotation = field.getAnnotation(JSONFieldExclude.class);
			
			if(annotation == null)
				return true;

			JSONFieldExclude.Exclude exclude = annotation.value();
			
			if(exclude == Exclude.ALWAYS)
				return false;
			else if(exclude == Exclude.NULL)
				return Objects.nonNull(value);
			else if(exclude == Exclude.ABSENT)
			{
				if(Objects.isNull(value))
					return false;
				
				if(value instanceof Optional<?> opt)
					return opt.isPresent();
			}
			else if(exclude == Exclude.EMPTY)
			{
				if(Objects.isNull(value))
					return false;
				
				if(value instanceof Optional<?> opt)
					return opt.isPresent();
				else if(value instanceof String str)
					return !str.isEmpty();
				else if(value instanceof Collection<?> col)
					return !col.isEmpty();
				else if(value instanceof Map<?, ?> map)
					return !map.isEmpty();
				else if(clazz.isArray())
					return Array.getLength(value) > 0;
			}
			else
			{
				throw new IllegalArgumentException("Unexpected value: " + exclude);
			}
		}
		catch(NoSuchFieldException | SecurityException e)
		{
			
		}
		
		return true;
	}

}

@ldcsaa ldcsaa added the enhancement New feature or request label Aug 11, 2023
@wenshao
Copy link
Member

wenshao commented Aug 12, 2023

请参考文档 https://github.com/alibaba/fastjson2/blob/main/docs/features_cn.md 中第5点的WriteNulls,如下方式使用

    public static class Bean {
        @JSONField(serializeFeatures = Feature.WriteNulls)
        public int id;
    }

@ldcsaa
Copy link
Author

ldcsaa commented Aug 19, 2023

请参考文档 https://github.com/alibaba/fastjson2/blob/main/docs/features_cn.md 中第5点的WriteNulls,如下方式使用

    public static class Bean {
        @JSONField(serializeFeatures = Feature.WriteNulls)
        public int id;
    }

正好相反,我的需求是 null 值不输出~~

@ldcsaa ldcsaa changed the title fastjson 能否提供字段级别的null输出控制,类似 @JsonInclude(value=Include.NON_NULL) fastjson 能否提供字段级别的null输出控制,类似Jackson2 的 @JsonInclude(value=Include.NON_NULL) 注解 Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants