我有以下代码,它将T
类型的实例编码为String
。
然后尝试将编码的字符串转换回类T
的实例。
package com.ncr.nep.messaging.notifications.tests;
import java.io.IOException;
import java.io.Serializable;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vertx.core.json.JsonObject;
class T implements Serializable {
private String channel;
//public T() { }
public T(String channel) {
super();
this.channel = channel;
}
public String getChannel() {
return channel;
}
}
public class Test {
public static void main(String[] args) {
T t = new T("abc");
String enc = JsonObject.mapFrom(t).encode();
System.out.println(enc); //prints: {"channel":"abc"}
//now back from String to T
try {
t = new ObjectMapper().readValue(enc,T.class);
System.out.println(t.getChannel());
} catch (IOException e) {
e.printStackTrace();
}
}
}
readValue方法调用抛出以下异常:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.ncr.nep.messaging.notifications.tests.T: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: {"channel":"abc"}; line: 1, column: 2]
取消注释默认构造函数可修复问题并生成正确的T
实例。
我发现很难想象这个实用工具类的设计者ObjectMapper
会对他们的客户施加如此大的限制。
请注意,我可以声明通道是最终的,在这种情况下,为了解决问题,不仅需要添加默认构造函数,而且还需要更改所有成员 - 不是最终的#39;。 ..
所以我的问题是这样的:
如果类T
的设计者明确禁止默认构造函数,该怎么办?还有什么可以做的吗?是否有注释可以做到这一点?
答案 0 :(得分:3)
您可以尝试使用@JsonCreator
注释构造函数,使用@JsonProperty
注释参数
@JsonCreator
public T(@JsonProperty("channel") String channel) {
super();
this.channel = channel;
}
答案 1 :(得分:1)
问题是天气MOXy或Jackson都需要一种方法来创建一个对象。您只提供T.class
。他们应该如何知道如何使用你的构造函数。在你的情况下,它可能很简单,但对于
public T(String a, String b) {..}
这将更加困难。在这种情况下,您可以添加另一个约束,如参数名称需要匹配json属性名称。我想这与默认的构造函数有同样的缺点。
更新: 我不知道@ Link64所描述的解决方案,但是如果这更好的话。我不知道。 MOXy提供XMLAdapter来创建对象。例如,如果T类不在您的控制之下。
答案 2 :(得分:0)
JavaBeans模式要求:
它们是可序列化的,具有零参数构造函数,并允许使用getter和setter方法访问属性。
由于这种形式的java类经常在许多框架中使用,因此用户应该期望这种形式。
解决方案"如果T的设计者禁止默认构造函数"取决于具体的用例。大多数情况下我会说这样的类不是bean,因此不是一个好的转移对象 - 你最好使用你自己的转移对象,它遵循预期的格式,并提供从/转换它的方法目标类。