java字段不序列化注解_java – Jackson,用私有字段反序列化类和没有注释的arg构造函数...

可以使用私有字段和自定义参数构造函数反序列化为不使用注释而不使用Jackson修改类的类?

我知道在使用这种组合时杰克逊有可能:1)Java 8,2)用“-parameters”选项编译,3)参数名称与JSON匹配.但是在没有所有这些限制的情况下,默认情况下也可以在GSON中使用.

例如:

public class Person {

private final String firstName;

private final String lastName;

private final int age;

public Person(String firstName, String lastName, int age) {

this.firstName = firstName;

this.lastName = lastName;

this.age = age;

}

public static void main(String[] args) throws IOException {

String json = "{firstName: \"Foo\", lastName: \"Bar\", age: 30}";

System.out.println("GSON: " + deserializeGson(json)); // works fine

System.out.println("Jackson: " + deserializeJackson(json)); // error

}

public static Person deserializeJackson(String json) throws IOException {

ObjectMapper mapper = new ObjectMapper();

mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

return mapper.readValue(json, Person.class);

}

public static Person deserializeGson(String json) {

Gson gson = new GsonBuilder().create();

return gson.fromJson(json, Person.class);

}

}

对于GSON来说这很好,但杰克逊抛出:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `jacksonParametersTest.Person` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

at [Source: (String)"{firstName: "Foo", lastName: "Bar", age: 30}"; line: 1, column: 2]

at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)

这在GSON中是可能的,所以我希望杰克逊必须有一些方法而不修改Person类,没有Java 8,也没有明确的自定义反序列化器.有人知道解决方案吗?

– 更新,其他信息

Gson似乎跳过了参数构造函数,因此它必须使用反射在幕后创建一个无参数构造函数.

此外,即使没有“-parameters”编译器标志,也存在能够为Kotlin数据类执行此操作的Kotlin Jackson module.

所以奇怪的是,Java Jackson似乎并不存在这样的解决方案.

这是Kotlin Jackson提供的(漂亮而干净的)解决方案(IMO也可以通过自定义模块在Java Jackson中使用):

val mapper = ObjectMapper()

.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)

.registerModule(KotlinModule())

val person: Person = mapper.readValue(json, Person::class.java)

解决方法:

带有混合注释的解决方案

您可以使用混合注释.当修改类不是一个选项时,它是一个很好的选择.您可以将其视为在运行时添加更多注释的面向方面的方式,以增加静态定义的注释.

假设您的Person类定义如下:

public class Person {

private final String firstName;

private final String lastName;

private final int age;

public Person(String firstName, String lastName, int age) {

this.firstName = firstName;

this.lastName = lastName;

this.age = age;

}

// Getters omitted

}

首先定义一个混合注释抽象类:

public abstract class PersonMixIn {

PersonMixIn(@JsonProperty("firstName") String firstName,

@JsonProperty("lastName") String lastName,

@JsonProperty("age") int age) {

}

}

然后配置ObjectMapper以将定义的类用作POJO的混合:

ObjectMapper mapper = new ObjectMapper();

mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);

mapper.addMixIn(Person.class, PersonMixIn.class);

并反序列化JSON:

String json = "{firstName: \"Foo\", lastName: \"Bar\", age: 30}";

Person person = mapper.readValue(json, Person.class);

标签:jackson2,jackson-databind,java,json,jackson

来源: https://codeday.me/bug/20190928/1829733.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值