27

I am using json-rpc-1.0.jar.Below is my code. I need to convert InputStream object into JSON since the response is in JSON.

I did verify the json response obtained from Zappos API. It is valid.

PrintWriter out = resp.getWriter();
String jsonString = null;
URL url = new URL("http://api.zappos.com/Search?term=boots&key=my_key");
InputStream inputStream = url.openConnection().getInputStream();
resp.setContentType("application/json");

JSONSerializer jsonSerializer = new JSONSerializer();
try {
   jsonString = jsonSerializer.toJSON(inputStream);
} catch (MarshallException e) {
 e.printStackTrace();
    }
out.print(jsonString);

I get the below mentioned exception:

com.metaparadigm.jsonrpc.MarshallException: can't marshall sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
    at com.metaparadigm.jsonrpc.JSONSerializer.marshall(JSONSerializer.java:251)
    at com.metaparadigm.jsonrpc.JSONSerializer.toJSON(JSONSerializer.java:259)
    at Communicator.doGet(Communicator.java:33)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
    at filters.ExampleFilter.doFilter(ExampleFilter.java:149)
Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
Margi
  • 455
  • 1
  • 9
  • 20

3 Answers3

80

Make use of Jackson JSON parser.

Refer - Jackson Home

The only thing you need to do -

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> jsonMap = mapper.readValue(inputStream, Map.class);

Now jsonMap will contain the JSON.

Vishal Pawale
  • 3,416
  • 3
  • 28
  • 32
  • 1
    Ok. Looks like the Jackson Home page you asked to refer to, is OLD Jackson Java JSON-processor Home Page. I have downloaded jackson-core-2.2.3.jar. It does not seem to have ObjectMapper Class. – Margi Sep 13 '13 at 21:08
  • Yes..They have shifted to fasterxml.com. BTW you need to download Core, Annotation & Databind jars. – Vishal Pawale Sep 13 '13 at 21:15
  • Compilation error is : Bad class file ..ObjectMapper.class. Class file has wrong version 50.0,should be 48.0.Tomcat server is running java version 1.4.2_13. I have two options now. 1.Change java version on Tomcat. 2. Look for any other compatible json library. Which one should I go for. Its really a small application. – Margi Sep 16 '13 at 01:50
  • I think you should change JAVA version, 1.4 is really too old, and I think you should update it.And as far as my opinion is concerned, Jackson is better that all the others. – Vishal Pawale Sep 16 '13 at 12:22
5

ObjectMapper.readTree(InputStream) easily let's you get nested JSON with JsonNodes.

public void testMakeCall() throws IOException {
    URL url = new URL("https://api.coindesk.com/v1/bpi/historical/close.json?start=2010-07-17&end=2018-07-03");
    HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
    httpcon.addRequestProperty("User-Agent", "Mozilla/4.0");
    InputStream is = httpcon.getInputStream();

    try {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonMap = mapper.readTree(is);
        JsonNode bpi = jsonMap.get("bpi");
        JsonNode day1 = bpi.get("2010-07-18");

        System.out.println(bpi.toString());
        System.out.println(day1.toString());
    } finally {
        is.close();
    }
}

Result:

{"2010-07-18":0.0858,"2010-07-19":0.0808,...}

0.0858

Philip Rego
  • 552
  • 4
  • 20
  • 35
0

Better to save memory by having output as Stream<JsonNode>


    private fun InputStream.toJsonNodeStream(): Stream<JsonNode> {
        return StreamSupport.stream(
                Spliterators.spliteratorUnknownSize(this.toJsonNodeIterator(), Spliterator.ORDERED),
                false
        )
    }

    private fun InputStream.toJsonNodeIterator(): Iterator<JsonNode> {
        val jsonParser = objectMapper.factory.createParser(this)

        return object: Iterator<JsonNode> {

            override fun hasNext(): Boolean {
                var token = jsonParser.nextToken()
                while (token != null) {
                    if (token == JsonToken.START_OBJECT) {
                        return true
                    }
                    token = jsonParser.nextToken()
                }
                return false
            }

            override fun next(): JsonNode {
                return jsonParser.readValueAsTree()
            }
        }
    }

Alex
  • 27
  • 1
  • 3