简体   繁体   中英

Jackson deserialization error: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field

The I am getting the above exception on a model which does contain the field. The exception also appears to be sporadic which is further cause for concern. I certainly can wrap the class with

JsonIgnoreProperties(ignoreUnknown = true)

But certainly will not want to do this.

The model is as follows:

public class OrderCommand {

    private int orderId;
    private String item;
    private int numberOfItems;
    private double price;
    private Payment payment;
    private String[] packages;
    private List<Shipment> shipment;
    private String orderStatus;

    public OrderCommand(){}

    public OrderCommand(String item, int numberOfItems, double price, OffsetDateTime timeStamp) {

        this.item = item;
        this.numberOfItems = numberOfItems;
        this.price = price;
        orderId = timeStamp.getNano();
    }

    public OrderCommand setOrderStatus(String orderStatus) {
        this.orderStatus = orderStatus;
        return this;
    }

    public String getOrderStatus(){
        return this.orderStatus;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public int getNumberOfItems() {
        return numberOfItems;
    }

    public void setNumberOfItems(int numberOfItems) {
        this.numberOfItems = numberOfItems;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public void setPackages(String[] packages) {
        this.packages = packages;
    }

    public String[] getPackages(){
        return packages;
    }

    public void setShipment(List<Shipment> shipment) {
        this.shipment = shipment;
    }

    public List<Shipment> getShipment(){
        return this.shipment;
    }

    public String toString(){
        return ReflectionToStringBuilder.toString(this);
    }

    public Payment getPayment() {
        return payment;
    }

    public OrderCommand setPayment(Payment payment) {
        this.payment = payment;
        return this;
    }
}

and the offending JSON is:

{
    "item": "headphones",
    "price": 200.0,
    "orderId": 600000000,
    "payment": {
        "charge": 200.0,
        "paymentMethod": "VISA",
        "success": true,
        "failureReason": null,
        "accountNumber": "1234"
    },
    "packages": [
        "headphones.package0",
        "headphones.package1"
    ],
    "shipment": null,
    "orderStatus": "PAYMENT-RECEIVED",
    "numberOfItems": 2
}

How do I prevent this from happening and get deserialization happening reliably?

EDIT 1: The exception indicates that the payment field is not recognized. The payment class is:

public class Payment {

    private double charge;
    private String paymentMethod;
    private boolean success;
    private String failureReason;
    private String accountNumber;

    public double getCharge() {
        return charge;
    }

    public Payment setCharge(double charge) {
        this.charge = charge;
        return this;
    }

    public String getPaymentMethod() {
        return paymentMethod;
    }

    public Payment setPaymentMethod(String paymentMethod) {
        this.paymentMethod = paymentMethod;
        return this;
    }

    public boolean getSuccess() {
        return success;
    }

    public Payment setSuccess(boolean success) {
        this.success = success;
        return this;
    }

    public String getFailureReason() {
        return failureReason;
    }

    public Payment setFailureReason(String failureReason) {
        this.failureReason = failureReason;
        return this;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public Payment setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
        return this;
    }
}

EDIT 2

Full exception is as follows:

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"payment\" (class com.sailpoint.rss.rss_service.model.OrderCommand), not marked as ignorable (8 known properties: \"numberOfItems\", \"item\", \"orderId\", \"shipment\", \"packages\", \"orderProcessingTime\", \"orderProcessed\", \"price\"])
at [Source: (String)\"{\"item\":\"headphones\",\"price\":200.0,\"orderId\":36000000,\"payment\":{\"charge\":200.0,\"paymentMethod\":\"VISA\",\"success\":true,\"failureReason\":null,\"accountNumber\":\"1234\"},\"packages\":null,\"shipment\":null,\"orderStatus\":\"PAYMENT-RECEIVED\",\"numberOfItems\":2}\"; line: 1, column: 66] (through reference chain: com.sailpoint.rss.rss_service.model.OrderCommand[\"payment\"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3005)
at io.zeebe.client.impl.ZeebeObjectMapper.fromJson(ZeebeObjectMapper.java:36)

Did not also mention but happens sporadically.

My experienced guess (in the absence of more details) is that the problem is with either orderStatus or payment because both setOrderStatus and setPayment return a value and not void .

Jackson cares about such things so I recommend annotating both methods with @JsonSetter .

The problem could also be with payment but it is impossible to tell since you didn't say which field could not be deserialized and you also didn't post the source code for the Payment class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM