我正在使用JSONObject来删除JSON字符串中不需要的certin属性:
JSONObject jsonObject = new JSONObject(jsonString);
jsonObject.remove("owner");
jsonString = jsonObject.toString();
它的工作正常但问题是JSONObject是“一个无序的名称/值对集合”,我想保持String在进行JSONObject操作之前的原始顺序。
知道怎么做吗?
答案 0 :(得分:3)
你做不到。
这就是为什么我们将其称为无序的名称/值对集合。
为什么你需要这样做,我不确定。但是如果你想要订购,你将不得不使用一个json数组。
答案 1 :(得分:2)
我最近遇到了同样的问题,只是将我们所有的测试(希望JSON属性的顺序相同)转换到另一个JSON库:
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.5</version>
</dependency>
在内部,它使用LinkedHashMap,它维护属性的顺序。这个库在功能上等同于json.org,所以我没有看到任何理由不使用它,至少对于测试而言。
答案 2 :(得分:2)
尝试
JSONObject jsonObject = new JSONObject(jsonString) {
/**
* changes the value of JSONObject.map to a LinkedHashMap in order to maintain
* order of keys.
*/
@Override
public JSONObject put(String key, Object value) throws JSONException {
try {
Field map = JSONObject.class.getDeclaredField("map");
map.setAccessible(true);
Object mapValue = map.get(this);
if (!(mapValue instanceof LinkedHashMap)) {
map.set(this, new LinkedHashMap<>());
}
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return super.put(key, value);
}
};
jsonObject.remove("owner");
jsonString=jsonObject.toString();
答案 3 :(得分:1)
如果您可以编辑服务器repose,则将其更改为JSON对象数组。
JSON:
[
{PropertyName:"Date of Issue:",PropertyValue:"3/21/2011"},
PropertyName:"Report No:",PropertyValue:"2131196186"},{PropertyName:"Weight:",PropertyValue:"1.00"},
{PropertyName:"Report Type:",PropertyValue:"DG"}
]
我在客户端(Android)使用JSONArray处理它:
String tempresult="[{PropertyName:"Date of Issue:",PropertyValue:"3/21/2011"},PropertyName:"Report No:",PropertyValue:"2131196186"},PropertyName:"Weight:",PropertyValue:"1.00"},{PropertyName:"Report Type:",PropertyValue:"DG"}]"
JSONArray array = new JSONArray(tempresult);
for (int i = 0; i < array.length(); i++)
{
String key = array.getJSONObject(i).getString("PropertyName");
String value = array.getJSONObject(i).getString("PropertyValue");
rtnObject.put(key.trim(),value.trim()); //rtnObject is LinkedHashMap but can be any other object which can keep order.
}
答案 4 :(得分:0)
这不容易,主要思想是使用LinkedHashMap,或者传入构造函数(JSONObject(Map map)),或者修改字节码来处理String参数(JSONObject(String source)),这是主要的用例。我在oson中找到了一个解决方案:
public static JSONObject getJSONObject(String source) {
try {
int lineNumberToReplace = 157;
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get("org.json.JSONObject");
if (ctClass.isFrozen() || ctClass.isModified()) {
if (source == null) {
return new JSONObject();
} else {
return new JSONObject(source);
}
}
ctClass.stopPruning(true);
CtConstructor declaredConstructor = ctClass.getDeclaredConstructor(new CtClass[] {});
CodeAttribute codeAttribute = declaredConstructor.getMethodInfo().getCodeAttribute();
LineNumberAttribute lineNumberAttribute = (LineNumberAttribute)codeAttribute.getAttribute(LineNumberAttribute.tag);
// Index in bytecode array where the instruction starts
int startPc = lineNumberAttribute.toStartPc(lineNumberToReplace);
// Index in the bytecode array where the following instruction starts
int endPc = lineNumberAttribute.toStartPc(lineNumberToReplace+1);
// Let's now get the bytecode array
byte[] code = codeAttribute.getCode();
for (int i = startPc; i < endPc; i++) {
// change byte to a no operation code
code[i] = CodeAttribute.NOP;
}
declaredConstructor.insertAt(lineNumberToReplace, true, "$0.map = new java.util.LinkedHashMap();");
ctClass.writeFile();
if (source == null) {
return (JSONObject) ctClass.toClass().getConstructor().newInstance();
} else {
return (JSONObject) ctClass.toClass().getConstructor(String.class).newInstance(source);
}
} catch (Exception e) {
//e.printStackTrace();
}
if (source == null) {
return new JSONObject();
} else {
return new JSONObject(source);
}
}
需要包含使用mvn
的jar文件<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
答案 5 :(得分:0)
在Android 20中,JSONObject保留顺序,因为它使用LinkedHashMap存储namevaluepairs。 Android 19及更低版本使用HashMap存储namevaluepairs。因此,Android 19及以下版本不保留订单。如果您使用20或更高版本,请不要担心,JSONObject将保留订单。或者,改为使用JSONArray。
答案 6 :(得分:0)
在JDK 8及更高版本中,我们可以使用JDK 8支持的 nashorn 引擎来实现。 Java 8支持使用js引擎来评估:
String content = ..json content...
String name = "test";
String result = (String) engine.eval("var json = JSON.stringify("+content+");"
+ "var jsResult = JSON.parse(json);"
+ "jsResult.name = \"" + name + "\";"
+ "jsResult.version = \"1.0\";"
+ "JSON.stringify( jsResult );"
);
答案 7 :(得分:0)
您可以使用com.google.gson提供的JsonObject,它与org.json的JSONObject几乎相同,但功能有所不同。 要将String转换为Json对象并保持顺序,可以使用:
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(<Json String>, JsonObject.class);
例如:-
String jsonString = "your json String";
JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);
它只是维护String中JsonObject的顺序。
答案 8 :(得分:0)
您可以使用Jsckson library来保持Json键的顺序。 它内部使用LinkedHashMap(已排序)。
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
用于删除字段的代码,如果需要,可以读取已删除的JsonToken本身。
String jsonString = "{\"name\":\"abc\",\"address\":\"add\",\"data\":[\"some 1\",\"some 2\",\"some3 3\"],\"age\":12,\"position\":8810.21}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
System.out.println("In original order:"+node.toString());
JsonToken removedToken = ((ObjectNode) node).remove("address").asToken();
System.out.println("Aft removal order:"+node.toString());
ObjectNode实现使用LinkedHashMap,它维护插入顺序:
public ObjectNode(JsonNodeFactory nc) {
super(nc);
_children = new LinkedHashMap<String, JsonNode>();
}
答案 9 :(得分:0)
继续 JSONObject类 从 HashMap()更改为 LinkedHashMap()
/**
* Construct an empty JSONObject.
*/
public JSONObject() {
this.map = new LinkedHashMap();
}
哈希类的哈希表。 Cette classe使用un liste doubleetchaînée竞争者吹捧了桌子餐桌上的ententes lesentréesde la tablehachée,dans l'ordreoùlesclésontétéinséréesdans la table:ceci permet d'obtenir un“ non chaotique” sur lesclés。 >
答案 10 :(得分:0)
我能够在类路径覆盖的帮助下做到这一点。
package org.json.simple
,该程序包与jar和名为JSONObject
的类中的程序包相同。
通过执行这两个步骤,它将保持顺序,因为从步骤1中创建的新包中选择`JSONObject的偏好要比jar更高。
答案 11 :(得分:0)
我通过执行以下操作来完成它:
JSONObject(json).put(key, ObjectMapper().writeValueAsString(ObjectMapper().readValue(string, whatever::class)))
因此本质上我将字符串反序列化为有序类,然后再次对其进行序列化。但是后来我还必须格式化该字符串以删除转义符。
.replace("\\\"", "\"").replace("\"{", "{").replace("}\"", "}")
如果您不希望使用null,则可能还必须替换null项目。