0

I am pulling a RESTful API in JSON format and traverse through the nodes retrieve the info that I am looking for. But there is one specific node that always start with "null" even if the JSON document looks fine and that specific node doesn't contain any null value.

I am novice on using Jackson for parsing JSON document and I can't find out why the specific node always return "null" in front of the node value?

The node I have problem with is the StationName, which return for example nullHägerstensåsen:. The result that I hope to retrieve is Hägerstensåsen: without the "null".

The raw JSON document from the RESTful service:

{
  "Departure": {
    "xmlnsxsi": "http://www.w3.org/2001/XMLSchema-instance",
    "xmlnsxsd": "http://www.w3.org/2001/XMLSchema",
    "xmlns": "http://www1.sl.se/realtidws/",
    "LatestUpdate": "2014-01-21T11:34:36.7189974+01:00",
    "ExecutionTime": "00:00:00.0937512",
    "Buses": {},
    "Metros": {
      "Metro": [
    {
      "SiteId": "9262",
      "TransportMode": "METRO",
      "StationName": "Hägerstensåsen",
      "GroupOfLine": "Tunnelbanans röda linje",
      "DisplayRow1": "14  Fruängen 2 min",
      "DisplayRow2": "14 Fruängen  12 min,      14 Fruängen  23 min"
    },
    {
      "SiteId": "9262",
      "TransportMode": "METRO",
      "StationName": "Hägerstensåsen",
      "GroupOfLine": "Tunnelbanans röda linje",
      "DisplayRow1": "14  Mörby centrum 2 min.",
      "DisplayRow2": "14 Mörby centrum  12 min.      14 Mörby centrum  22 min."
    }
      ]
    },
    "Trains": {},
    "Trams": {},
    "TrainError": {
      "HasError": "true",
      "FaultCode": "Client",
      "ErrorLevel": "Error",
      "ErrorCode": "1000",
      "ErrorSource": "/realtidws/RealTimeService.asmx/GetDepartures",
      "ErrorMessage": "Connection string is missing"
    },
    "TramError": {
      "HasError": "true",
      "FaultCode": "Client",
      "ErrorLevel": "Error",
      "ErrorCode": "1000",
      "ErrorSource": "/realtidws/RealTimeService.asmx/GetDepartures",
      "ErrorMessage": "Connection string is missing"
    }
  }
}

My code for parsing the nodes:

...
result = null;
JsonNode node = mapper.readTree(slRealTimeClient.getJson(depatureSite));
node = node.path("Departure").path("Metros").path("Metro");
JsfUtil.debug("Node size: " + node.size());
depatureSiteResponse = node.get(0).path("SiteId").getTextValue();
for (JsonNode element : node) {
    if (!element.isNull()) {
        result += element.get("StationName").getTextValue();
        result += ":" + System.getProperty("line.separator");
        result += element.get("DisplayRow1").getTextValue();
        result += System.getProperty("line.separator");
        result += element.get("DisplayRow2").getTextValue();
        result += System.getProperty("line.separator");
    }
}
Chris
  • 712
  • 3
  • 16
  • 39
  • Try printing out the raw REST response, or examining the String in a debugger. I have a feeling there might be an extra unprintable character there that is mucking things up. – CodeChimp Jan 21 '14 at 13:22
  • My guess is that this has nothing to do with JSON, but rather the actual character data. There is a possibility that you converted to/from the 8-byte representation of the JSON without specifying UTF8 code page, or there may actually be an invisible character embedded in the StationName string. (Hint: Dump the elements of the Metro array using toString.) – Hot Licks Jan 21 '14 at 13:23
  • @CodeChimp the JSON document is the raw deal. "@Hot Licks" yes that is one thought I had, of an invisible char. As you say maybe just get the whole array and print it as it is. – Chris Jan 21 '14 at 13:34
  • Actually, if I comment out the "StationName" and retrieve the "DisplayRow1" node, the same problem occurs. What is the correct way to access array elements? – Chris Jan 21 '14 at 13:41

1 Answers1

1

After some debugging I came up with a solution. I just assigned a new String object before I start to getting the text values. Before I assigned it with null, to clear the String object. Why it retained the null as an text value when copying text values I don't know.

Here is the solution

result = new String();
JsonNode node = mapper.readTree(slRealTimeClient.getJson(depatureSite));
node = node.path("Departure").path("Metros").path("Metro");
JsfUtil.debug("Node size: " + node.size());
depatureSiteResponse = node.get(0).path("SiteId").getTextValue();
for (JsonNode element : node) {
    if (!element.isNull()) {
        result += element.get("StationName").getTextValue();
        result += ":" + System.getProperty("line.separator");
        result += element.get("DisplayRow1").getTextValue();
        result += System.getProperty("line.separator");
        result += element.get("DisplayRow2").getTextValue();
        result += System.getProperty("line.separator");
    }
}
Chris
  • 712
  • 3
  • 16
  • 39
  • You could simply assign `""` rather than `new String()`. – Hot Licks Jan 21 '14 at 23:01
  • Assign an empty string "", is the same as new String(). The garbage collector will clean it up eventually. – Chris Jan 23 '14 at 14:04
  • `""` is a lot cheaper. It's created when the class is loaded and is interned, so it doesn't need to be GCed. – Hot Licks Jan 23 '14 at 16:59
  • Given that you are appending strings repeatedly over loops, Java compiler might not kick in to optimize string concatenation. I feel [StringBuilder](http://stackoverflow.com/questions/1532461/stringbuilder-vs-string-concatenation-in-tostring-in-java) has legitimate use here. – THIS USER NEEDS HELP Aug 11 '16 at 00:04