0

I have a rest endpoint with the following response

{
    "Shops": {
        "Shop": [
            {
                "RowID": "1",
                "Penalties": {
                    "Penalty": [
                        {
                            "PenaltyCode": "abc-01",
                            "PenaltyCount": "1"
                        },
                        {
                            "PenaltyCode": "abc-02",
                            "PenaltyCount": "2"
                        }
                    ]
                },
                "VisitOutComes": {
                    "VisitOutCome": {
                        "TaskOutComeName": "text",
                        "TaskOutComeCount": "1"
                    }
                }
            }
        ]
    }
}

I need to insert the response in a RDMS using hibernate. I already done the hibernate part and the rest client part. I am confused how to map the json to java classes.

I write the follwing classes , getter and setter are omitted for clarity.

public class Shops {
    @JsonProperty("Shop")
    private ArrayList<Shop> shop ;



    public class Shop {
        @JsonProperty("VisitOutComes")
        private VisitOutComes  visitOutComes ;
        
        @JsonProperty("Penalties")
        private Penalties  penalties ;
    
        @JsonProperty("RowID")
        private String rowID ;
    
    public class VisitOutComes {
        @JsonProperty("VisitOutCome")
        ArrayList<VisitOutCome> visitOutCome ;
    
    
    public class Penalties {
        @JsonProperty("Penalty")
        ArrayList<Penalty> penalty ;
    
    
    public class VisitOutCome {
        @JsonProperty("TaskOutComeCount")
        private String TaskOutComeCount;
        
        @JsonProperty("TaskOutComeName")
        private String TaskOutComeName ;
    
    
    public class Penalty {
        @JsonProperty("penaltyCode")
        private String penaltyCode ;
        
        @JsonProperty("penaltyCount")
        private String penaltyCount ;

Then I wirte the main method as follows :

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
String path = "C:\\jars\\response.json" ;
Shops shops = mapper.readValue(new File(path),Shops.class);

Finally I get the error

Cannot deserialize instance of java.util.ArrayList jscksondemo.VisitOutCome out of START_OBJECT token

I appreciate any help on how to create the maping for this json file.

Smile
  • 3,832
  • 3
  • 25
  • 39
Ahmed Mohamed
  • 29
  • 1
  • 5
  • 1
    `VisitOutCome` is not an array in your json – Smile Sep 14 '20 at 11:01
  • 1
    That is because the rest web service returned it this way when there is only one item. – Ahmed Mohamed Sep 14 '20 at 11:34
  • I think it would be a better design to you keep your hibernate entity (modelled based on the tables) separate from the API response. And you write converter class to convert between 2 formats. This will safeguard your database layer code and entities from being directly affected by changes in API response, This will also help you to handle your current case where an attribute could be an array or object. – Smile Sep 14 '20 at 11:53
  • 1
    You need to enable `DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY` feature. Take a look on linked question. – Michał Ziober Sep 14 '20 at 12:06

1 Answers1

0

Try with this JSON:

{
    "Shops": {
        "Shop": [
            {
                "RowID": "1",
                "Penalties": {
                    "Penalty": [
                        {
                            "PenaltyCode": "abc-01",
                            "PenaltyCount": "1"
                        },
                        {
                            "PenaltyCode": "abc-02",
                            "PenaltyCount": "2"
                        }
                    ]
                },
                "VisitOutComes": {
                    "VisitOutCome": [
                        {
                            "TaskOutComeName": "text",
                            "TaskOutComeCount": "1"
                        }
                    ]
                }
            }
        ]
    }
}

I think the bracket of your VisitOutCome List is not right.

danielbene
  • 25
  • 6