1

I am creating an API that will take HTTP requests and return JSON reports. I have been testing the requests in both Java (using HTTPUrlConnection) and Python (using requests). The API is written in Java Spark. I am doing some testing in Python since requests is a little easier to play with. The Python code I've used is provided for insight into what I'm trying to do, since that works.

Some of the parameters of my request are being passed as a string representation of a JSON object. What I am finding is that when a JSON object string is passed to my API and parsed, the object is treated differently depending on where it comes from, specifically when the data in question is an int.

In Python:

report_dict = {
        "client_name": "Wayne_Enterprises",
        "client_id": 123,
        "report_type": "test_report",
        "timestamp_generated": "2015-08-11T11:00:00Z",
        "report_data": {"revenue": 40000}
    }
response = requests.post(myurl, data=json.dumps(report_dict))

In Java:

JSONObject testData = new JSONObject();
JSONObject content = new JSONObject();
content.put("revenue", 40000);
testData.put("client_name","Wayne_Enterprises");
testData.put("client_id",123);
testData.put("report_type","test_report");
testData.put("timestamp_generated","2015-08-11T11:00:00Z");
testData.put("report_data",content.toString());

URL url = new URL("http","127.0.0.1",8080,"/reports/");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setDoOutput(true);
System.out.println(testData.toString());
DataOutputStream wr = new DataOutputStream (connection.getOutputStream());
wr.writeBytes(testData.toString());
wr.close();

The JSON String is handled in the API like so:

120> JSONParser parser = new JSONParser();
121> JSONObject report = (JSONObject) parser.parse(request.body());
122> String reportType = (String) report.get("report_type");
123> String clientName = (String) report.get("client_name");
124> int clientId = (int)(long) report.get("client_id");
125> JSONObject data = (JSONObject)parser.parse((String)report.get("report_data"));
126> String dateStr = (String) report.get("timestamp_generated");

When I run the test in Python, the data is posted successfully. However, when I run the java test, I get a ClassCast Exception: java.lang.String cannot be cast to java.lang.long when I set the clientID int. Well, that's easy enough to fix. So that line now becomes:

int clientId = (int)(long) Long.parseLong((String) report.get("client_id"));

Not only is this ugly, it creates the opposite issue. Now i have 'java.lang.Long cannot be cast to java.lang.String!

Am I doing something wrong with my object creation in Java? Or am I handling the request incorrectly?

Edit: I am using org.json.simple

The string outputs: Java

{"report_data":"{\"revenue\":123}","timestamp_generated":"2000-01-01T12:00:00Z","report_type":"api_testing","client_name":"Wayne_Enterprises","client_id":123}

Python

{'client_name': 'test_client', 'report_data': '{"revenue": 4000}', 'report_type': 'transparency', 'client_id': 123, 'timestamp_generated': '2015-07-29T11:00:00Z'}

Stack Trace:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
        at com.simplerelevance.Main.lambda$init$1(Main.java:124)
        at com.simplerelevance.Main$$Lambda$2/449105069.handle(Unknown Source)
        at spark.SparkBase$1.handle(SparkBase.java:311)
        at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:159)
        at spark.servlet.SparkFilter.doFilter(SparkFilter.java:131)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1652)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java
:585)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.j
ava:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.jav
a:577)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandl
er.java:223)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandl
er.java:1127)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:
515)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandle
r.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandle
r.java:1061)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.j
ava:141)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(Cont
extHandlerCollection.java:215)
        at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerColl
ection.java:110)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper
.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:497)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.jav
a:257)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java
:540)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPoo
l.java:635)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool
.java:555)
        at java.lang.Thread.run(Thread.java:745)
4
  • Which JSON library are you using server side? Different implementations of JSON will have different APIs to get values out of objects (including numerics), but generally they will return doubles. What does the json string produced by your clients look like, and how do they compare? Also, it looks like your real question is "How do I get an int into and out of json with Java?", not a comparison between Python and Java. Commented Aug 11, 2015 at 18:57
  • I added that information, and changed the question title, thanks for the suggestion Commented Aug 11, 2015 at 19:07
  • Please also paste the exception stack trace and mark the line numbers in the code on which exception is occurring. I would also suggest you to use jackson json api. It will convert raw response to/from json using single function call. Commented Aug 11, 2015 at 19:16
  • possible duplicate of Convert JSON inside an array list to an ArrayList (Java) Commented Aug 11, 2015 at 19:28

2 Answers 2

2

Why not just use:

int clientId = (int) report.getLong("client_id");

The getLong returns a long based on a key. Then you cast from long to int.

Alternatively, you could change declaration of clientId in Java to type long, instead of int. Then no casting is required.

Sign up to request clarification or add additional context in comments.

Comments

1

report.get("client_id”); will give you a String object, which cannot just be casted to long or int. Use report.getLong or report.getInt instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.