为什么我不能打开根节点并反序列化一个对象数组?
Why can't I unwrap the root node and deserialize an array of objects?
为什么我无法通过展开根节点来反序列化对象数组?
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonRootName;
import org.junit.Assert;
import org.junit.Test;
public class RootNodeTest extends Assert {
@JsonRootName("customers")
public static class Customer {
public String email;
}
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
List<Customer> customers = Arrays.asList(mapper.readValue(json, Customer[].class));
System.out.println(customers);
}
}
我一直在研究 Jackson 的文档,这是我能弄清楚的,但是在 运行 之后,我收到以下错误:
A org.codehaus.jackson.map.JsonMappingException has been caught, Root name 'customers' does not match expected ('Customer[]') for type [array type, component type: [simple type, class tests.RootNodeTest$Customer]] at [Source: java.io.StringReader@49921538; line: 1, column: 2]
我想在不创建包装器的情况下完成此操作 class。虽然这是一个示例,但我不想创建不必要的包装器 classes 仅用于展开根节点。
看来你无法逃脱包装器 class。
根据 this,@JsonRootName
注释只允许您解包一个包含单个 pojo 实例的 json:
所以它适用于这样的字符串:"{\"customer\":{\"email\":\"hello@world.com\"}}";
创建一个 ObjectReader 以显式配置根名称:
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectReader objectReader = mapper.reader(new TypeReference<List<Customer>>() {})
.withRootName("customers");
List<Customer> customers = objectReader.readValue(json);
assertThat(customers, contains(customer("hello@world.com"), customer("john.doe@example.com")));
}
(顺便说一句,这是 Jackson 2.5,你有不同的版本吗?我有 DeserializationFeature 而不是 DeserializationConfig.Feature)
似乎通过以这种方式使用对象 reader,您不需要全局配置 "unwrap root value" 功能,也不需要使用 @JsonRootName
注释。
另请注意,您可以直接请求 List<Customer>
而不是通过数组 - 给 ObjectMapper.reader
的类型就像 ObjectMapper.readValue
[=15= 的第二个参数一样工作]
这段代码对我有用:
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class RootNodeTest extends Assert {
public static class CustomerMapping {
public List<Customer> customer;
public List<Customer> getCustomer() {
return customer;
}
public static class Customer {
public String email;
public String getEmail() {
return email;
}
}
}
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customer\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectMapper mapper = new ObjectMapper();
CustomerMapping customerMapping = mapper.readValue(json, CustomerMapping.class);
List<CustomerMapping.Customer> customers = customerMapping.getCustomer();
for (CustomerMapping.Customer customer : customers) {
System.out.println(customer.getEmail());
}
}
}
首先,您需要一个 java 对象作为整个 json 对象。在我的例子中,这是 CustomerMapping。然后您需要一个 java 对象作为您的客户密钥。在我的例子中,这是内部 class CustomerMapping.Customer。因为 customer 是一个 json 数组,所以您需要 CustomerMapping.Customer 个对象的列表。此外,您不需要将 json 数组映射到 java 数组并将其转换为列表。杰克逊已经为你做了。最后,您只需指定 String 类型的变量 email 并将其打印到控制台即可。
为什么我无法通过展开根节点来反序列化对象数组?
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonRootName;
import org.junit.Assert;
import org.junit.Test;
public class RootNodeTest extends Assert {
@JsonRootName("customers")
public static class Customer {
public String email;
}
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
List<Customer> customers = Arrays.asList(mapper.readValue(json, Customer[].class));
System.out.println(customers);
}
}
我一直在研究 Jackson 的文档,这是我能弄清楚的,但是在 运行 之后,我收到以下错误:
A org.codehaus.jackson.map.JsonMappingException has been caught, Root name 'customers' does not match expected ('Customer[]') for type [array type, component type: [simple type, class tests.RootNodeTest$Customer]] at [Source: java.io.StringReader@49921538; line: 1, column: 2]
我想在不创建包装器的情况下完成此操作 class。虽然这是一个示例,但我不想创建不必要的包装器 classes 仅用于展开根节点。
看来你无法逃脱包装器 class。
根据 this,@JsonRootName
注释只允许您解包一个包含单个 pojo 实例的 json:
所以它适用于这样的字符串:"{\"customer\":{\"email\":\"hello@world.com\"}}";
创建一个 ObjectReader 以显式配置根名称:
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customers\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectReader objectReader = mapper.reader(new TypeReference<List<Customer>>() {})
.withRootName("customers");
List<Customer> customers = objectReader.readValue(json);
assertThat(customers, contains(customer("hello@world.com"), customer("john.doe@example.com")));
}
(顺便说一句,这是 Jackson 2.5,你有不同的版本吗?我有 DeserializationFeature 而不是 DeserializationConfig.Feature)
似乎通过以这种方式使用对象 reader,您不需要全局配置 "unwrap root value" 功能,也不需要使用 @JsonRootName
注释。
另请注意,您可以直接请求 List<Customer>
而不是通过数组 - 给 ObjectMapper.reader
的类型就像 ObjectMapper.readValue
[=15= 的第二个参数一样工作]
这段代码对我有用:
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class RootNodeTest extends Assert {
public static class CustomerMapping {
public List<Customer> customer;
public List<Customer> getCustomer() {
return customer;
}
public static class Customer {
public String email;
public String getEmail() {
return email;
}
}
}
@Test
public void testUnwrapping() throws IOException {
String json = "{\"customer\":[{\"email\":\"hello@world.com\"},{\"email\":\"john.doe@example.com\"}]}";
ObjectMapper mapper = new ObjectMapper();
CustomerMapping customerMapping = mapper.readValue(json, CustomerMapping.class);
List<CustomerMapping.Customer> customers = customerMapping.getCustomer();
for (CustomerMapping.Customer customer : customers) {
System.out.println(customer.getEmail());
}
}
}
首先,您需要一个 java 对象作为整个 json 对象。在我的例子中,这是 CustomerMapping。然后您需要一个 java 对象作为您的客户密钥。在我的例子中,这是内部 class CustomerMapping.Customer。因为 customer 是一个 json 数组,所以您需要 CustomerMapping.Customer 个对象的列表。此外,您不需要将 json 数组映射到 java 数组并将其转换为列表。杰克逊已经为你做了。最后,您只需指定 String 类型的变量 email 并将其打印到控制台即可。