alibaba / fastjson

FASTJSON 2.0.x has been released, faster and more secure, recommend you upgrade.
https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn
Apache License 2.0
25.74k stars 6.5k forks source link

1.2.70升级至1.2.83问题:JSONField的别名设置后,属性名格式失效 #4132

Open CrazyHZM opened 2 years ago

CrazyHZM commented 2 years ago

从1.2.70版本升级到1.2.83版本,发现早期版本JSONField的别名和属性名会同时生效,而在最新的版本中,只会按照别名的格式进行序列化和发序列化。 比如

@JSONField( name="first_name")
private String firstName;

只能反序列化下划线格式的数据,而并不在支持小驼峰式。这是在某个版本迭代中正常的变更吗?

wangyongtao7725 commented 2 years ago

没懂您的意思,能够举出存在问题的case吗

876377620 commented 2 years ago
@JSONField(name = "order_no")
private String orderNo;

1.2.70反序列化时 orderNo、order_no 都有值 1.2.83反序列化时 只有 order_no 有值 orderNo为null 不向老版本兼容吗

CrazyHZM commented 2 years ago
@JSONField(name = "order_no")
private String orderNo;

1.2.70反序列化时 orderNo、order_no 都有值 1.2.83反序列化时 只有 order_no 有值 orderNo为null 不向老版本兼容吗

是这个case。

wangyongtao7725 commented 2 years ago
@JSONField(name = "order_no")
private String orderNo;

1.2.70反序列化时 orderNo、order_no 都有值 1.2.83反序列化时 只有 order_no 有值 orderNo为null 不向老版本兼容吗

是这个case。

是指需要反序列化的JSON同时存在orderNo和order_no?

CrazyHZM commented 2 years ago

字符串反序列化转Java对象时,字符串内只带有orderNo的值,但是反序列化后得到的对象属性值却为null。在低版本中是可以反序列化得到对应的值的。

wangyongtao7725 commented 2 years ago

明白了,问题是现在只能根据@JSONField的name属性里面的值去反序列化了,而不能根据类中字段命名的值,老版本是兼容的。

CrazyHZM commented 2 years ago

老版本是兼容的,是指这个是一个问题需要修复吗?

876377620 commented 2 years ago
@JSONField(name = "order_no")
private String orderNo;

1.2.70反序列化时 orderNo、order_no 都有值 1.2.83反序列化时 只有 order_no 有值 orderNo为null 不向老版本兼容吗

是这个case。

是指需要反序列化的JSON同时存在orderNo和order_no?

是的

wenshao commented 2 years ago

1.2.71修改了这个行为,如果你要兼容,可以配置alternateNames,比如

@JSONField( name="first_name", alternateNames="firstName")
private String firstName;
CrazyHZM commented 2 years ago

@wenshao 新增了这个alternateNames配置后,也没有效果,依旧反序列化出来为null

aliiohs commented 2 years ago

@wenshao 新增了这个alternateNames配置后,也没有效果,依旧反序列化出来为null 我刚试了一下,是可以的

class JsonTest {

@JSONField(name = "first_name", alternateNames = "firstName")
private String firstName;

String getFirstName() {
    return firstName
}

void setFirstName(String firstName) {
    this.firstName = firstName
}

}

public static void main(String[] args) {

    String s = "{\"first_name\":\"xxxx\"}";
    JsonTest jsonTest = JSONObject.parseObject(s, JsonTest.class);
    System.out.println(jsonTest);

}
CrazyHZM commented 2 years ago

"{\"first_name\":\"xxxx\"}"; 如果改成"{\"firstName\":\"xxxx\"}"; 好像就不行了

lonelystone545 commented 2 years ago

1.2.71修改了这个行为,如果你要兼容,可以配置alternateNames,比如

@JSONField( name="first_name", alternateNames="firstName")
private String firstName;

刚刚测试了一把,可以使用的。加了alternateNames,反序列化没问题

CrazyHZM commented 2 years ago

1.2.71修改了这个行为,如果你要兼容,可以配置alternateNames,比如

@JSONField( name="first_name", alternateNames="firstName")
private String firstName;

刚刚测试了一把,可以使用的。加了alternateNames,反序列化没问题

@wy545 尝试过"{"first_name":"xxxx"}"; 改成"{"firstName":"xxxx"}"吗

xiongjunming commented 2 years ago

刚试了alternateNames是完全生效的。上面JsonTest示例代码有点问题,setter方法改成public就行了。` public class JsonTest {

@JSONField(name = "first_name", alternateNames = "firstName")
private String firstName;

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

@Override
public String toString() {
    return "JsonTest{" +
        "firstName='" + firstName + '\'' +
        '}';
}

public static void main(String[] args) {

    String s = "{\"firstName\":\"xxxx\"}";
    JsonTest jsonTest = JSONObject.parseObject(s, JsonTest.class);
    System.out.println(jsonTest);

}

}`

CrazyHZM commented 2 years ago

刚试了alternateNames是完全生效的。上面JsonTest示例代码有点问题,setter方法改成public就行了。` public class JsonTest {

@JSONField(name = "first_name", alternateNames = "firstName")
private String firstName;

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

@Override
public String toString() {
    return "JsonTest{" +
        "firstName='" + firstName + '\'' +
        '}';
}

public static void main(String[] args) {

    String s = "{\"firstName\":\"xxxx\"}";
    JsonTest jsonTest = JSONObject.parseObject(s, JsonTest.class);
    System.out.println(jsonTest);

}

}`


public class JsonTest{
@JSONField(name = "first_name", alternateNames = "firstName")
private String firstName;
public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public JsonTest(String firstName) {
    this.firstName = firstName;
}

@Override
public String toString() {
    return "JsonTest{" +
            "firstName='" + firstName + '\'' +
            '}';
}

public static void main(String[] args) {

    String s = "{\"firstName\":\"xxxx\"}";
    JsonTest jsonTest = JSONObject.parseObject(s, JsonTest.class);
    System.out.println(jsonTest);

}

}


发现加了构造函数就失效了 @wenshao @xiongjunming 
zhangpeng0927 commented 1 year ago

1.2.71修改了这个行为,如果你要兼容,可以配置alternateNames,比如

@JSONField( name="first_name", alternateNames="firstName")
private String firstName;

@wenshao 除了配置alternateNames没其他办法了吗?会选择在高版本恢复这个行为吗?增加alternateNames这个改动对于业务大量使用fastjson来说改动太大了。