fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

[BUG]JSONWriter.Feature.IgnoreNonFieldGetter无法序列化问题

Open kervin521 opened this issue 1 year ago • 2 comments

问题描述

简要描述您碰到的问题。

环境信息

请填写以下信息:

  • OS信息: [e.g.:Windows 10 Intel(R) Core(TM) i5-10500 CPU @ 3.10GHz 3.10 ]
  • JDK信息: [e.g.:Java(TM) SE Runtime Environment (build 1.8.0_341-b10) Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)]
  • 版本信息:[e.g.:Fastjson2 2.0.13]

重现步骤

如何操作可以重现该问题:

  1. 使用 xxx.xxx 方法
  2. 输入 ... 数据
  3. 出现 ... 错误

测试代码

package com.hollysys.smartfactory.common.docker;

import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.unit.DataSize;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.hollysys.smartfactory.common.docker.DockerTest.Service.Deploy;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Data
public class DockerTest {
	private String version="3.8";
	private Map<String,Service> services = Maps.newHashMap();
	
	public Map<String,Service> addService(String name,Service service){
		if(services==null) {
			services = Maps.newHashMap();
		}
		services.put(name, service);
		return services;
	}
	@Getter
	public static class Service{
		private String image;
		private Set<String> environment;
		private Deploy deploy;

		public Service putEnv(String env){
			if(environment==null) {
				environment = Sets.newHashSet();
			}
			if(StringUtils.isNotBlank(env)&&env.contains("=")) {
				environment.add(env);
			}
			return this;
		}
		public Service putEnv(String key,String value){
			if(StringUtils.isBlank(key)||StringUtils.isBlank(value)) {
				return this;
			}
			return putEnv(key+"="+value);
		}

		public final void setImage(String image) {
			this.image = image;
		}
		public final void setDeploy(Deploy deploy) {
			this.deploy = deploy;
		}
		@Data
		@NoArgsConstructor
		@AllArgsConstructor
		public static class Deploy{
			private String mode = DeployMode.REPLICATED.getValue();
			private Integer replicas=1;
			private RestartPolicy restart_policy;
			private Resource resources;
			private Map<String,String> labels;

			public Deploy putLabel(String label,String value){
				if(labels==null) {
					labels = Maps.newHashMap();
				}
				labels.put(label, value);
				return this;
			}
			@Getter
			public static enum DeployMode{
				REPLICATED("replicated"),
				GLOBAL("global");
				private String value;
				private DeployMode(String value) {
					this.value = value;
				}
			}
			@Data
			@NoArgsConstructor
			@AllArgsConstructor
			public static class RestartPolicy{
				private String condition;
				private Duration delay;
				private Integer max_attempts;
				private Duration window;
				
			}
			@Data
			@NoArgsConstructor
			@AllArgsConstructor
			public static class Resource{
				private Limit limits;
				private Limit reservations;
				public Resource limit(Number cpus,DataSize memory) {
					limits = new Limit(cpus,memory);
					return this;
				}
				public Resource limit(Number cpus,String memory) {
					return limit(cpus, StringUtils.isNotBlank(memory)?DataSize.parse(memory):null);
				}
				public Resource limit(Number cpus) {
					limits = new Limit(cpus);
					return this;
				}
				public Resource limit(String memory) {
					if(StringUtils.isNotBlank(memory)) {
						limits = new Limit(DataSize.parse(memory));
					}
					return this;
				}
				@Data
				@NoArgsConstructor
				@AllArgsConstructor
				public static class Limit{
					private Number cpus;
					private DataSize memory;
					public Limit(Number cpus) {
						this.cpus = cpus;
					}
					public Limit(DataSize memory) {
						this.memory = memory;
					}
					public final String getMemory() {
						return memory!=null?memory.toMegabytes()+"M":null;
					}
					public final String getCpus() {
						return cpus!=null?cpus.toString():null;
					}
				}
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
		DockerTest compose = new DockerTest();
		compose.setVersion("3.9");
		
