Java 顺序混乱

Java 顺序混乱,java,json,Java,Json,我在试图让我的页面按我想要的顺序打印出JSONObject时遇到问题。在我的代码中,我输入了以下内容: JSONObject myObject=new JSONObject(); myObject.put(“用户ID”、“用户1”); myObject.put(“金额”,“24.23”); myObject.put(“成功”、“否”); 但是,当我看到页面上的显示时,它给出: JSON格式字符串:[{“success”:“NO”,“userid”:“User 1”,“bid”:24.23}]

我在试图让我的页面按我想要的顺序打印出
JSONObject
时遇到问题。在我的代码中,我输入了以下内容:

JSONObject myObject=new JSONObject();
myObject.put(“用户ID”、“用户1”);
myObject.put(“金额”,“24.23”);
myObject.put(“成功”、“否”);
但是,当我看到页面上的显示时,它给出:

JSON格式字符串:
[{“success”:“NO”,“userid”:“User 1”,“bid”:24.23}]


我需要它的顺序是userid,amount,然后success。已尝试在代码中重新排序,但无效。我也尝试了
.append
…这里需要一些帮助,谢谢

JavaScript对象和JSON无法设置键的顺序。在Java中,您可能会得到正确的结果(我真的不知道Java对象是如何工作的),但如果它将被用于web客户机或JSON的另一个消费者,则无法保证键的顺序

您不能也不应该依赖JSON对象中元素的顺序

从JSON规范

对象是一组无序的 名称/值对

因此,, JSON库可以根据需要自由地重新排列元素的顺序。
这不是一个bug。

我同意其他答案。您不能依赖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)
}

您也可以查看我的帖子:

正如大家所说,JSON不维护“序列”,但array维护,也许这可以说服您: 来自lemiorhan示例 我只需要修改一行lemiorhan的代码就可以解决这个问题 使用:

与此相反:

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());
从以下站点下载“json simple 1.1 jar”

并将jar文件添加到lib文件夹中


使用JSONValue,您可以将LinkedHashMap转换为json字符串

真正的答案可以在规范中找到,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;
    }
}
/**
*我真的厌倦了JSON重新排列添加的属性。
*规范规定:
*“对象是一组无序的名称/值对”
*堆栈溢出状态:
*因此,JSON库可以根据需要自由地重新排列元素的顺序。
*我声明:
*我的实现将按顺序自由安排添加的属性!
*我为什么这么做?创建的JSON文档可读性的原因!
*/
私有静态类OrderedJSONObject工厂{
私有静态记录器log=Logger.getLogger(OrderedJSONObjectFactory.class.getName());
私有静态布尔setupDone=false;
私有静态字段JSONObjectMapField=null;
专用静态无效setupFieldAccessor(){
如果(!setupDone){
setupDone=true;
试一试{
JSONObjectMapField=JSONObject.class.getDeclaredField(“map”);
JSONObjectMapField.setAccessible(true);
}捕获(忽略NoSuchFieldException){
警告(“JSONObject实现已更改,返回未修改的实例”);
}
}
}
私有静态JSONObject create(){
setupFieldAccessor();
JSONObject结果=新建JSONObject();
试一试{
if(JSONObjectMapField!=null){
set(结果,新LinkedHashMap());
}
}捕获(IllegalacessException被忽略){}
返回结果;
}
}

如果使用属于com.google.gson:D的JsonObject,则可以保留订单

JsonObject responseObj = new JsonObject();
responseObj.addProperty("userid", "User 1");
responseObj.addProperty("amount", "24.23");
responseObj.addProperty("success", "NO");
使用这个JsonObject甚至不用麻烦使用Map


干杯

对于使用maven的用户,请尝试


com.github.tsohr

但是切换上面提到的@lemiorhan的map实现

对于Java代码,为对象创建一个POJO类,而不是JSONObject。 并为您的POJO类使用JsoneCapsulator。 这样,元素的顺序取决于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();
JSONContentEncapsulator JSONObject=新的JSONEncapsulator(“myObject”);
setObject(myObj);
返回Response.status(status.OK).entity(JSONObject.build();
该行的响应将是


{myObject:{//attributes order与getter setter order相同。}

这里的主要目的是发送一个有序的JSON对象作为响应。我们不需要javax.json.JsonObject来实现这一点。我们可以将有序json创建为字符串。 首先创建一个LinkedHashMap,按要求的顺序包含所有键值对。然后生成字符串形式的json,如下所示。 使用Java8要容易得多

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();
}
public Response getJSONResponse(){
Map linkedHashMap=新建linkedHashMap();
linkedHashMap.put(“A”,“1”);
linkedHashMap.put(“B”,“2”);
linkedHashMap.put(“C”,“3”);
字符串jsonStr=linkedHashMap.entrySet().stream()
.map(x->“\”+x.getKey()+“\”:\”+x.getValue()+“\”)
.collect(collector.joining(“,”,“{,“}”);
返回Response.ok(jsonStr.build();
}
此函数返回的响应如下所示:
{“A”:“1”、“B”:“2”、“C”:“3”}

使用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));
Map myObject=newlinkedhashmap();
myObject.put(“用户ID”、“用户1”);
myObject.put(“金额”,“24.23”);
myObject.put(“成功”、“否”);
System.out.println(U.toJson(myObject));
我在“互联网络”上找到了一个“简洁”的反射调整,我想与大家分享。 (来源:)

它将把org.json.JSONObject中的基础集合更改为未排序的集合(LinkedHashMap)
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();
}
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));
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)
@JsonPropertyOrder({ "property1", "property2"})
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);
    }
}
 var Sorted=[];
 Sorted.push({test1:check1})
 Sorted.push({test2:check2})
 Sorted.push({test3:check3})
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);
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.10.7</version>
</dependency>