在 Jackson 中反序列化 JSON,其中键是一个值
Deserialize JSON in Jackson where key is a value
{
{
"1234": {
"name": "bob"
}
},
{
"5678": {
"name": "dan"
}
}
}
我有一个 class 表示名称(和其他字段,我只是简单地解决了这个问题)。但是每个元素都以人的 id 为关键字。
我尝试了几种方法,包括:
class Name {
String Name;
//getter and setter
}
class NameId {
String id;
Name name;
//getter and setters
}
//json is the string containing of the above json
ArrayList<NameId> map = objectMapper.readValue(json, ArrayList.class);
for (Object m : map) {
LinkedHashMap<String, NameId> l = (LinkedHashMap)m;
Map<String, NameId> value = (Map<String, NameId>) l;
//System.out.println(l);
//System.out.println(value);
for (Object key : value.keySet()) {
System.out.println("key: " + key);
System.out.println("obj: " + value.get(key));
NameId nameId = (NameId)value.get(key);
}
}
我遇到的问题是它不允许强制转换为 NameId。我得到的错误是:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to NameId
关于正确解析这样的 json 字符串的最佳方法有什么想法吗?
试试这个
Iterator<String> iterator1 =outerObject.keys();
while(iterator1.hasNext())
{
JsonObject innerObject=outerObject.getJsonObject(iterator1.next());
Iterator<String> iterator2=innerObject.keys();
while(iterator2.hasNext()){
String name=innerObject.getString(iterator2.next());
}
}
您的 json 无效。可能有点不同:
{
"1234": {
"name": "bob"
},
"5678": {
"name": "dan"
}
}
你可以这样建模:
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
不要尝试使用列表,而是使用地图:
Map<Integer, Person> map = new ObjectMapper().readValue(json,
TypeFactory.defaultInstance()
.constructMapType(Map.class, Integer.class, Person.class));
您的 json 格式不正确。您需要在它周围加上方括号,否则它不会被视为 json 数组。如果您的 json 看起来像(例如)
[
{
"1234" : {
"name" : "dan"
}
},
{
"5678" : {
"name" : "mike"
}
}
]
您可以为对象映射器编写自定义反序列化程序。请参阅下面的工作示例:
public static void main(String... args) throws Exception {
String testJson = "[{ \"1234\" : { \"name\" : \"dan\" } },{ \"5678\" : { \"name\" : \"mike\" } }]";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(NameId.class, new MyDeserializer());
mapper.registerModule(module);
ArrayList<NameId> map = mapper.readValue(testJson.getBytes(), new TypeReference<List<NameId>>() {
});
for (NameId m : map) {
System.out.println(m.id);
System.out.println(m.name.name);
System.out.println("----");
}
}
@JsonDeserialize(contentUsing = MyDeserializer.class)
static class NameId {
String id;
Name name;
//getter and setters
}
static class Name {
String name;
//getter and setter
}
static class MyDeserializer extends JsonDeserializer<NameId> {
@Override
public NameId deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
Map.Entry<String, JsonNode> nodeData = node.fields().next();
String id = nodeData.getKey();
String name = nodeData.getValue().get("name").asText();
Name nameObj = new Name();
nameObj.name = name;
NameId nameIdObj = new NameId();
nameIdObj.name = nameObj;
nameIdObj.id = id;
return nameIdObj;
}
}
不需要自定义解串器。
首先,@klaimmore 建议的 json 文件(命名为 test.json):
{
"1234": {
"name": "bob"
},
"5678": {
"name": "dan"
}
}
其次。这是 2 个单独的 class 文件:
@JsonDeserialize
public class Name {
String name;
public Name(String name) {
this.name = name;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
和
@JsonDeserialize
public class NameId {
Name name;
String id;
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public Name getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(Name name) {
this.name = name;
}
}
和额外简单的 json 解析器 class.
public class JsonParser {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String jsonString = new String(Files.readAllBytes(Paths.get("test.json")));
ObjectMapper mapper = new ObjectMapper();
Map<String,NameId> nameIdList = mapper.readValue(jsonString, new TypeReference<Map<String,NameId>>(){});
nameIdList.entrySet().forEach(nameIdEntry -> System.out.println("name id is: " + nameIdEntry.getKey() +
" and name is: " + nameIdEntry.getValue().getName().getName()));
}
}
还有。这几乎是 的骗局。你应该读读这个。
{
{
"1234": {
"name": "bob"
}
},
{
"5678": {
"name": "dan"
}
}
}
我有一个 class 表示名称(和其他字段,我只是简单地解决了这个问题)。但是每个元素都以人的 id 为关键字。
我尝试了几种方法,包括:
class Name {
String Name;
//getter and setter
}
class NameId {
String id;
Name name;
//getter and setters
}
//json is the string containing of the above json
ArrayList<NameId> map = objectMapper.readValue(json, ArrayList.class);
for (Object m : map) {
LinkedHashMap<String, NameId> l = (LinkedHashMap)m;
Map<String, NameId> value = (Map<String, NameId>) l;
//System.out.println(l);
//System.out.println(value);
for (Object key : value.keySet()) {
System.out.println("key: " + key);
System.out.println("obj: " + value.get(key));
NameId nameId = (NameId)value.get(key);
}
}
我遇到的问题是它不允许强制转换为 NameId。我得到的错误是:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to NameId
关于正确解析这样的 json 字符串的最佳方法有什么想法吗?
试试这个
Iterator<String> iterator1 =outerObject.keys();
while(iterator1.hasNext())
{
JsonObject innerObject=outerObject.getJsonObject(iterator1.next());
Iterator<String> iterator2=innerObject.keys();
while(iterator2.hasNext()){
String name=innerObject.getString(iterator2.next());
}
}
您的 json 无效。可能有点不同:
{
"1234": {
"name": "bob"
},
"5678": {
"name": "dan"
}
}
你可以这样建模:
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
不要尝试使用列表,而是使用地图:
Map<Integer, Person> map = new ObjectMapper().readValue(json,
TypeFactory.defaultInstance()
.constructMapType(Map.class, Integer.class, Person.class));
您的 json 格式不正确。您需要在它周围加上方括号,否则它不会被视为 json 数组。如果您的 json 看起来像(例如)
[
{
"1234" : {
"name" : "dan"
}
},
{
"5678" : {
"name" : "mike"
}
}
]
您可以为对象映射器编写自定义反序列化程序。请参阅下面的工作示例:
public static void main(String... args) throws Exception {
String testJson = "[{ \"1234\" : { \"name\" : \"dan\" } },{ \"5678\" : { \"name\" : \"mike\" } }]";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(NameId.class, new MyDeserializer());
mapper.registerModule(module);
ArrayList<NameId> map = mapper.readValue(testJson.getBytes(), new TypeReference<List<NameId>>() {
});
for (NameId m : map) {
System.out.println(m.id);
System.out.println(m.name.name);
System.out.println("----");
}
}
@JsonDeserialize(contentUsing = MyDeserializer.class)
static class NameId {
String id;
Name name;
//getter and setters
}
static class Name {
String name;
//getter and setter
}
static class MyDeserializer extends JsonDeserializer<NameId> {
@Override
public NameId deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
Map.Entry<String, JsonNode> nodeData = node.fields().next();
String id = nodeData.getKey();
String name = nodeData.getValue().get("name").asText();
Name nameObj = new Name();
nameObj.name = name;
NameId nameIdObj = new NameId();
nameIdObj.name = nameObj;
nameIdObj.id = id;
return nameIdObj;
}
}
不需要自定义解串器。
首先,@klaimmore 建议的 json 文件(命名为 test.json):
{
"1234": {
"name": "bob"
},
"5678": {
"name": "dan"
}
}
其次。这是 2 个单独的 class 文件:
@JsonDeserialize
public class Name {
String name;
public Name(String name) {
this.name = name;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
和
@JsonDeserialize
public class NameId {
Name name;
String id;
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the name
*/
public Name getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(Name name) {
this.name = name;
}
}
和额外简单的 json 解析器 class.
public class JsonParser {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String jsonString = new String(Files.readAllBytes(Paths.get("test.json")));
ObjectMapper mapper = new ObjectMapper();
Map<String,NameId> nameIdList = mapper.readValue(jsonString, new TypeReference<Map<String,NameId>>(){});
nameIdList.entrySet().forEach(nameIdEntry -> System.out.println("name id is: " + nameIdEntry.getKey() +
" and name is: " + nameIdEntry.getValue().getName().getName()));
}
}
还有。这几乎是