fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

[BUG] 对于字母名称字段,在序列化/反序列化含大小写字符串时的处理方式不一致

Open Cooperzzy opened this issue 1 year ago • 3 comments

问题描述

类似 #546 和 #2523 ,fastjson 和 fastjson2 在序列化/反序列化含大小写字符串时的处理方式不一致

环境信息

  • OS信息: [MacOS 12.7.4 M1 Pro 16 GB]
  • JDK信息: [Openjdk 17.0.6]
  • 版本信息:[Fastjson/Fastjson2 2.0.49]

重现步骤


import com.alibaba.fastjson2.JSON;
import lombok.Data;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue546Mutated_38 {

    @Test
    public void testMutated() {
        A vo = new A();
        vo.setCId("2");
        assertEquals("{\"cId\":\"2\"}", JSON.toJSONString(vo));
    }

    @Test
    public void testMutated1() {
        A vo = new A();
        vo.setCId("2");
        assertEquals("{\"cId\":\"2\"}", com.alibaba.fastjson.JSON.toJSONString(vo));
    }

    @Data
    public static class A {
        private String uId;
        private String cId;
    }

    @Test
    public void test() {
        assertEquals("abc", JSON.parseObject("{\"uId\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
        assertEquals("abc", JSON.parseObject("{\"UId\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
        assertEquals("abc", JSON.parseObject("{\"UiD\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
    }

    @Test
    public void test1() {
        assertEquals("abc", com.alibaba.fastjson.JSON.parseObject("{\"uId\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
        assertEquals("abc", com.alibaba.fastjson.JSON.parseObject("{\"UId\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
        assertEquals("abc", com.alibaba.fastjson.JSON.parseObject("{\"UiD\":\"abc\"}", Issue546Mutated_561.C.class).getUId());
    }

    public static class C {
        private String uId;

        public String getUId() {
            return uId;
        }

        public void setUId(String uId) {
            this.uId = uId;
        }
    }
}

期待的正确结果

期望fastjson和fastjson2的在字段上的处理方式应保持一致

相关日志输出

Expected :{"cId":"2"} Actual :{"CId":"2"}

Expected :abc Actual :null

Cooperzzy avatar May 06 '24 07:05 Cooperzzy

fastjson2采用的是和JavaBean一样的行为,如同JDK这个方法java.beans.Introspector#decapitalize的实现。如果希望fastjson2保持和fastjson1一样的行为,需要配置单独的ObjectWriterProvider:

ObjectWriterProvider provider = new ObjectWriterProvider(PropertyNamingStrategy.CamelCase1x);

        Bean1 bean = new Bean1();
        bean.age = 20;
        bean.oAuthName = "xxx";
        String str = JSON.toJSONString(bean, JSONFactory.createWriteContext(provider));
        assertEquals("{\"age\":20,\"oAuthName\":\"xxx\"}", str);

或者使用NamingFilter,如下:

Student test = new Student("z", 12, null);
NameFilter nameFilter = NameFilter.of(PropertyNamingStrategy.CamelCase1x);
String res = JSON.toJSONString(test, nameFilter, JSONWriter.Feature.WriteNullStringAsEmpty);

wenshao avatar May 07 '24 12:05 wenshao

配置ObjectWriterProvider没有问题,谢谢温少

Cooperzzy avatar May 07 '24 13:05 Cooperzzy

创建ObjectWriterProvider需要注意要单例化处理,否则会和fastjson 1.x那样,会导致性能慢并且class gc

wenshao avatar May 07 '24 17:05 wenshao