我只是想序列化和反序列化简单的不可变对象,不明白为什么我不能用Jackson来做
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Value;
public class TestApplication {
@Value
static class Test {
private final String a;
}
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
String res = objectMapper.writeValueAsString(new Test("test"));
System.out.println(res);
System.out.println(objectMapper.readValue(res, Test.class));
}
}
它会因异常而失败:
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.devchallange.rogatakopita.RogatakopitaApplication$Test` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"a":"test"}"; line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at com.devchallange.rogatakopita.RogatakopitaApplication.main(RogatakopitaApplication.java:29)
我知道答案应该很简单,但这是最常见的情况,应该从盒子里起作用,不是吗?
在java中,final属性必须在构造函数中设置,并且只能稍后读取。但jackson稍后会尝试更改该属性。因此不能使用jackson填充最后一个字段。
在设计不可变类时,Jackson应该使用所有必需的参数调用构造函数。
如果你不用龙目岛,
@JsonCreator注释希望Jackson调用的构造函数
用@JsonProperty
注释构造函数参数。如果要跳过此操作,可以添加useParameterNamesModule
扩展名
例:
static class Test {
private final String a;
public Test() {
a = "default";
}
@JsonCreator // Jackson will use this constructor during deserialization
public Test(@JsonProperty("a") String a) { // @JsonProperty can be skipped if you use ParameterNamesModule annotation
this.a = a;
}
// Getter for A
}
Lombok的
@Value
注释只生成一个all-args构造函数,我们需要使用@JsonCreator进行注释。这可以通过使用
@AllArgsConstructor(onConstructor=@__(@JsonCreator))
注释类来完成。
。由于构造函数是自动生成的,我们将无法用< code>@JsonProperty
注释参数,因此,您必须使用< code > ParameterNamesModule
包含以下更改的代码段:
public class TestApplication {
@Value
@AllArgsConstructor(onConstructor = @__(@JsonCreator))
static final class Test {
private final String a;
}
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new ParameterNamesModule());
String res = objectMapper.writeValueAsString(new Test("test"));
System.out.println(res);
System.out.println(objectMapper.readValue(res, Test.class));
}
}
下面是参数名模块的maven依赖性。
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
<version>2.9.8</version>
<scope>compile</scope>
</dependency>
这是密码 输出量 我的问题是: 为什么jackson在完成构建后修改了没有setter的私有final字段?如果这是有意的,我该如何关闭它 非常感谢。
问题内容: 在Java中进行序列化后,是否可以将字段设置为任何非默认值?我的用例是一个缓存变量- 这就是为什么。我也有一个习惯,即不要更改字段(即,地图的内容已更改,但对象本身保持不变)。但是,这些属性似乎是矛盾的- 尽管编译器允许这样的组合,但除反序列化之后,我无法将字段设置为任何值。 我尝试了以下操作,但没有成功: 简单的字段初始化(如示例所示):这是我通常所做的,但是在未序列化之后似乎没有发
问题内容: 我正在尝试使用JSON(使用simplejson)序列化python对象列表,并收到以下错误:对象“不可JSON序列化”。 该类是一个简单的类,其字段只有整数,字符串和浮点数,并且从一个父超类继承相似的字段,例如: foo,bar是我上面提到的简单类型。唯一棘手的事情是,ChildClass有时具有一个字段,该字段引用另一个对象(类型不是ParentClass或ChildClass)。
问题内容: 我想知道下面的代码是否有意义,因为编译器会警告“空白的最终字段对象可能尚未初始化”。有更好的方法吗? 问题答案: 我将字段定为final,并强制构造函数将值向上传递:
问题内容: 使用JSON定义的样子,为了将其反序列化为对象,我需要在我的类上创建一个名为“ event”的属性,这是一个C#关键字。还有另一种方法可以告诉它字段名称是什么? 这是JSON的示例: {event:123 data:{“ data”:“ 0D0401”,“ ttl”:“ 60”,“ published_at”:“ 2014-04-16T18:04:42.446Z”,“ id”:“ 48
问题内容: 我有一个定义不可变值类型的类,现在需要对其进行序列化。不变性来自构造函数中设置的最终字段。我已经尝试过序列化,并且它可以工作(令人惊讶的是?)-但我不知道如何进行。 这是课程的一个例子 鉴于该类没有no arg构造函数,如何实例化它并设置最终字段? (顺便说一句,我注意到了该类,尤其是因为IDEA并未为此类生成“ no serialVersionUID”检查警告,但尚未为我刚刚使其可序