[英]Cannot deserialize from Object value (no delegate- or property-based Creator) using Jackson
I'm trying to deserialise below JSON
payload with Jackson
:我正在尝试使用Jackson
在JSON
有效负载下反序列化:
{"code":null,"reason":"subscription yet available","message":"{ Message:\"subscription yet available\", SubscriptionUID:\"46b62920-c519-4555-8973-3b28a7a29463\" }"}
but I'm getting this JsonMappingException
:但我收到了这个JsonMappingException
:
Cannot construct instance of `com.ids.utilities.DeserializeSubscription` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"code":null,"reason":"subscription yet available","message":"{ Message:\"subscription yet available\", SubscriptionUID:\"46b62920-c519-4555-8973-3b28a7a29463\" }"}"; line: 1, column: 2]
I've created two classes.我创建了两个类。 The first class:第一堂课:
import lombok.Data;
@Data
public class DeserializeSubscription {
private String code;
private String reason;
private MessageSubscription message;
public DeserializeSubscription(String code, String reason, MessageSubscription message) {
super();
this.code = code;
this.reason = reason;
this.message = message;
}
and the second class和第二类
import lombok.Data;
@Data
public class MessageSubscription {
private String message;
private String subscriptionUID;
public MessageSubscription(String message, String subscriptionUID) {
super();
this.message = message;
this.subscriptionUID = subscriptionUID;
}
In the main class:在主类中:
try
{
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
DeserializeSubscription desSub=null;
desSub=mapper.readValue(e.getResponseBody(), DeserializeSubscription.class);
System.out.println(desSub.getMessage().getSubscriptionUID());
}
catch (JsonParseException e1) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (JsonMappingException e1) {
System.out.println(e1.getMessage());
e.printStackTrace();
}
catch (IOException e1) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I've found this solution but I didn't work it https://facingissuesonit.com/2019/07/17/com-fasterxml-jackson-databind-exc-invaliddefinitionexception-cannot-construct-instance-of-xyz-no-creators-like-default-construct-exist-cannot-deserialize-from-object-value-no-delega/我找到了这个解决方案,但我没有工作https://faceissuesonit.com/2019/07/17/com-fasterxml-jackson-databind-exc-invaliddefinitionexception-cannot-construct-instance-of-xyz-no -creators-like-default-construct-exist-cannot-deserialize-from-object-value-no-delega/
The jackson maven I'm using in my application我在我的应用程序中使用的 jackson maven
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
The message is pretty clear: (no Creators, like default construct, exist)
消息非常清楚:( (no Creators, like default construct, exist)
you need to add a no argument constructor to the class or the NoArgsConstructor
annotation:您需要向类或NoArgsConstructor
注释添加无参数构造函数:
@Data
public class DeserializeSubscription {
public DeserializeSubscription (){}
or或者
@NoArgsConstructor
@Data
public class DeserializeSubscription {
You have to consider few cases:您必须考虑几种情况:
message
field in JSON
is primitive String
. JSON
message
字段是原始String
。 On POJO
level it is an MessageSubscription
object.在POJO
级别,它是一个MessageSubscription
对象。message
value in JSON
contains unquoted property names which is illegal but Jackson
handles them as well. JSON
中的message
值包含不带引号的属性名称,这是非法的,但Jackson
也会处理它们。JSON
we need to configure it using annotations.如果构造函数不适合JSON
我们需要使用注释对其进行配置。 To handle unquoted names we need to enable ALLOW_UNQUOTED_FIELD_NAMES feature.要处理未加引号的名称,我们需要启用ALLOW_UNQUOTED_FIELD_NAMES功能。 To handle mismatch between JSON
payload and POJO
we need to implement custom deserialiser for MessageSubscription
class.为了处理JSON
负载和POJO
之间的不匹配,我们需要为MessageSubscription
类实现自定义反序列化器。
Custom deserialiser could look like this:自定义反序列化器可能如下所示:
class MessageSubscriptionJsonDeserializer extends JsonDeserializer<MessageSubscription> {
@Override
public MessageSubscription deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
final String value = p.getValueAsString();
final Map<String, String> map = deserializeAsMap(value, (ObjectMapper) p.getCodec(), ctxt);
return new MessageSubscription(map.get("Message"), map.get("SubscriptionUID"));
}
private Map<String, String> deserializeAsMap(String value, ObjectMapper mapper, DeserializationContext ctxt) throws IOException {
final MapType mapType = ctxt.getTypeFactory().constructMapType(Map.class, String.class, String.class);
return mapper.readValue(value, mapType);
}
}
Now, we need to customise DeserializeSubscription
's constructor:现在,我们需要自定义DeserializeSubscription
的构造函数:
@Data
class DeserializeSubscription {
private String code;
private String reason;
private MessageSubscription message;
@JsonCreator
public DeserializeSubscription(
@JsonProperty("code") String code,
@JsonProperty("reason") String reason,
@JsonProperty("message") @JsonDeserialize(using = MessageSubscriptionJsonDeserializer.class) MessageSubscription message) {
super();
this.code = code;
this.reason = reason;
this.message = message;
}
}
Example how to use it:示例如何使用它:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.type.MapType;
import lombok.Data;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
mapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
DeserializeSubscription value = mapper.readValue(jsonFile, DeserializeSubscription.class);
System.out.println(value);
}
}
For provided JSON
payload above example prints:对于上面提供的JSON
有效负载,示例打印:
DeserializeSubscription(code=null, reason=subscription yet available, message=MessageSubscription(message=subscription yet available, subscriptionUID=46b62920-c519-4555-8973-3b28a7a29463))
This can happen due to using unsupported data types, eg unsigned integers.由于使用了不受支持的数据类型,例如无符号整数,可能会发生这种情况。
I received this error when deserializing a JSON object that had a ULong field.我在反序列化具有 ULong 字段的 JSON 对象时收到此错误。 and worked around it by changing the field type to normal signed (long) integer.并通过将字段类型更改为正常的有符号(长)整数来解决它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.