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

13 天前
 OpenYanxi

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 的文档 和 升级文档,没找到类似的说明

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

409 次点击
所在节点    问与答
5 条回复
kokutou
13 天前
你就说快不快吧
V2Micheal
12 天前
似乎是没有设置 setter 和 getter ,同时 JSON 字段名和变量名对不上,要加上 @JSONField ,类似这样:

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

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

我这边试了下加上就可以解析了,具体原理也不太清楚,好久没用 java 了。
OpenYanxi
8 小时 57 分钟前
@V2Micheal

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

( 2 )谢谢, 看来 fastjson 2 大小写敏感了,fastjson 1 是不敏感的
OpenYanxi
8 小时 42 分钟前
@V2Micheal 感谢指点, 沿着你的思路:

找到这个:
OpenYanxi
8 小时 41 分钟前
@V2Micheal 感谢指点, 沿着你的思路:

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

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

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

这样子就可以了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1087762

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX