Unfortunately this example is quite long so I cannot quite understand the intent; but I have 2 suggestions in trying to trace the behavior.
1. Instead of assuming current token type to be certain thing, verify what the token is: some methods (like "parser.getText()" and "parser.getCurrentName()") are applicable to different token types -- and just because you have "current name" does not necessarily mean you have FIELD_NAME token (in fact it is the value of last name for token following) 2. When a parse exception is thrown, underlying JsonParser is NOT guaranteed to be in a consistent state. Parser should still have information about the last successfully decoded token (but not in case where we are half-way through decoding a new one, and fail), and the location where the problem is encountered. But it SHOULD NOT be assumed that you can further parse content successfully. It is possible no content is available; internal state may be corrupt and so forth. -+ Tatu +- On Thu, Sep 2, 2021 at 11:44 PM Aravinda Baliga B <[email protected]> wrote: > I am building a Jackson deserialization application that can handle the > deserialization of `CustomerList` and `Customer`. Users can provide any > input and based on the input the code will make the decision whether the > provided input JSON is `CustomerList` or `Single Customer`. > > Everything is working as expected apart from one small thing. When I > provide the `CustomerList` JSON then it would skip the first `key value` > pair. In my case, it's skipping the `@Context`. > > Following is the `JSON` i am trying to deserialize: > ``` > { > "@context": [ > "https://stackoverflow.com", > { > "example": "https://example.com" > } > ], > "isA": "CustomerDocument", > "customerList": [ > { > "isA": "Customer", > "name": "Batman", > "age": "2008" > } > ] > } > ``` > > Following is my Customer POJO class: > ``` > @Data > @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = > JsonTypeInfo.As.PROPERTY, visible = true, property = "isA") > @JsonInclude(JsonInclude.Include.NON_NULL) > public class Customer implements BaseResponse { > private String isA; > private String name; > private String age; > } > > > @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = > JsonTypeInfo.As.PROPERTY, visible = true, property = "isA") > @JsonSubTypes({ > @JsonSubTypes.Type(value = Customer.class, name = "Customer")}) > interface BaseResponse { > } > ``` > > Following is the Main: > ``` > public class JacksonMain { > public static void main(String[] args) throws IOException { > final InputStream jsonStream = > JacksonMain.class.getClassLoader().getResourceAsStream("Customer.json"); > final JsonParser jsonParser = new > JsonFactory().createParser(jsonStream); > final ObjectMapper objectMapper = new ObjectMapper(); > jsonParser.setCodec(objectMapper); > > //Goto the start of the document > jsonParser.nextToken(); > > try { > BaseResponse baseResponse = objectMapper.readValue(jsonParser, > BaseResponse.class); > System.out.println("SINGLE EVENT INPUT" + > baseResponse.toString()); > } catch (Exception e) { > System.out.println("LIST OF CUSTOMER INPUT"); > //Go until the customerList has been reached > while (!jsonParser.getText().equals("customerList")) { > System.out.println("Current Token Name : " + > jsonParser.getCurrentName()); > if (jsonParser.getCurrentName() != null && > jsonParser.getCurrentName().equalsIgnoreCase("@context")) { > System.out.println("WITHIN CONTEXT"); > } > jsonParser.nextToken(); > } > jsonParser.nextToken(); > > //Loop through each object within the customerList and > deserilize them > while (jsonParser.nextToken() != JsonToken.END_ARRAY) { > final JsonNode customerNode = jsonParser.readValueAsTree(); > final String eventType = customerNode.get("isA").asText(); > Object event = objectMapper.treeToValue(customerNode, > BaseResponse.class); > System.out.println(event.toString()); > } > } > } > } > ``` > > When I run the application I get the following response: > ``` > LIST OF CUSTOMER INPUT > Current Token Name : isA > Customer(isA=Customer, name=Batman, age=2008) > ``` > > As we can see it's printing only `Current Token Name: isA` I would expect > it to print `isA and @Context` because it's present before the `isA`. > > The weird thing that I am seeing is that if I switch the places of `isA` > and `@context` in my `JSON` something like this: > ``` > { > "isA": "CustomerDocument", > "@context": [ > "https://stackoverflow.com", > { > "example": "https://example.com" > } > ], > "customerList": [ > { > "isA": "Customer", > "name": "Batman", > "age": "2008" > } > ] > } > ``` > > Then I get the output like this, As you can see now it's reading the > `@context` and `isA` both. > ``` > LIST OF CUSTOMER INPUT > Current Token Name : isA > Current Token Name : @context > WITHIN CONTEXT > Current Token Name : @context > WITHIN CONTEXT > Current Token Name : null > Current Token Name : null > Current Token Name : example > Current Token Name : example > Current Token Name : null > Current Token Name : @context > WITHIN CONTEXT > Customer(isA=Customer, name=Batman, age=2008) > ``` > > Since it's working in the second case I am thinking it's not an issue with > my code. But I am not sure what's causing the issue for it to not read in > the `firstcase` (with `@context` first and `isA` second). Can someone > please help me understand this issue and provide some workaround as I am > trying since yesterday to figure out the problem? Is this a bug in Jackson? > > Please note: > The JSON is out of my control as it's coming from another application. > Provided JSON is a replica of my actual application JSON. > > The second JSON that I can feed to the application is the direct customer > rather than a list: (with the current code this is working perfectly) > ``` > { > "@context": [ > "https://stackoverflow.com", > { > "example": "https://example.com" > } > ], > "isA": "Customer", > "name": "Batman", > "age": "2008" > } > > ``` > > Can someone please help me understand why Jackson is skipping the > `@context` when provided first and provide some workaround as I am trying > since yesterday to figure out the problem? Is this a bug in Jackson? > > -- > You received this message because you are subscribed to the Google Groups > "jackson-user" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/jackson-user/8b99e386-325a-45a7-9616-74ec142b45c4n%40googlegroups.com > <https://groups.google.com/d/msgid/jackson-user/8b99e386-325a-45a7-9616-74ec142b45c4n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jackson-user/CAGrxA24asd-0%3DPZ33%3DLe4jg1QHp2RZXW8hGHqxsYpsOuNkF5pw%40mail.gmail.com.