		Service realtimeSvc = new Service();
		realtimeSvc.setImage("real-svc:1.0.21");
		realtimeSvc.putEnv("NETWORK_NAME", "eth0");
		realtimeSvc.putEnv("DEBUG_VERBOSE", "false");
		realtimeSvc.putEnv("SPRING_PROFILES_ACTIVE", "test");
		realtimeSvc.putEnv("SERVER_IP", "172.21.32.180");
		Deploy realtimeSvcDeploy = new Deploy();
		realtimeSvcDeploy.setReplicas(1);
		realtimeSvc.setDeploy(realtimeSvcDeploy);
		compose.addService("realtime-svc", realtimeSvc);
		Service realtimePipe = new Service();
		realtimePipe.setImage("realpipe:1.0.21");
		realtimePipe.putEnv("NETWORK_NAME", "eth0");
		realtimePipe.putEnv("DEBUG_VERBOSE", "false");
		realtimePipe.putEnv("SPRING_PROFILES_ACTIVE", "test");
		realtimePipe.putEnv("SERVER_IP", "172.21.22.180");
		Deploy realtimePipeDeploy = new Deploy();
		realtimePipeDeploy.setReplicas(1);
		realtimePipeDeploy.setResources(new Deploy.Resource().limit(2.5));
		realtimePipe.setDeploy(realtimePipeDeploy);
		compose.addService("realtime-pipe", realtimePipe);
		
		Service platformManagerSvc = new Service();
		platformManagerSvc.setImage("platform:1.0.21");
		platformManagerSvc.putEnv("NETWORK_NAME", "eth0");
		platformManagerSvc.putEnv("DEBUG_VERBOSE", "false");
		platformManagerSvc.putEnv("SPRING_PROFILES_ACTIVE", "test");
		platformManagerSvc.putEnv("SERVER_IP", "172.21.32.180");
		platformManagerSvc.putEnv("HOLLYSYS_LOGIC_IMAGE=nodered:1.3.7_v1.0.21");
		platformManagerSvc.putEnv("HOLLYSYS_UDPIO_ENV[MINIO_FILE_PATH]=/opt/deploy/data/udpio/");
		platformManagerSvc.putEnv("HOLLYSYS_UDPIO_ENV[HOLLYSYS_SERVER_ENABLED]=false");
		platformManagerSvc.putEnv("HOLLYSYS_UDPIO_ENV[HOLLYSYS_PROTOCOL]=udp");
		platformManagerSvc.putEnv("HOLLYSYS_UDPIO_ENV[HOLLYSYS_UDP_PACKAGE_LENGTH]=1000");
		platformManagerSvc.putEnv("hollysys.logic.data=/opt/m7it/logic/");
		Deploy platformManagerSvcDeploy = new Deploy();
		platformManagerSvcDeploy.setReplicas(1);
		platformManagerSvcDeploy.setResources(new Deploy.Resource().limit("4096MB"));
		platformManagerSvc.setDeploy(platformManagerSvcDeploy);
		compose.addService("platform-manager-svc", platformManagerSvc);
	}
}

v2.0.13 新方式JSONWriter.Feature

	   	/**
	   	 * Fastjson忽略忽略写特性
	   	 */
	   	JSONWriter.Feature[] FASTJSON_IGNORE_WRITER_FEATURES = {JSONWriter.Feature.BrowserCompatible, JSONWriter.Feature.WriteNullBooleanAsFalse, JSONWriter.Feature.NotWriteDefaultValue,JSONWriter.Feature.IgnoreErrorGetter, JSONWriter.Feature.IgnoreNonFieldGetter };
	   	
		Yaml yml = new Yaml();
		String json = com.alibaba.fastjson2.JSON.toJSONString(compose, FASTJSON_IGNORE_WRITER_FEATURES);
		String result = yml.dumpAs(JSON.parse(json), Tag.MAP, FlowStyle.BLOCK);
		System.out.println(result);

v2.0.12 兼容模式SerializerFeature

/**
	   	 * Fastjson忽略序列化特性
	   	 */
	   	SerializerFeature[] FASTJSON_IGNORE_SERIALIZER_FEATURES = {SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.NotWriteDefaultValue, SerializerFeature.WriteNullBooleanAsFalse,SerializerFeature.IgnoreErrorGetter, SerializerFeature.SkipTransientField,SerializerFeature.IgnoreNonFieldGetter };
	   	
