Java类转换为JSONObject时成员顺序被打乱,如何保留原有顺序?
问题原因
- 问题出在
JSONParser.parse生成JSONObject的环节:你当前使用的JSON解析库的JSONObject底层默认基于HashMap实现,HashMap本身不保留插入顺序,解析JSON字符串时会自动重排字段顺序,和ObjectMapper序列化环节无关。 - 额外说明:JSON规范本身不要求字段顺序,因此绝大多数JSON库的默认实现都会忽略字段顺序,需要保留顺序必须手动指定有序存储结构。
- 注意你代码中
parser.perse是笔误,正确写法为parser.parse。
解决方案
方案1:全程使用Jackson的API(推荐)
Jackson自身的JsonNode支持保留字段顺序,无需引入第三方JSON解析库,调整代码如下:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.MapperFeature; // ... ObjectMapper mapper = new ObjectMapper(); // 配置ObjectMapper按Java类字段声明顺序序列化,避免生成JSON字符串时就乱序 mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false); String obj = mapper.writeValueAsString(myClass); // 直接用Jackson解析,得到的JsonNode会保留原有字段顺序 JsonNode jsonNode = mapper.readTree(obj);
如果需要全局控制或者指定类的序列化顺序,可以给对应的Java类添加@JsonPropertyOrder注解:
import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonPropertyOrder(alphabetic = false) public class MyClass { // 按声明顺序排列的字段 private String authorisation; private List<String> signatries; // 其他字段、getter、setter方法 }
方案2:必须使用第三方JSONObject的场景
如果项目强制要求使用org.json或者org.json.simple的JSONObject,可以通过指定有序存储容器实现顺序保留:
针对org.json包
直接调用支持保序的构造方法即可:
import org.json.JSONObject; // ... ObjectMapper mapper = new ObjectMapper(); mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false); String obj = mapper.writeValueAsString(myClass); // 第二个参数传true表示保留字段顺序,底层会用LinkedHashMap存储 JSONObject jsonObject = new JSONObject(obj, true);
针对org.json.simple包
升级到1.1.1及以上版本,解析时指定自定义容器工厂:
import org.json.simple.parser.ContainerFactory; import org.json.simple.parser.JSONParser; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; // ... JSONParser parser = new JSONParser(); // 自定义容器工厂,对象用LinkedHashMap存储保证顺序 ContainerFactory orderedContainerFactory = new ContainerFactory() { @Override public Map createObjectContainer() { return new LinkedHashMap<>(); } @Override public List creatArrayContainer() { return new ArrayList<>(); } }; ObjectMapper mapper = new ObjectMapper(); mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false); String obj = mapper.writeValueAsString(myClass); JSONObject jsonObject = (JSONObject) parser.parse(obj, orderedContainerFactory);
内容的提问来源于stack exchange,提问作者user2746466
相关产品推荐
相关产品推荐

