我尝试按照我想要的顺序打印JSONObject
页面时遇到问题。在我的代码中,我输入了这个:
JSONObject myObject = new JSONObject();
myObject.put("userid", "User 1");
myObject.put("amount", "24.23");
myObject.put("success", "NO");
但是,当我在页面上看到显示时,它会显示:
JSON格式化字符串:[{"success":"NO","userid":"User 1","bid":24.23}
我需要按用户ID,数量,然后成功的顺序。已经尝试在代码中重新排序,但无济于事。我也试过.append
....需要一些帮助,谢谢!!
答案 0 :(得分:92)
您不能也不应该依赖JSON对象中元素的排序。
的JSON规范对象是一组无序的 名称/值对
因此, JSON库可以根据需要重新排列元素的顺序。 这不是一个错误。
答案 1 :(得分:11)
我同意其他答案。您不能依赖JSON元素的排序。
但是,如果我们需要一个有序的JSON,一个解决方案可能是使用元素准备 LinkedHashMap 对象并将其转换为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)
}
通常订单不会保留如下。
@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)
}
您也可以查看我的帖子:http://www.flyingtomoon.com/2011/04/preserving-order-in-json.html
答案 2 :(得分:5)
JSONObject json = new JSONObject(obj);
而不是:
JSONObject json = (JSONObject) obj
所以在我的测试代码中是:
Map item_sub2 = new LinkedHashMap();
item_sub2.put("name", "flare");
item_sub2.put("val1", "val1");
item_sub2.put("val2", "val2");
item_sub2.put("size",102);
JSONArray itemarray2 = new JSONArray();
itemarray2.add(item_sub2);
itemarray2.add(item_sub2);//just for test
itemarray2.add(item_sub2);//just for test
Map item_sub1 = new LinkedHashMap();
item_sub1.put("name", "flare");
item_sub1.put("val1", "val1");
item_sub1.put("val2", "val2");
item_sub1.put("children",itemarray2);
JSONArray itemarray = new JSONArray();
itemarray.add(item_sub1);
itemarray.add(item_sub1);//just for test
itemarray.add(item_sub1);//just for test
Map item_root = new LinkedHashMap();
item_root.put("name", "flare");
item_root.put("children",itemarray);
JSONObject json = new JSONObject(item_root);
System.out.println(json.toJSONString());
答案 3 :(得分:3)
真正的答案可以在规范中找到,json是无序的。 然而,作为一个人类读者,我按重要性排序了我的元素。它不仅是一种更逻辑的方式,而且更容易阅读。也许规范的作者从来不必阅读JSON,我这样做。所以,这里有一个修复:
/**
* I got really tired of JSON rearranging added properties.
* Specification states:
* "An object is an unordered set of name/value pairs"
* StackOverflow states:
* As a consequence, JSON libraries are free to rearrange the order of the elements as they see fit.
* I state:
* My implementation will freely arrange added properties, IN SEQUENCE ORDER!
* Why did I do it? Cause of readability of created JSON document!
*/
private static class OrderedJSONObjectFactory {
private static Logger log = Logger.getLogger(OrderedJSONObjectFactory.class.getName());
private static boolean setupDone = false;
private static Field JSONObjectMapField = null;
private static void setupFieldAccessor() {
if( !setupDone ) {
setupDone = true;
try {
JSONObjectMapField = JSONObject.class.getDeclaredField("map");
JSONObjectMapField.setAccessible(true);
} catch (NoSuchFieldException ignored) {
log.warning("JSONObject implementation has changed, returning unmodified instance");
}
}
}
private static JSONObject create() {
setupFieldAccessor();
JSONObject result = new JSONObject();
try {
if (JSONObjectMapField != null) {
JSONObjectMapField.set(result, new LinkedHashMap<>());
}
}catch (IllegalAccessException ignored) {}
return result;
}
}
答案 4 :(得分:3)
这里的主要目的是发送一个有序的JSON对象作为响应。我们不需要javax.json.JsonObject来实现。我们可以将有序的json创建为字符串。 首先以所需顺序创建一个具有所有键值对的LinkedHashMap。然后生成字符串形式的json,如下所示。 使用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();
}
此函数返回的响应如下:
{"A":"1","B":"2","C":"3"}
答案 5 :(得分:2)
JavaScript对象和JSON无法设置密钥的顺序。您可能在Java中正确使用它(我不知道Java对象是如何工作的),但如果它是用于Web客户端或JSON的另一个使用者,则无法保证密钥的顺序。
答案 6 :(得分:2)
下载&#34; json simple 1.1 jar&#34;来自https://code.google.com/p/json-simple/downloads/detail?name=json_simple-1.1.jar&can=2&q=
将jar文件添加到lib文件夹
使用JSONValue可以将LinkedHashMap转换为json字符串
如需更多参考,请点击此处http://androiddhina.blogspot.in/2015/09/ordered-json-string-in-android.html
答案 7 :(得分:1)
如果您使用属于com.google.gson的JsonObject,则可以保留订单:D
JsonObject responseObj = new JsonObject();
responseObj.addProperty("userid", "User 1");
responseObj.addProperty("amount", "24.23");
responseObj.addProperty("success", "NO");
使用这个JsonObject甚至不需要使用Map&lt;&gt;
CHEERS !!!
答案 8 :(得分:0)
只需使用 LinkedHashMap 保持顺序并使用 jackson 将其转换为 json
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.LinkedHashMap;
LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
stats.put("aaa", "aaa");
stats.put("bbb", "bbb");
stats.put("ccc", "ccc");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
System.out.println(json);
maven 依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.10.7</version>
</dependency>
答案 9 :(得分:0)
ES6 你可以这样操作。订单将保持不变
var Sorted=[];
Sorted.push({test1:check1})
Sorted.push({test2:check2})
Sorted.push({test3:check3})
之所以有效,是因为我们正在一个接一个地推送键值对。通过这种方式,我们可以可靠地实现订购目标。
答案 10 :(得分:0)
不确定我是否迟到了,但我发现了这个很好的例子,它覆盖了 JSONObject 构造函数,并确保 JSON 数据以与添加相同的方式输出。在幕后 JSONObject 使用 MAP,而 MAP 不保证顺序,因此我们需要覆盖它以确保我们按照订单接收 JSON。
如果您将此添加到您的 JSONObject 中,那么生成的 JSON 将与您创建它的顺序相同。
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import org.json.JSONObject;
import lombok.extern.java.Log;
@Log
public class JSONOrder {
public static void main(String[] args) throws IOException {
JSONObject jsontest = new JSONObject();
try {
Field changeMap = jsonEvent.getClass().getDeclaredField("map");
changeMap.setAccessible(true);
changeMap.set(jsonEvent, new LinkedHashMap<>());
changeMap.setAccessible(false);
} catch (IllegalAccessException | NoSuchFieldException e) {
log.info(e.getMessage());
}
jsontest.put("one", "I should be first");
jsonEvent.put("two", "I should be second");
jsonEvent.put("third", "I should be third");
System.out.println(jsonEvent);
}
}
答案 11 :(得分:0)
只需添加带有此标签的订单
@JsonPropertyOrder({ "property1", "property2"})
答案 12 :(得分:0)
我在我喜欢分享的“ interweb”上发现了一个“整洁”的反射调整。 (来源:https://towardsdatascience.com/create-an-ordered-jsonobject-in-java-fb9629247d76)
这将通过反射API将org.json.JSONObject中的基础集合更改为无序集合(LinkedHashMap)。
我测试成功:
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import org.json.JSONObject;
private static void makeJSONObjLinear(JSONObject jsonObject) {
try {
Field changeMap = jsonObject.getClass().getDeclaredField("map");
changeMap.setAccessible(true);
changeMap.set(jsonObject, new LinkedHashMap<>());
changeMap.setAccessible(false);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
[...]
JSONObject requestBody = new JSONObject();
makeJSONObjLinear(requestBody);
requestBody.put("username", login);
requestBody.put("password", password);
[...]
// returned '{"username": "billy_778", "password": "********"}' == unordered
// instead of '{"password": "********", "username": "billy_778"}' == ordered (by key)
答案 13 :(得分:0)
Underscore-java使用linkedhashmap存储JSON的键/值。我是该项目的维护者。
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));
答案 14 :(得分:0)
对于Java代码,为对象而不是JSONObject创建POJO类。 并为您的POJO类使用JSONEncapsulator。 这种方式的元素顺序取决于POJO类中getter setter的顺序。 例如。 POJO类就像
Class myObj{
String userID;
String amount;
String success;
// getter setters in any order that you want
以及您需要在响应中发送json对象的位置
JSONContentEncapsulator<myObj> JSONObject = new JSONEncapsulator<myObj>("myObject");
JSONObject.setObject(myObj);
return Response.status(Status.OK).entity(JSONObject).build();
此行的响应将是
{myObject:{//属性顺序与getter setter order。}}
答案 15 :(得分:0)
对于那些使用maven的人,请尝试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>
它从JSON-java分叉,但切换了@lemiorhan上面提到的地图实现with LinkedHashMap。
答案 16 :(得分:0)
正如所有人都告诉你的那样,JSON没有维护“序列”但是阵列没有,也许这可以说服你: Ordered JSONObject