簡體   English   中英

Umarshall JSON對象,包含Jackson和JAXB之間的下划線和camelCase字段

[英]Umarshall JSON object with underscore and camelCase fields between Jackson and JAXB

使用JAXB(2.2)和Jackson(1.9.13),我無法將以下JSON對象解組到我的POJO

{
   "userId": "foo",
   "group_id": "bar"
}

請注意,有效負載包含camelCase和下划線字段。

xjc為我的XML模式生成的POJO如下:

public class User {
    @XmlElement(required = true)
    protected String userId;
    @XmlElement(name = "group_id", required = true)
    protected String groupId;

    public String getUserId() { return userId; }       
    public void setUserId(String value) { this.userId = value; }
    public String getGroupId() { return groupId; }
    public void setGroupId(String value) { this.groupId = value; }
}

傑克遜因以下例外而失敗:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "group_id"

到目前為止我嘗試過但失敗了

1.使用JAXB綁定underscoreBinding="asCharInWord"

在我的XML模式中使用以下JXB綁定

<jxb:globalBindings underscoreBinding="asCharInWord"/>

生成以下POJO:

public class User {
    @XmlElement(required = true)
    protected String userId;
    @XmlElement(name = "group_id", required = true)
    protected String groupId;

    public String getUserId() { return userId; }
    public void setUserId(String value) { this.userId = value; }
    public String getGroup_Id() { return groupId; }
    public void setGroup_Id(String value) { this.groupId = value; }
}

請注意,JAXB現在為組ID生成帶下划線的setter / getter,但group_id字段仍然轉換為CamelCase。 Jackson的對象映射器似乎忽略了屬性getter / setter名稱,仍然無法將group_id映射到groupId

2.傑克遜財產命名策略

使用Jackson的PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES我可以將group_id轉換為groupId ,但現在對象映射器在userId JSON屬性上失敗。

3.向groupId添加JSONProperty批注

JSONProperty添加到vanilla JAXB生成的POJO實際上是有效的

public class User {
        /* ... */
        @XmlElement(name = "group_id", required = true)
        @JSONProperty("group_id")
        protected String groupId;
        /* ... */
   }

但是,我的XML模式非常龐大,並且生成的類的手動檢測是不可行的,因為我們經常生成類。

我該怎么辦?

我看到以下兩個剩余的選項來處理這個問題:

  1. 實現一個JAXB插件,增加了一個JSONProperty注釋每個XMLElement有下划線的名稱(我的首選另一個方法)
  2. 如此 Stackoverflow答案中所述,為XJC使用自定義名稱生成器。

我錯過了明顯的嗎? 謝謝你的想法。

您是否嘗試使用@JsonProperty("group_id")在用戶類中注釋groupId屬性。 這應該工作(測試和證明)!

如果屬性上沒有這樣的注釋,Jackson映射器將只考慮屬性名稱,否則提供的值將用於JSON反序列化。 以下是應該如何查看您的User類:

public class User {

private String userId;

@JsonProperty("group_id")
private String groupId;

這應該映射到您的JSON

{"userId": "foo","group_id": "bar"}

如果您正在使用基於Jackson的CXF(或任何其他Rest框架),我建議您閱讀以下簡短的博客文章,其中詳細介紹了如何在CXF中配置JacksonJsonProvider以實現Java / JSON Snake的序列化和反序列化大小寫(下划線)格式化數據

https://mahichir.wordpress.com/2015/07/08/cxf-configuration-to-produce-json-snake-case-underscore-case-formatted-data-using-jackson-json-library/

我發現了一個可能的解決方案,從類似的情況,在stackoverflow上。 如何從JAX-RS客戶端提取ObjectMapper?

一旦您可以訪問Object Mapper,就可以設置自己的注釋提供程序。 現在,作為一個單獨的模塊已被刪除,因為jackson 2.0是jaxb模塊。

答案雖然我修改了它,但它符合Jackson模塊Jaxb 2.4.4和Jackson API 2.3.2:

public final static JacksonJsonProvider JACKSON_JSON_PROVIDER = new JacksonJaxbJsonProvider().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
public final static ObjectMapper OBJECT_MAPPER = JACKSON_JSON_PROVIDER.locateMapper(Object.class, MediaType.APPLICATION_JSON_TYPE);
public final static Client CLIENT = ClientBuilder.newClient().register(JACKSON_JSON_PROVIDER);

這需要jar:jackson-module-jaxb-annotations-2.xxjar,所以jackson可以通過接口JacksonJaxbProvider將它加載到場景后面。

對於你的傑克遜版本,我認為jaxb代碼仍在其中。 因此,您可以使用http://wiki.fasterxml.com/JacksonJAXBAnnotations以類似的方式引用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM