2016-10-06 5 views
0

У меня естьПочему Predicates.instanceOf возвращает false?

String s = 
    { 
     "code1" : { 
     "price" : 100, 
     "type" : null 
     }, 
     "code2" : { 
     "price" : 110, 
     "type" : null 
     } 
    } 

Тогда я:

Object p = Mapper.readValue(s, Person.class); 

Так выполняет метод с аннотацией @JsonCreator в Person.class:

@JsonCreator 
static Person create(Map<String, Object> s) { 
     s = Maps.filterValues(s, Predicates.instanceOf(Person.class)); 
     ... 
    } 

Моя проблема заключается s всегда пусто. Я проверил, и значения имеют price и type. Но когда я делаю ps.get("code1").getClass(), он дает мне LinkedHashMap.

Я не понимаю, что происходит ... У вас есть ключ?

Это мой класс Person (это внутренний класс):

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; 
     } 
    } 

Спасибо!

+0

Это проблема с курицей и яйцом. Вы буквально пишете создателя для класса Person. Как ожидать, что значения Object на карте могут быть экземплярами Person еще? – rmlan

+0

@ jordaniac89 А? Это не то, что означает это утверждение. – rmlan

+0

Не могли бы вы предоставить защиту класса Person – eGoLai

ответ

1

Проблема заключается в том, что вы десериализации 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-вы можете иметь меньше коды при фильтрации карты:

Map<String, Person> filteredMap = Maps.filterValues(mapPerson, Person::isNotEmpty); 

BTW, он будет работать вино, даже у вас есть какие-то дополнительные поля внутри ключевых значений обозревают вам JSON:

{ 
     "code1" : { 
     "price" : 100, 
     "type" : null, 
     "uselessExtraField": "Hi Stack" 
     }, 
     "code2" : { 
     "price" : 110, 
     "type" : null, 
     "anotherAccidentalField": "What?" 
     } 
    } 

У вас будет такой же результат, как если бы эти поля никогда не существовали.

+0

Хорошо, я понимаю, почему у меня всегда есть «LinkedHashMap» ... Спасибо! – dardy

 Смежные вопросы

  • Нет связанных вопросов^_^