I\'ve a problem trying to make my page printing out the JSONObject
in the order i want. In my code, I entered this:
For those who're using maven, please try com.github.tsohr/json
<!-- https://mvnrepository.com/artifact/com.github.tsohr/json -->
<dependency>
<groupId>com.github.tsohr</groupId>
<artifactId>json</artifactId>
<version>0.0.1</version>
</dependency>
It's forked from JSON-java but switch its map implementation with LinkedHashMap which @lemiorhan noted above.
Underscore-java uses linkedhashmap to store key/value for json. I am the maintainer of the project.
Map<String, Object> myObject = new LinkedHashMap<>();
myObject.put("userid", "User 1");
myObject.put("amount", "24.23");
myObject.put("success", "NO");
System.out.println(U.toJson(myObject));
As all are telling you, JSON does not maintain "sequence" but array does, maybe this could convince you: Ordered JSONObject
For Java code, Create a POJO class for your object instead of a JSONObject. and use JSONEncapsulator for your POJO class. that way order of elements depends on the order of getter setters in your POJO class. for eg. POJO class will be like
Class myObj{
String userID;
String amount;
String success;
// getter setters in any order that you want
and where you need to send your json object in response
JSONContentEncapsulator<myObj> JSONObject = new JSONEncapsulator<myObj>("myObject");
JSONObject.setObject(myObj);
return Response.status(Status.OK).entity(JSONObject).build();
The response of this line will be
{myObject : {//attributes order same as getter setter order.}}
I agree with the other answers. You cannot rely on the ordering of JSON elements.
However if we need to have an ordered JSON, one solution might be to prepare a LinkedHashMap object with elements and convert it to JSONObject.
@Test
def void testOrdered() {
Map obj = new LinkedHashMap()
obj.put("a", "foo1")
obj.put("b", new Integer(100))
obj.put("c", new Double(1000.21))
obj.put("d", new Boolean(true))
obj.put("e", "foo2")
obj.put("f", "foo3")
obj.put("g", "foo4")
obj.put("h", "foo5")
obj.put("x", null)
JSONObject json = (JSONObject) obj
logger.info("Ordered Json : %s", json.toString())
String expectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""
assertEquals(expectedJsonString, json.toString())
JSONAssert.assertEquals(JSONSerializer.toJSON(expectedJsonString), json)
}
Normally the order is not preserved as below.
@Test
def void testUnordered() {
Map obj = new HashMap()
obj.put("a", "foo1")
obj.put("b", new Integer(100))
obj.put("c", new Double(1000.21))
obj.put("d", new Boolean(true))
obj.put("e", "foo2")
obj.put("f", "foo3")
obj.put("g", "foo4")
obj.put("h", "foo5")
obj.put("x", null)
JSONObject json = (JSONObject) obj
logger.info("Unordered Json : %s", json.toString(3, 3))
String unexpectedJsonString = """{"a":"foo1","b":100,"c":1000.21,"d":true,"e":"foo2","f":"foo3","g":"foo4","h":"foo5"}"""
// string representation of json objects are different
assertFalse(unexpectedJsonString.equals(json.toString()))
// json objects are equal
JSONAssert.assertEquals(JSONSerializer.toJSON(unexpectedJsonString), json)
}
You may check my post too: http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html
The main intention here is to send an ordered JSON object as response. We don't need javax.json.JsonObject to achieve that. We could create the ordered json as a string. First create a LinkedHashMap with all key value pairs in required order. Then generate the json in string as shown below. Its much easier with Java 8.
public Response getJSONResponse() {
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("A", "1");
linkedHashMap.put("B", "2");
linkedHashMap.put("C", "3");
String jsonStr = linkedHashMap.entrySet().stream()
.map(x -> "\"" + x.getKey() + "\":\"" + x.getValue() + "\"")
.collect(Collectors.joining(",", "{", "}"));
return Response.ok(jsonStr).build();
}
The response return by this function would be following:
{"A":"1","B":"2","C":"3"}