javaobjectmapperhttpconnection

Avoid calling toString with Objectmapper [Java 8]


I achieved what I was trying to accomplish, however, I am not satisfied with the unnecessary(?) string-parsing to arrive to my goal.

Here is the simplified code:

HttpURLConnection con = null;

URL url = new URL(URL);
con = (HttpURLConnection) url.openConnection();

// set connection parameters and make a GET-call
con.setRequestMethod("GET");

//Must be a better way?
InputStream inputStream = con.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));


StringBuilder response = new StringBuilder();
String currentLine;

//Build the string from the response from con
while ((currentLine = in.readLine()) != null)
       response.append(currentLine);

in.close();


ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(response.toString());

// I only want the child-node
String myArray = jsonNode.get("parent").get("child").toString();

// Map the response to my object
List<Car> car = objectMapper.readValue(myArray, new TypeReference<List<Car>>(){});

There is so much manual parsing like

  1. Reading the Http connection input stream to StringBuilder, then calling toString().
  2. Retrieving the JsonNode and calling toString()
jsonNode.get("parent").get("child").toString()

to achieve my goal. I am by no means any senior- developer, and I gladly take advice and how I can remove "unnecessary" parsing.

  1. The response from the API-call is in JSON already
  2. Can only use HttpURLConnection-class for the API-call.

My Car class:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "id",
        "color"})
public class Car {

    @JsonProperty("id")
    public String id;
    @JsonProperty("color")
    public String color;
}


Solution

  • It is glad to see you want to improve your code. Reading the input stream to StringBuilder and calling jsonNode.toString() is really unnecessary. In most of the case, there is always an useful API for your need. Here is my suggestions:

    1. Use ObjectMapper#readTree(InputStream) to simplify the part for consuming the HTTP input stream.
    JsonNode jsonNode = objectMapper.readTree(con.getInputStream());
    
    1. After retrieving the target JsonNode, create a JsonParser and then call
    JsonParser jsonParser = new TreeTraversingParser(jsonNode.get("parent").get("child"));
    objectMapper.readValue(jsonParser,new TypeReference<List<Car>>(){});