How to get the base string from JsonParser (Jackson Json)

Looking through the documentation and source code, I see no clear way to do this. Curious if I missed something.

Say I get an InputStream from a server response. I am creating a JsonParser from this InputStream. The server response is expected to contain text containing valid json, for example:

{"iamValidJson":"yay"}

However, if the response ends up as invalid json or not json at all, for example:

Some text that is not json

JsonParser ultimately throws an exception. In this case, I would like to extract the main invalid text " Some text that is not json " from JsonParser so that it can be used for other purposes.

I can't get it out of InputStream because it doesn't support dumping, and JsonParser creation uses it.

Is there any way to do this?

+7
java json android jackson inputstream
May 30 '13 at 12:04
source share
3 answers

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

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

+8
May 30 '13 at
source share

I had a situation where I used my own deserializer, but I wanted the deserializer to do most of the work by default, and then using SAME json, do some extra custom work. However, after the deserializer does its job by default, the current location of the JsonParser object was outside the json text I needed. So I had the same problem as you: how to access the json main line.

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

Here is 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 information on using the default deserializer in the user deserializer is in How to call the default deserializer from the user deserializer in Jackson

+3
Dec 09 '14 at 23:14
source share

What you are trying to do is beyond Jackson (and most, if not all other Java JSON libraries). What you want to do is completely absorb the input stream into a string, and then try to convert that string to a JSON object using Jackson. If the conversion fails, then something to do with the intermediate line, otherwise normal. Here is an example that uses the excellent Apo Commons IO library for convenience:

 final InputStream stream ; // Your stream here final String json = IOUtils.toString(stream); try { final JsonNode node = new ObjectMapper().readTree(json); // Do something with JSON object here } catch(final JsonProcessingException jpe) { // Do something with intermediate string here } 
+2
May 31 '13 at 5:37
source share



All Articles