2015-03-20 5 views
2

Я пытаюсь десериализовать объект JSON, полученный из веб-сервиса RESTful. У меня есть следующий класс:Jackson: ignore unknown enum values ​​

public class ACE { 
    private Persona trustee; 
    private String accesstype; 
    private final Set<Right> accessrights = EnumSet.noneOf(Right.class); 
    private final Set<Inheritance> inherit_flags 
      = EnumSet.noneOf(Inheritance.class); 
    private String op; 

    public static enum Right { 
     traverse, list, dir_read_attr, dir_read_ext_attr, add_file, add_subdir, 
     dir_write_attr, dir_write_ext_attr, delete_child, std_delete, 
     std_read_dac, std_write_dac, std_write_owner, 

     dir_gen_all, dir_gen_execute, dir_gen_read, dir_gen_write, modify; 
    } 

    public static enum Inheritance { 
     object_inherit, container_inherit, no_prop_inherit, inherit_only, 
     inherited_ace; 
    } 

    public ACE setAccessrights(Set<Right> rights) { 
     accessrights.clear(); 
     accessrights.addAll(rights); 
     return this; 
    } 
... 

Теперь WebServices возвращает «std_synchronize» в наборе «AccessRights», который является значением, которое не определено в правильном перечислимого типа.

Я получаю следующее исключение:

com.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: gina.nas.ws.ACL["acl"]->gina.nas.ws.ACE["accessrights"]) 
      at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:421) 
      at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:404) 
      at com.fasterxml.jackson.databind.deser.impl.MethodProperty.set(MethodProperty.java:116) 
      at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) 
      at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) 
      at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) 
      at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:147) 
      at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18) 
      at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375) 
      at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) 
      at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) 
      at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) 
      at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2793) 
      at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1989) 
      at gina.nas.ws.NasSession.getACL(NasSession.java:188) 
      at gina.nas.NasAPI.getSecurity(NasAPI.java:451) 
      at gina.nas.NasAPI.getSecurity(NasAPI.java:244) 
     at gina.nas.NasHelper.setStructureUOACL(NasHelper.java:622) 
     at gina.nas.NasHelper.setStructureUOACL(NasHelper.java:263) 
     at gina.nas.NasHelper.setStructureUOACL(NasHelper.java:280) 
     at gina.nas.NasHelper.setStructureUOACL(NasHelper.java:299) 
     at gina.nas.NasHelper.setStructureUOACL(NasHelper.java:317) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126) 
     ... 13 more 
Caused by: java.lang.NullPointerException 
     at java.util.EnumSet.typeCheck(Unknown Source) 
     at java.util.RegularEnumSet.add(Unknown Source) 
     at java.util.RegularEnumSet.add(Unknown Source) 
     at java.util.AbstractCollection.addAll(Unknown Source) 
     at java.util.RegularEnumSet.addAll(Unknown Source) 
     at gina.nas.ws.ACE.setAccessrights(ACE.java:51) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:97) 
     ... 38 more 

Я установил следующий флаг в ObjectMapper:

mapper.configure(
     DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); 

но проблема, кажется, возникает, когда джексон пытается добавить к нулю задавать.

Есть ли способ просто игнорировать неизвестные значения?

+0

В моем тестовом случае исключение не возникает, поэтому я думаю, что проблема заключается в методе ACE.setAccessrights. можете ли вы опубликовать его? – Giovanni

+0

@ Гиованни, ты прав. Я только что добавил метод. –

ответ

3

мне не удалось воспроизвести вашу проблему с Джексоном 2.5.1

Это мой класс ACE

public class ACE { 
    private final Set<Right> accessrights = EnumSet.noneOf(Right.class); 
    private final Set<Inheritance> inherit_flags 
      = EnumSet.noneOf(Inheritance.class); 

    public static enum Right { 
     traverse, list, dir_read_attr, dir_read_ext_attr, add_file, add_subdir, 
     dir_write_attr, dir_write_ext_attr, delete_child, std_delete, 
     std_read_dac, std_write_dac, std_write_owner, 
     dir_gen_all, dir_gen_execute, dir_gen_read, dir_gen_write, modify; 
    } 

    public static enum Inheritance { 
     object_inherit, container_inherit, no_prop_inherit, inherit_only, 
     inherited_ace; 
    } 

    public Set<Right> getAccessrights() { 
     return accessrights; 
    } 

    public Set<Inheritance> getInherit_flags() { 
     return inherit_flags; 
    } 

} 

это мой тест:

package test; 

import test.ACE.Inheritance; 
import test.ACE.Right; 

import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.ObjectMapper; 

public class TestJacksonEnum { 

    public static void main(String[] args) throws Exception { 
     // TODO Auto-generated method stub 
     ACE ace= new ACE(); 
     ace.getAccessrights().add(Right.add_file); 
     ace.getAccessrights().add(Right.add_subdir); 
     ace.getInherit_flags().add(Inheritance.container_inherit); 
     ace.getInherit_flags().add(Inheritance.inherit_only); 
     ObjectMapper mapper=new ObjectMapper(); 
     mapper.configure(
       DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); 
     System.out.println(mapper.writeValueAsString(ace)); 
     String serializedFormREST="{\"accessrights\":[\"std_synchronize\",\"add_subdir\"],\"inherit_flags\":[\"container_inherit\",\"inherit_only\"]}"; 
     ACE deserializedAce= mapper.readValue(serializedFormREST, ACE.class); 
     System.out.println(mapper.writeValueAsString(deserializedAce)); 
    } 


} 

Объект deserializedAce является читайте правильно, и набор не содержит std_synchronize, но содержит нуль. Я что-то упускаю?

+0

Вы правы: проблема, похоже, в настройщике (я добавил код для сеттера), точнее, с набором, который джексон переходит в сеттер. Он работает, если я объявляю параметр EnumSet вместо Set. –

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