2011-05-27 76 views
2

Jackson具有便利的功能,您可以使用specify custom constructors or static factory methods to use when creating a class, getting parameters from the JSON object。然而,我不知道什麼最好的方法是將一個額外的構造函數參數傳遞給反序列化的對象。例如,我希望能有傑克遜使用JSON來構建和初始化以下類:反序列化JSON時指定創建類的其他參數

{ 
    "x": "foo", 
    "y": "bar", 
    "z": "baz" 
} 

public class Foo { 
    /* 
    * conf and x <b>must</b> be supplied at construction time 
    */ 
    @JsonCreator 
    public Foo(Configuration conf, @JsonValue("x") String x) 

    public String getX(); 

    public String getY(); 
    public void setY(String y); 
    public String getZ(); 
    public void setZ(String z); 
} 

public class SomeMainApplicationClass { 
    public Foo loadFoo(InputStream in, Configuration conf) { 
     ObjectMapper mapper = new ObjectMapper(/* ??? */); 
     /* ??? */ 
     return mapper.readValue(in, Foo.class); 
    } 
} 

我的第一反應是,我需要創造一些工廠對象:

public class FooFactory { 
    private final Configuration conf; 
    public FooFactory(Configuration conf) { 
     this.conf = conf; 
    } 
    @JsonCreator 
    public createFoo(@JsonProperty("x") String x) { 
     return new Foo(conf, x); 
    } 
} 

但傑克遜並沒有直截了當地插上,在 - 大多數的方法我發現(或基於註釋的選項)使用靜態工廠方法。

答案不得使用全局/靜態變量 - 我想以每個ObjectMapper基礎上配置的配置對象。

我的首選答案應該

  • 是短暫的!我知道有多種方法可以解決這個問題,我正在尋找最簡單的方法
  • 繼續利用Jackson的反思能力,並將data-binding annotations解釋爲非構造函數屬性,而不是編寫必須更新的Deserializer一次,我添加或編輯設置屬性
    • 應該不需要我手動讀取和JSON緩衝對象屬性(即不重複BeanDeserializer._deserializeUsingPropertyBased)
  • 工作與annotation mix-ins

我已經探索過設置自定義CreatorContainersDeserializerProviders,但我還沒有想出符合我的要求的方法。

回答

1

目前沒有這樣的設施;會「在反序列化過程中注入值的能力」(請參見http://jira.codehaus.org/browse/JACKSON-406)這樣做?您可能要問這個傑克遜用戶(或開發者)郵件列表上,因爲這是,希望能對傑克遜進行1.9制定更高的優先級的功能之一。

一種可能性就是使用@JsonCreator,用@JsonParameter修飾所有參數,並從那裏訪問值 - 如果沒有匹配的屬性,您將得到null值。這是不是最佳的,但如果你可以訪問你需要的值,你會至少能夠解決這個(通過ThreadLocal中,在調用反序列化填寫)。

+0

感謝您的回答。 JACKSON-406將不完全解決了使用情況下,我在腦子裏(雖然這將是在自己的權利是有用的),但我決定無論如何要採取不同的方法。我敢肯定,這將至少是可能的,但我最終來到了,我不得不爲了完成它近乎重複的代碼庫量不可接受的結論。 – Miles 2011-06-03 06:01:42

+0

(我認爲我可以用CreatorContainer創建一個BeanDeserializer,該CreatorContainer返回一個調用非靜態方法的自定義PropertyBased構造函數,但當我發現工廠方法靜態調用時,放棄了。)ThreadLocal也是一個合理的建議 - 我發佈這個問題後我自己想到了。 – Miles 2011-06-03 06:06:03

+0

是的,非常好的偵探工作。 :-)唉,我同意在不修改代碼庫代碼的情況下這個特殊功能很難做到。 – StaxMan 2011-06-03 16:59:00