		Yaml yml = new Yaml();
		String json = com.alibaba.fastjson.JSON.toJSONString(compose, FASTJSON_IGNORE_SERIALIZER_FEATURES);
		String result = yml.dumpAs(JSON.parse(json), Tag.MAP, FlowStyle.BLOCK);
		System.out.println(result);

期待的正确结果

services:
  realtime-svc:
    image: real-svc:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.32.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    deploy:
      mode: replicated
      replicas: 1
  platform-manager-svc:
    image: platform:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - HOLLYSYS_UDPIO_ENV[MINIO_FILE_PATH]=/opt/deploy/data/udpio/
    - SERVER_IP=172.21.66.180
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_SERVER_ENABLED]=false
    - HOLLYSYS_LOGIC_IMAGE=nodered:1.3.7_v1.0.21
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_PROTOCOL]=udp
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_UDP_PACKAGE_LENGTH]=1000
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    - hollysys.logic.data=/opt/m7it/logic/
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 4096M
  realtime-pipe:
    image: realpipe:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.66.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: '2.5'
version: '3.9'

相关日志输出

请复制并粘贴任何相关的日志输出。

v2.0.12 兼容模式SerializerFeature  结果正确
v2.0.13 新方式JSONWriter.Feature 结果不正确,结果为 {}
v2.0.13 兼容模式SerializerFeature 结果不正确,结果为 {}

附加信息

如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。

kervin521 avatar Sep 14 '22 02:09 kervin521

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.14-SNAPSHOT/ 问题已修复,请用2.0.14-SNAPSHOT版本帮忙验证,2.0.14版本预计在10月7日前发布

wenshao avatar Sep 14 '22 12:09 wenshao

@wenshao

v2.0.14-SNAPSHOT 兼容模式SerializerFeature --》结果:

services:
  realtime-svc:
    image: real-svc:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.32.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    deploy:
      mode: replicated
      replicas: 1
  platform-manager-svc:
    image: platform:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - HOLLYSYS_UDPIO_ENV[MINIO_FILE_PATH]=/opt/deploy/data/udpio/
    - SERVER_IP=172.21.32.180
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_SERVER_ENABLED]=false
    - HOLLYSYS_LOGIC_IMAGE=nodered:1.3.7_v1.0.21
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_PROTOCOL]=udp
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_UDP_PACKAGE_LENGTH]=1000
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    - hollysys.logic.data=/opt/m7it/logic/
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 4096M
  realtime-pipe:
    image: realpipe:1.0.21
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.22.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: '2.5'
version: '3.9'

v2.0.14-SNAPSHOT 新方式JSONWriter.Feature --》结果:

services:
  realtime-svc:
    deploy:
      mode: replicated
      replicas: 1
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.32.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    image: real-svc:1.0.21
  platform-manager-svc:
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          memory: 4096M
    environment:
    - DEBUG_VERBOSE=false
    - HOLLYSYS_UDPIO_ENV[MINIO_FILE_PATH]=/opt/deploy/data/udpio/
    - SERVER_IP=172.21.32.180
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_SERVER_ENABLED]=false
    - HOLLYSYS_LOGIC_IMAGE=nodered:1.3.7_v1.0.21
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_PROTOCOL]=udp
    - HOLLYSYS_UDPIO_ENV[HOLLYSYS_UDP_PACKAGE_LENGTH]=1000
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    - hollysys.logic.data=/opt/m7it/logic/
    image: platform:1.0.21
  realtime-pipe:
    deploy:
      mode: replicated
      replicas: 1
      resources:
        limits:
          cpus: '2.5'
    environment:
    - DEBUG_VERBOSE=false
    - SERVER_IP=172.21.22.180
    - SPRING_PROFILES_ACTIVE=test
    - NETWORK_NAME=eth0
    image: realpipe:1.0.21
version: '3.9'

输出顺序有问题

期望是【v2.0.14-SNAPSHOT 兼容模式SerializerFeature】顺序

kervin521 avatar Sep 16 '22 11:09 kervin521

https://github.com/alibaba/fastjson2/releases/tag/2.0.15 问题修复,请用新版本。输出顺序问题请帮忙开新的Issue

wenshao avatar Oct 05 '22 06:10 wenshao