首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Jackson和JAXB之间使用下划线和camelCase字段的Umarshall对象

在Jackson和JAXB之间使用下划线和camelCase字段的Umarshall对象
EN

Stack Overflow用户
提问于 2014-02-25 01:51:14
回答 2查看 15K关注 0票数 20

使用JAXB (2.2)和Jackson (1.9.13),我在将以下JSON对象解组到POJO时遇到了问题

代码语言:javascript
复制
{
   "userId": "foo",
   "group_id": "bar"
}

请注意,有效负载包含一个camelCase和一个下划线字段。

xjc为我的XML模式生成的POJO如下所示:

代码语言:javascript
复制
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; }
}

Jackson失败了,但有以下例外:

代码语言:javascript
复制
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "group_id"

我到目前为止所做的尝试都失败了

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

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

代码语言:javascript
复制
<jxb:globalBindings underscoreBinding="asCharInWord"/>

生成以下POJO:

代码语言:javascript
复制
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现在生成了带有下划线的组is的setter/getter,但是group_id字段仍然被转换为CamelCase。Jackson的对象映射器似乎忽略了属性的setter/setter名称,并且仍然不能将group_id映射到groupId

2. Jackson属性命名策略

使用Jackson的PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES,我可以将group_id转换为groupId,但是现在对象映射器在userId JSON属性上失败了。

3.向groupId添加JSONProperty注释

向普通的JAXB生成的POJO添加JSONProperty实际上是可行的

代码语言:javascript
复制
public class User {
        /* ... */
        @XmlElement(name = "group_id", required = true)
        @JSONProperty("group_id")
        protected String groupId;
        /* ... */
   }

然而,我的XML模式很庞大,手动插装生成的类是不可行的,因为我们经常生成我们的类。

我该怎么办?

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

XJC

  • 实现了一个JAXB插件,该插件为每个XJC添加一个带有下划线名称的JSONProperty注释(我更喜欢的next XMLElement是一个用于XJC的自定义名称生成器,如this Stackoverflow answer中所述。

我是不是错过了显而易见的事情?谢谢你的想法。

EN

回答 2

Stack Overflow用户

发布于 2015-07-08 19:50:46

您是否尝试过用@JsonProperty("group_id")注释user类中的groupId属性。这应该是可行的(经过测试和验证)!

如果属性上没有这样的注释,Jackson映射器将按原样考虑属性名,否则提供的值将用于JSON反序列化。下面是你的User类应该是什么样子:

代码语言:javascript
复制
public class User {

private String userId;

@JsonProperty("group_id")
private String groupId;

这应该映射到您的JSON

代码语言:javascript
复制
{"userId": "foo","group_id": "bar"}

如果您正在使用基于Jackson的CXF (或任何其他Rest框架),我建议您阅读下面这篇简短的博客文章,其中详细介绍了如何在CXF中配置JacksonJsonProvider以实现JSON Snake Case (下划线)格式数据的序列化和反序列化

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

票数 8
EN

Stack Overflow用户

发布于 2014-06-13 19:04:54

我在stackoverflow上从一个类似的案例中找到了您的问题的可能解决方案。How to extract ObjectMapper from JAX-RS Client?

访问Object Mapper后,您可以设置自己的批注提供程序。因为jackson 2.0是jaxb模块,所以现在已经作为一个单独的模块删除了。

答案在这里,尽管我对它进行了修改,使其符合Jackson模块Jaxb 2.4.4和Jackson API 2.3.2:

代码语言:javascript
复制
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.x.x.jar,这样jackson就可以通过接口JacksonJaxbProvider在后台加载它。

对于您的Jackson版本,我认为jaxb代码仍然在其中。因此您可以使用http://wiki.fasterxml.com/JacksonJAXBAnnotations以类似方式引用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21995175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档