java-JSONの順序がまちまち
ページで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
....も試してみました。ありがとうございます!!
答え :
解決策:
JSONオブジェクト内の要素の順序に依存することはできません。依存すべきではありません。
のJSON仕様からオブジェクトは順序付けられていないセットです 名前と値のペア
結果として、 JSONライブラリは、適切と思われる要素の順序を自由に並べ替えることができます。 これはバグではありません。
答え :
解決策:
他の回答に同意します。 JSON要素の順序に依存することはできません。
ただし、順序付けられたJSONが必要な場合、1つの解決策は、要素を含む 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
答え :
解決策:
com.google.gson:Dに属するJsonObjectを使用している場合、uは順序を保持できます:D
JsonObject responseObj = new JsonObject();
responseObj.addProperty("userid", "User 1");
responseObj.addProperty("amount", "24.23");
responseObj.addProperty("success", "NO");
このJsonObjectの使用法は、Mapを使用することすらありません<>
乾杯!!!
答え :
解決策:
実際の答えは仕様に記載されていますが、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;
}
}
答え :
解決策:
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が前述したLinkedHashMapを使用してマップの実装を切り替えます。
答え :
解決策:
JavaScriptオブジェクトとJSONには、キーの順序を設定する方法がありません。 Javaで正しく理解できるかもしれませんが(実際にはJavaオブジェクトがどのように機能するかはわかりません)、WebクライアントまたはJSONの別のコンシューマーに送信される場合、キーの順序は保証されません。
答え :
解決策:
レミオーハンの例から lemiorhanのコードのいくつかの行を変更するだけで解決できます 使用:
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());
答え :
解決策:
ここでの主な目的は、順序付けられた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();
}
この関数によって返される応答は次のようになります。 {"A":"1","B":"2","C":"3"}
答え :
解決策:
そして、jarファイルをlibフォルダーに追加します
JSONValueを使用すると、LinkedHashMapをjson文字列に変換できます
答え :
解決策:
Javaコードの場合、JSONObjectの代わりにオブジェクトのPOJOクラスを作成します。 POJOクラスにJSONEncapsulatorを使用します。 このように、要素の順序は、POJOクラスのゲッターセッターの順序によって異なります。 たとえば。 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:{//属性の順序はgettersetterの順序と同じです。}}
答え :
解決策:
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));
答え :
解決策:
共有したい「インターウェブ」に「きちんとした」反射の微調整を見つけました。 (起源: 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)
答え :
解決策:
パーティーに遅れているかどうかはわかりませんが、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);
}
}
答え :
解決策:
ES6この方法で行うことができます。注文はそのまま保持されます
var Sorted=[];
Sorted.push({test1:check1})
Sorted.push({test2:check2})
Sorted.push({test3:check3})
キーと値のペアを次々にプッシュしているため、機能します。このようにして、注文の目標を確実に達成できます。
答え :
解決策:
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>
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。