为什么 Predicates.instanceOf returns 是假的?
Why does Predicates.instanceOf returns false?
我有一个
String s =
{
"code1" : {
"price" : 100,
"type" : null
},
"code2" : {
"price" : 110,
"type" : null
}
}
然后我做:
Object p = Mapper.readValue(s, Person.class);
所以执行Person.class
中注解为@JsonCreator
的方法:
@JsonCreator
static Person create(Map<String, Object> s) {
s = Maps.filterValues(s, Predicates.instanceOf(Person.class));
...
}
我的问题是 s
总是空的。我检查了一下,这些值有一个 price
和一个 type
。但是当我做 ps.get("code1").getClass()
时,它给了我 LinkedHashMap
.
我不明白发生了什么......你有什么线索吗?
这是我的classPerson
(这是一个内部class):
public static class Person{
private int price;
private String type;
public Person(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public String getType() {
return type;
}
}
谢谢!
问题是你正在将 json String
反序列化为 Object
并且你将始终在那里有 LinkedHashMap
,因为 java.lang.Object
没有任何自定义字段。
换一种方式试试:
public class Demo {
public static void main(String[] args) throws IOException {
String s = "{" +
" \"code1\" : {" +
" \"price\" : 100," +
" \"type\" : null" +
" }," +
" \"code3\" : {" +
" \"somethingElsse\" : false," +
" \"otherType\" : 1" +
" }," +
" \"code2\" : {" +
" \"price\" : 110," +
" \"type\" : null" +
" }" +
"}";
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Map<String, Person> mapPerson = mapper.readValue(s, MapPerson.class);
Map<String, Person> filteredMap = Maps.filterValues(mapPerson, new Predicate<Person>() {
@Override
public boolean apply(Person person) {
return person.isNotEmpty();
}
});
System.out.println(filteredMap);
}
public static class MapPerson extends HashMap<String, Person> {}
public static class Person{
private int price;
private String type;
public Person() {
}
public boolean isNotEmpty() {
return !(0 == price && null ==type);
}
@Override
public String toString() {
return "Person{" +
"price=" + price +
", type='" + type + '\'' +
'}';
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
当您使用 configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
配置对象映射器时,它只会将一个空的 Person 实例添加到您的映射中,而不是抛出异常。
因此,您还应该定义一个方法,如果 Person 的实例为空,然后使用它过滤您的地图。
如果你使用java 8你可以在过滤地图时有更少的代码:
Map<String, Person> filteredMap = Maps.filterValues(mapPerson, Person::isNotEmpty);
顺便说一句,即使您在键值中有一些额外的字段,它也可以工作 JSON:
{
"code1" : {
"price" : 100,
"type" : null,
"uselessExtraField": "Hi Stack"
},
"code2" : {
"price" : 110,
"type" : null,
"anotherAccidentalField": "What?"
}
}
您将得到相同的结果,就好像该字段从未存在过一样。
我有一个
String s =
{
"code1" : {
"price" : 100,
"type" : null
},
"code2" : {
"price" : 110,
"type" : null
}
}
然后我做:
Object p = Mapper.readValue(s, Person.class);
所以执行Person.class
中注解为@JsonCreator
的方法:
@JsonCreator
static Person create(Map<String, Object> s) {
s = Maps.filterValues(s, Predicates.instanceOf(Person.class));
...
}
我的问题是 s
总是空的。我检查了一下,这些值有一个 price
和一个 type
。但是当我做 ps.get("code1").getClass()
时,它给了我 LinkedHashMap
.
我不明白发生了什么......你有什么线索吗?
这是我的classPerson
(这是一个内部class):
public static class Person{
private int price;
private String type;
public Person(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public String getType() {
return type;
}
}
谢谢!
问题是你正在将 json String
反序列化为 Object
并且你将始终在那里有 LinkedHashMap
,因为 java.lang.Object
没有任何自定义字段。
换一种方式试试:
public class Demo {
public static void main(String[] args) throws IOException {
String s = "{" +
" \"code1\" : {" +
" \"price\" : 100," +
" \"type\" : null" +
" }," +
" \"code3\" : {" +
" \"somethingElsse\" : false," +
" \"otherType\" : 1" +
" }," +
" \"code2\" : {" +
" \"price\" : 110," +
" \"type\" : null" +
" }" +
"}";
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Map<String, Person> mapPerson = mapper.readValue(s, MapPerson.class);
Map<String, Person> filteredMap = Maps.filterValues(mapPerson, new Predicate<Person>() {
@Override
public boolean apply(Person person) {
return person.isNotEmpty();
}
});
System.out.println(filteredMap);
}
public static class MapPerson extends HashMap<String, Person> {}
public static class Person{
private int price;
private String type;
public Person() {
}
public boolean isNotEmpty() {
return !(0 == price && null ==type);
}
@Override
public String toString() {
return "Person{" +
"price=" + price +
", type='" + type + '\'' +
'}';
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
当您使用 configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
配置对象映射器时,它只会将一个空的 Person 实例添加到您的映射中,而不是抛出异常。
因此,您还应该定义一个方法,如果 Person 的实例为空,然后使用它过滤您的地图。
如果你使用java 8你可以在过滤地图时有更少的代码:
Map<String, Person> filteredMap = Maps.filterValues(mapPerson, Person::isNotEmpty);
顺便说一句,即使您在键值中有一些额外的字段,它也可以工作 JSON:
{
"code1" : {
"price" : 100,
"type" : null,
"uselessExtraField": "Hi Stack"
},
"code2" : {
"price" : 110,
"type" : null,
"anotherAccidentalField": "What?"
}
}
您将得到相同的结果,就好像该字段从未存在过一样。