简体   繁体   English

无法使用 Jackson 从对象值(无基于委托或基于属性的创建者)反序列化

[英]Cannot deserialize from Object value (no delegate- or property-based Creator) using Jackson

I'm trying to deserialise below JSON payload with Jackson :我正在尝试使用JacksonJSON有效负载下反序列化:

{"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也会处理它们。
  • If constructor does not fit to 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.

相关问题 Spring Kafka 消费者给出错误“无法从对象值反序列化(没有基于委托或基于属性的创建者” - Spring Kafka consumer Gives an error " cannot deserialize from Object value (no delegate- or property-based Creator" 即使存在默认构造函数,也无法从对象值(没有基于委托或基于属性的创建者)反序列化 - cannot deserialize from Object value (no delegate- or property-based Creator) even with default constructor present Jackson 根据属性名称反序列化 - Jackson deserialize based on property name 杰克逊将json属性反序列化为对象 - Jackson deserialize json property into object 重构帮助…基于属性的对象或许多成员字段? - Refactoring help…property-based object or lots of member fields? 使用Jackson将带有私有列表属性的JSON数组反序列化为对象 - Deserialize JSON Array to Object with private list property using Jackson 使用Jackson反序列化包含在具有未知属性名称的对象中的JSON - Deserialize a JSON wrapped in an object with an unknown property name using Jackson Jackson 使用属性名称作为值将 JSON 反序列化为泛型类型以从注册表中获取类型 - Jackson deserialize JSON into generic type using property name as value to fetch type from registry “JSON 解析错误:无法构造实例(尽管至少存在一个 Creator):无法从 Object 值反序列化 - SpringBoot - "JSON parse error: Cannot construct instance of (although at least one Creator exists): cannot deserialize from Object value - SpringBoot Cannot deserialize ArrayList object out of String from nested XML to Java POJO using Jackson - Cannot deserialize ArrayList object out of String from nested XML to Java POJO using Jackson
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM