V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
OpenYanxi
V2EX  ›  问与答

请教一个 fastjson 1 版本完全可以正常解析为对象,但是 fastjson 2 只能解析一个字段的值,其他字段都没有解析, list 也没解析

  •  
  •   OpenYanxi · 48 天前 · 626 次点击
    这是一个创建于 48 天前的主题,其中的信息可能已经有所发展或是发生改变。

    JDK 版本使用的 17 , 使用 JDK 11 , 也是一样的结果。

    使用的 fast json:

    1.x 版本使用的:

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.83</version>
            </dependency>
    

    2.x 版本使用的:

            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>2.0.53</version>
            </dependency>
    

    原始的 json 字符串如下, (用 bejson 校验过,是对的)

    {
    	"ListBucketResult":{
    		"xmlns":"http://s3.amazonaws.com/doc/2006-03-01/",
    		"Name":"a_name",
    		"Prefix":"",
    		"Marker":"",
    		"MaxKeys":1000,
    		"IsTruncated":false,
    		"Contents":[
    			{
    				"Key":"E.jpg",
    				"LastModified":"2024-11-01T13:09:17.000Z",
    				"ETag":"\"tag-1\"",
    				"Size":26579,
    				"Owner":{
    					"ID":"xx1",
    					"DisplayName":"c_name"
    				},
    				"StorageClass":"STANDARD"
    			},
    			{
    				"Key":"地球.jpg",
    				"LastModified":"2024-11-07T13:56:43.000Z",
    				"ETag":"\"tag-2\"",
    				"Size":26579,
    				"Owner":{
    					"ID":"xx2",
    					"DisplayName":"c_name"
    				},
    				"StorageClass":"STANDARD"
    			}
    		]
    	}
    }
    
    

    准备接收的实体如下:

    package com.code.domain;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    import java.util.List;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class ListBucketResult implements Serializable {
    
        /**
         * 包装体
         */
        private ListBucketResultContent ListBucketResult;
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class ListBucketResultContent implements Serializable {
            private String xmlns;
            private String name;
            private String prefix;
            private String marker;
            private int maxKeys;
            private boolean isTruncated;
            private List<Contents> contents;
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Contents implements Serializable {
            private String key;
            private String lastModified;
            private String eTag;
            private int size;
            private Owner owner;
            private String storageClass;
    
            @Data
            @NoArgsConstructor
            @AllArgsConstructor
            public static class Owner {
                private String id;
                private String displayName;
            }
        }
    }
    

    对 fastjson 1 测试类:

    package com.code;
    
    import com.alibaba.fastjson.JSON;
    import com.code.s3xmlgateway.domain.ListBucketResult;
    import org.junit.jupiter.api.Test;
    
    public class Fast1Test {
        @Test
        public void testFast1()
        {
            String rawJsonStr = "{\n" +
                    "\t\"ListBucketResult\":{\n" +
                    "\t\t\"xmlns\":\"http://s3.amazonaws.com/doc/2006-03-01/\",\n" +
                    "\t\t\"Name\":\"a_name\",\n" +
                    "\t\t\"Prefix\":\"\",\n" +
                    "\t\t\"Marker\":\"\",\n" +
                    "\t\t\"MaxKeys\":1000,\n" +
                    "\t\t\"IsTruncated\":false,\n" +
                    "\t\t\"Contents\":[\n" +
                    "\t\t\t{\n" +
                    "\t\t\t\t\"Key\":\"E.jpg\",\n" +
                    "\t\t\t\t\"LastModified\":\"2024-11-01T13:09:17.000Z\",\n" +
                    "\t\t\t\t\"ETag\":\"\\\"tag-1\\\"\",\n" +
                    "\t\t\t\t\"Size\":26579,\n" +
                    "\t\t\t\t\"Owner\":{\n" +
                    "\t\t\t\t\t\"ID\":\"xx1\",\n" +
                    "\t\t\t\t\t\"DisplayName\":\"c_name\"\n" +
                    "\t\t\t\t},\n" +
                    "\t\t\t\t\"StorageClass\":\"STANDARD\"\n" +
                    "\t\t\t},\n" +
                    "\t\t\t{\n" +
                    "\t\t\t\t\"Key\":\"地球.jpg\",\n" +
                    "\t\t\t\t\"LastModified\":\"2024-11-07T13:56:43.000Z\",\n" +
                    "\t\t\t\t\"ETag\":\"\\\"tag-2\\\"\",\n" +
                    "\t\t\t\t\"Size\":26579,\n" +
                    "\t\t\t\t\"Owner\":{\n" +
                    "\t\t\t\t\t\"ID\":\"xx2\",\n" +
                    "\t\t\t\t\t\"DisplayName\":\"c_name\"\n" +
                    "\t\t\t\t},\n" +
                    "\t\t\t\t\"StorageClass\":\"STANDARD\"\n" +
                    "\t\t\t}\n" +
                    "\t\t]\n" +
                    "\t}\n" +
                    "}";
    
            ListBucketResult listBucketResult = JSON.parseObject(rawJsonStr, ListBucketResult.class);
    
            System.out.println(listBucketResult);
    
        }
    }
    
    

    运行结果:

    ListBucketResult(ListBucketResult=ListBucketResult.ListBucketResultContent(xmlns=http://s3.amazonaws.com/doc/2006-03-01/, name=a_name, prefix=, marker=, maxKeys=1000, isTruncated=false, contents=[ListBucketResult.Contents(key=E.jpg, lastModified=2024-11-01T13:09:17.000Z, eTag="tag-1", size=26579, owner=com.code.s3xmlgateway.domain.ListBucketResult$Contents$Owner@188715b5, storageClass=STANDARD), ListBucketResult.Contents(key=地球.jpg, lastModified=2024-11-07T13:56:43.000Z, eTag="tag-2", size=26579, owner=com.code.s3xmlgateway.domain.ListBucketResult$Contents$Owner@1ea9f6af, storageClass=STANDARD)]))
    

    如上可以看出,运行结果一切正常,可以正常解析为对象的值

    针对 fastjson 2 的测试类:

    package com.code;
    
    import com.alibaba.fastjson2.JSON;
    import com.code.s3xmlgateway.domain.ListBucketResult;
    import org.junit.jupiter.api.Test;
    
    public class Fast2Test {
    
        @Test
        public void testFast2()
        {
            String rawJsonStr = "{\n" +
                    "\t\"ListBucketResult\":{\n" +
                    "\t\t\"xmlns\":\"http://s3.amazonaws.com/doc/2006-03-01/\",\n" +
                    "\t\t\"Name\":\"a_name\",\n" +
                    "\t\t\"Prefix\":\"\",\n" +
                    "\t\t\"Marker\":\"\",\n" +
                    "\t\t\"MaxKeys\":1000,\n" +
                    "\t\t\"IsTruncated\":false,\n" +
                    "\t\t\"Contents\":[\n" +
                    "\t\t\t{\n" +
                    "\t\t\t\t\"Key\":\"E.jpg\",\n" +
                    "\t\t\t\t\"LastModified\":\"2024-11-01T13:09:17.000Z\",\n" +
                    "\t\t\t\t\"ETag\":\"\\\"tag-1\\\"\",\n" +
                    "\t\t\t\t\"Size\":26579,\n" +
                    "\t\t\t\t\"Owner\":{\n" +
                    "\t\t\t\t\t\"ID\":\"xx1\",\n" +
                    "\t\t\t\t\t\"DisplayName\":\"c_name\"\n" +
                    "\t\t\t\t},\n" +
                    "\t\t\t\t\"StorageClass\":\"STANDARD\"\n" +
                    "\t\t\t},\n" +
                    "\t\t\t{\n" +
                    "\t\t\t\t\"Key\":\"地球.jpg\",\n" +
                    "\t\t\t\t\"LastModified\":\"2024-11-07T13:56:43.000Z\",\n" +
                    "\t\t\t\t\"ETag\":\"\\\"tag-2\\\"\",\n" +
                    "\t\t\t\t\"Size\":26579,\n" +
                    "\t\t\t\t\"Owner\":{\n" +
                    "\t\t\t\t\t\"ID\":\"xx2\",\n" +
                    "\t\t\t\t\t\"DisplayName\":\"c_name\"\n" +
                    "\t\t\t\t},\n" +
                    "\t\t\t\t\"StorageClass\":\"STANDARD\"\n" +
                    "\t\t\t}\n" +
                    "\t\t]\n" +
                    "\t}\n" +
                    "}";
    
            ListBucketResult listBucketResult = JSON.parseObject(rawJsonStr, ListBucketResult.class);
    
            System.out.println(listBucketResult);
        }
    }
    

    运行结果:

    ListBucketResult(ListBucketResult=ListBucketResult.ListBucketResultContent(xmlns=http://s3.amazonaws.com/doc/2006-03-01/, name=null, prefix=null, marker=null, maxKeys=0, isTruncated=false, contents=null))
    

    使用 fastjson2 可以看到,只解析了 xmlns 这个字段的值; 我尝试在原始的 json 删掉这个 xmlns 字段,结果会是其他字段一样不能解析,list 也无法解析。

    自己查阅了 fastjson 的文档 和 升级文档,没找到类似的说明

    因此请教下社区的各位大神, 看这是什么情况? 谢谢

    5 条回复    2024-11-21 19:36:29 +08:00
    kokutou
        1
    kokutou  
       48 天前 via Android   ❤️ 2
    你就说快不快吧
    V2Micheal
        2
    V2Micheal  
       47 天前
    似乎是没有设置 setter 和 getter ,同时 JSON 字段名和变量名对不上,要加上 @JSONField ,类似这样:

    ```
    @JSONField (name = "xmlns")
    Private String xmlns;

    @JSONField(name = "Name")
    private String name;
    ```

    我这边试了下加上就可以解析了,具体原理也不太清楚,好久没用 java 了。
    OpenYanxi
        3
    OpenYanxi  
    OP
       35 天前
    @V2Micheal

    ( 1 )@Data
    @NoArgsConstructor
    @AllArgsConstructor lombok 的注解会自动生成 setter 和 getter

    ( 2 )谢谢, 看来 fastjson 2 大小写敏感了,fastjson 1 是不敏感的
    OpenYanxi
        4
    OpenYanxi  
    OP
       35 天前
    @V2Micheal 感谢指点, 沿着你的思路:

    找到这个:
    OpenYanxi
        5
    OpenYanxi  
    OP
       35 天前
    @V2Micheal 感谢指点, 沿着你的思路:

    找到这个: https://github.com/alibaba/fastjson/issues/1442

    找到另外一个 fastjson 2 开启跟 fastjson 1 一样效果的一个参数:

    JSON.parseObject(rawJsonStr, ListBucketResult.class, SupportSmartMatch);

    这样子就可以了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3490 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 57ms · UTC 00:08 · PVG 08:08 · LAX 16:08 · JFK 19:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.