2

I want to parse some JSON data in uint32 and uint64 format that are sent as numbers (without quotes), and then use them in java.

I found out that I can store them as unsigned integers via the parseUnsignedInt(String) method, but the problem is that I cannot get the json value as a string, because it's lacking quotes. If I parse it as an int, the value returned is wrong before I have the chance to convert it.

Example:

// data is a JSONObject containing: {"number" : 4294967294}
...
System.out.println(data.getInt("number"));
// returns: -10001
System.out.println(Integer.parseUnsignedInt(data.getString("number")));
// returns: JSONObject["number"] not a string.
System.out.println(Integer.parseUnsignedInt(Integer.toString(data.getInt("number"))));
// returns: Illegal leading minus sign on unsigned string -10001.

Is there a way to extract the value from the json object as a string (or any other way that doesn't ruin it)?

Yiorgos
  • 111
  • 8
  • Depends on the library you are using for parsing, It looks like the interger is overflowing. Have you tried parsing it as Long ? – Althaf M Mar 23 '20 at 14:26
  • Integer max value :2147483647 < ( 4294967294 ) Long max value :9223372036854775807 – Althaf M Mar 23 '20 at 14:27
  • @AlthafM That's the problem they are facing. How would you get the number directly as a long? – cegredev Mar 23 '20 at 14:29
  • I thought about that option, but I also need to handle uint32 with Long.parseUnsignedInt(String), so I'm searching for a universal solution, if any. // I also need to parse uint64 in the long run, but that's a different story, let's leave it for later :P – Yiorgos Mar 23 '20 at 14:29
  • 1
    are you using javax.json ? – Althaf M Mar 23 '20 at 14:36
  • if you are using javax.json , then you can do data.getJsonNumber("number").longValue() – Althaf M Mar 23 '20 at 14:41
  • data.getString("number") returns «JSONObject["number"] not a string». That's the core of my problem, that I cannot parse the value as a string in the first place. – Yiorgos Mar 23 '20 at 14:41
  • @Yiorgos got a chance to test this : data.getJsonNumber("number").longValue() – Althaf M Mar 23 '20 at 14:53
  • Please provide the json library and version you are using.. – samabcde Mar 23 '20 at 14:59
  • I actually tested the equivalent from org.json.JSONObject that I'm currently using: Integer.parseUnsignedInt(Long.toString(data.getLong("number"))) and it worked, but I'm still searching for a way to directly get the json values as string as stated in the question title, in order to be able to use it to parse uint64 as well. – Yiorgos Mar 23 '20 at 15:04

2 Answers2

1

as far as I know, there is no way to read json-numbers as strings (as long as using standard libs).

But I think, finally, you want to handle numbers, so, converting them into string is maybe inconvenient.

Instead, you can read as json-number and then handle numbers instead of strings:

final JsonNumber jsonNumber = data.getJsonNumber("number");
System.out.println(jsonNumber.longValue());
// returns: 4294967294

From here on you can convert it into uint32 as you like.

Hope this helps.

Martin Ackermann
  • 884
  • 6
  • 15
1

Suppose the library using is org.json. getLong method can not support uint64. We should use getBigInteger in such case.

import org.json.JSONObject;

public class JsonParseLargeInteger {
    public static void main(String[] args) {
        String uint32MaxValueJson = "{\"number\" : 4294967296}";
        JSONObject uint32MaxValueJsonObject = new JSONObject(uint32MaxValueJson);
        System.out.println(((Integer) uint32MaxValueJsonObject.getInt("number")).toString());
        // Result is 0
        System.out.println(((Long) uint32MaxValueJsonObject.getLong("number")).toString());
        // Result is 4294967296
        System.out.println(uint32MaxValueJsonObject.getBigInteger("number").toString());
        // Result is 4294967296

        String uint64MaxValueJson = "{\"number\" : 18446744073709551615}";
        JSONObject uint64MaxValueJsonObject = new JSONObject(uint64MaxValueJson);
        System.out.println(((Integer) uint64MaxValueJsonObject.getInt("number")).toString());
        // Result is -1
        System.out.println(((Long) uint64MaxValueJsonObject.getLong("number")).toString());
        // Result is -1
        System.out.println(uint64MaxValueJsonObject.getBigInteger("number").toString());
        // Result is 18446744073709551615
    }
}
samabcde
  • 6,988
  • 2
  • 25
  • 41
  • Yes, I think BigInteger is what I was missing in order to elevate the solution to uint64 as well. I understand that this logic can be implemented with both org.json and javax.json. Any particular advantage any of those libraries has over the other? – Yiorgos Mar 23 '20 at 15:23
  • It depends on your use case, JsonNumber (of javax) provide more general handling on number(can be `int`, `long`, `BigInteger` or `BigDecimal`). I suppose such generalization require trade off in performance. On the other hand, `org.json` provide specific function to handle different data type, which should be faster. So it depends on whether you know the type of number you are handling. – samabcde Mar 23 '20 at 15:44