Umarshall JSON对象,带有Jackson和JAXB之间的下划线和camelCase字段问题如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (125)

使用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 / getters,但该group_id字段仍被转换为CamelCase。杰克逊的对象映射器似乎忽略了属性getters / setter名称,仍然无法映射group_idgroupId

2.jackson物业命名策略

使用Jackson的PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES我可以转换group_idgroupId,但现在对象映射器在userIdJSON属性上失败。

3. JSONProperty为groupId 添加注释

JSONProperty香草JAXB 添加一个生成的POJO实际上是可行的

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

然而,我的XML模式是巨大的,并且生成的类的手动检测是不可行的,因为我们经常生成我们的类。

我该怎么办?

我看到以下两个剩余的选项来处理这个问题:

  1. 实现一个JAXB插件,JSONProperty为每个插件添加一个注释,并在其中添加XMLElement下划线名称(我首选的下一个方法)
  2. 为XJC使用自定义名称生成器。
提问于
用户回答回答于

我发现一个可能的解决方案来解决你的问题,从类似的情况,在计算器上。

一旦你有权访问Object Mapper,你可以设置自己的注释提供者。现在已经作为一个单独的模块被删除了,因为jackson 2.0是jaxb模块。

这里的答案,虽然我修改它,所以它符合jackson模块Jaxb 2.4.4和jacksonAPI 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将其加载到场景后面。

对于jackson版本,我认为jaxb代码仍在其中。所以你可以参考http://wiki.fasterxml.com/JacksonJAXBAnnotations的类似方法

用户回答回答于

你有没有尝试groupId用你的用户类注解属性@JsonProperty("group_id")。这应该工作(测试和证明)!

如果一个属性上没有这样的注释,那么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/

扫码关注云+社区