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>