2016-02-12 69 views
9

我有許多類來自供應商喜歡隨機拋出RuntimeExceptions屬性訪問。如何讓傑克遜忽略屬性,如果吸氣者拋出異常

public Object getSomeProperty() { 
    if (!someObscureStateCheck()) { 
     throw new IllegalStateExcepion(); 
    } 
    return calculateTheValueOfProperty(someRandomState); 
} 

我不能改變類,可以不加註釋和是不現實的定義混入爲每一個類,因爲這部分的堆變化相當頻繁。

如何讓傑克遜忽略一個屬性,如果它的getter引發異常?

+0

是否可以使用try catch? –

+1

我想調查用自定義的'JsonGenerator'設置你的對象映射器,可能通過擴展和修改[默認實現](http://fasterxml.github.io/jackson-core/javadoc/2.4/com/fasterxml/ jackson/core/json/JsonGeneratorImpl.html)以不同的方式忽略/處理異常。 – Vulcan

回答

9

要在傑克遜執行custom serialization,您可以使用register a moduleBeanSerializerModifier來指定需要進行的任何修改。在你的情況下,BeanPropertyWriter.serializeAsField是負責序列化單個字段的方法,所以你應該自己製作BeanPropertyWriter,以忽略字段序列化的異常,並註冊一個模塊​​,使用changeProperties來替換所有默認的BeanPropertyWriter實例。下面的例子說明:

import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.databind.*; 
import com.fasterxml.jackson.databind.module.SimpleModule; 
import com.fasterxml.jackson.databind.ser.*; 

import java.io.IOException; 
import java.util.List; 
import java.util.stream.Collectors; 

public class JacksonIgnorePropertySerializationExceptions { 

    public static void main(String[] args) throws IOException { 
     ObjectMapper mapper = new ObjectMapper(); 
     mapper.registerModule(new SimpleModule().setSerializerModifier(new BeanSerializerModifier() { 
      @Override 
      public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) { 
       return beanProperties.stream().map(bpw -> new BeanPropertyWriter(bpw) { 
        @Override 
        public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception { 
         try { 
          super.serializeAsField(bean, gen, prov); 
         } catch (Exception e) { 
          System.out.println(String.format("ignoring %s for field '%s' of %s instance", e.getClass().getName(), this.getName(), bean.getClass().getName())); 
         } 
        } 
       }).collect(Collectors.toList()); 
      } 
     })); 

     mapper.writeValue(System.out, new VendorClass()); 
    } 

    public static class VendorClass { 
     public String getNormalProperty() { 
      return "this is a normal getter"; 
     } 

     public Object getProblematicProperty() { 
      throw new IllegalStateException("this getter throws an exception"); 
     } 

     public String getAnotherNormalProperty() { 
      return "this is a another normal getter"; 
     } 
    } 
} 

上面的代碼輸出下面,使用傑克遜2.7.1和Java 1.8:

ignoring java.lang.reflect.InvocationTargetException for field 'problematicProperty' of JacksonIgnorePropertySerializationExceptions$VendorClass instance 
{"normalProperty":"this is a normal getter","anotherNormalProperty":"this is a another normal getter"} 

表示getProblematicProperty,這將引發IllegalStateException,將從串行化可以省略值。