Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the underlying String from a JsonParser (Jackson Json)

Tags:

Looking through the documentation and source code I don't see a clear way to do this. Curious if I'm missing something.

Say I receive an InputStream from a server response. I create a JsonParser from this InputStream. It is expected that the server response is text containing valid JSON, such as:

{"iamValidJson":"yay"}

However, if the response ends up being invalid JSON or not JSON at all such as:

Some text that is not JSON

the JsonParser will eventually throw an exception. In this case, I would like to be able to extract the underlying invalid text "Some text that is not JSON" out of the JsonParser so it can be used for another purpose.

I cannot pull it out of the InputStream because it doesn't support resetting and the creation of the JsonParser consumes it.

Is there a way to do this?

like image 565
cottonBallPaws Avatar asked May 30 '13 00:05

cottonBallPaws


People also ask

How do I read a JSON file using ObjectMapper?

Read Object From JSON via URL ObjectMapper objectMapper = new ObjectMapper(); URL url = new URL("file:data/car. json"); Car car = objectMapper. readValue(url, Car. class);

How do you access the JSON fields arrays and nested objects of JsonNode in Java?

We can access a field, array or nested object using the get() method of JsonNode class. We can return a valid string representation using the asText() method and convert the value of the node to a Java int using the asInt() method of JsonNode class.


2 Answers

If you have the JsonParser then you can use jsonParser.readValueAsTree().toString().

However, this likely requires that the JSON being parsed is indeed valid JSON.

like image 148
Shadow Man Avatar answered Sep 21 '22 07:09

Shadow Man


I had a situation where I was using a custom deserializer, but I wanted the default deserializer to do most of the work, and then using the SAME json do some additional custom work. However, after the default deserializer does its work, the JsonParser object current location was beyond the json text I needed. So I had the same problem as you: how to get access to the underlying json string.

You can use JsonParser.getCurrentLocation.getSourceRef() to get access to the underlying json source. Use JsonParser.getCurrentLocation().getCharOffset() to find the current location in the json source.

Here's the solution I used:

public class WalkStepDeserializer extends StdDeserializer<WalkStep> implements     ResolvableDeserializer {      // constructor, logger, and ResolvableDeserializer methods not shown      @Override     public MyObj deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,             JsonProcessingException {         MyObj myObj = null;          JsonLocation startLocation = jp.getCurrentLocation();         long charOffsetStart = startLocation.getCharOffset();          try {             myObj = (MyObj) defaultDeserializer.deserialize(jp, ctxt);         } catch (UnrecognizedPropertyException e) {             logger.info(e.getMessage());         }          JsonLocation endLocation = jp.getCurrentLocation();         long charOffsetEnd = endLocation.getCharOffset();         String jsonSubString = endLocation.getSourceRef().toString().substring((int)charOffsetStart - 1, (int)charOffsetEnd);         logger.info(strWalkStep);          // Special logic - use JsonLocation.getSourceRef() to get and use the entire Json         // string for further processing          return myObj;     } } 

And info about using a default deserializer in a custom deserializer is at How do I call the default deserializer from a custom deserializer in Jackson

like image 28
user2636014 Avatar answered Sep 21 '22 07:09

user2636014