将 Jersey/Jackson 配置为不使用 @XmlElement 字段注释进行 JSON 字段命名

Posted

技术标签:

【中文标题】将 Jersey/Jackson 配置为不使用 @XmlElement 字段注释进行 JSON 字段命名【英文标题】:Configure Jersey/Jackson to NOT use @XmlElement field annotation for JSON field naming 【发布时间】:2011-06-27 16:48:35 【问题描述】:

我正在运行 Jersey REST 服务。代表我的资源的 POJO 是带有 JAXB (XML) 注释的简单 Java 类(它们是从模式定义生成的 - 因此它们具有注释)。

我希望 Jersey/Jackson 忽略 XML 注释。我在我的 web.xml 中做了这个配置(如提到的here):

  <init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
  </init-param>

我现在预计 @XMLElement 注释将不再用于 JSON 字段命名策略。

但是看这个java字段(成员)

@XmlElement(name = "person", required = true)
protected List<Person> persons;

我仍然得到以下 JSON 表示:

....,"person":["name":"FooBar", ....... (person without the 's')

所有其他字段也仍然从 @XmlElement 注释而不是从 Java 字段名称中获取其 JSON 名称。

我想实现 Jackson Full Data Binding (POJO) Example 中描述的 JSON 输出。

它在像这样的简单测试中运行良好(使用我的 XML 注释类):

  ObjectMapper mapper = new ObjectMapper(); 
  mapper.writeValue(System.out, myObject);

但嵌入泽西岛我没有得到预期的 JSON 输出。

他们在 Jersey 中获得“简单”POJO JSON 表示的其他配置选项是什么(因为这最适合必须反序列化 JSON 结果的客户端)。

谢谢克劳斯

详细解决方案

(1) 为 Jacksons ObjectMapper 实现一个 ContextResolver,它会创建一个不使用注释的 ObjectMapper。

package foo.bar.jackson;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;

/**
 * Customized @code ContextResolver implementation that does not use any
 * annotations to produce/resolve JSON field names.
 */
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonContextResolver implements ContextResolver<ObjectMapper> 

    private ObjectMapper objectMapper;

    /**
     * Creates a new instance.
     * 
     * @throws Exception
     */
    public JacksonContextResolver() throws Exception 
        this.objectMapper = new ObjectMapper().configure(
                DeserializationConfig.Feature.USE_ANNOTATIONS, false)
                .configure(SerializationConfig.Feature.USE_ANNOTATIONS, false);
        ;
    

    /**
     * @see javax.ws.rs.ext.ContextResolver#getContext(java.lang.Class)
     */
    public ObjectMapper getContext(Class<?> objectType) 
        return objectMapper;
    

(2) 在 application.xml 中注册 ContextResolver Spring bean

<bean class="foo.bar.jackson.JacksonContextResolver"/>

【问题讨论】:

【参考方案1】:

在低级别,需要确保 ObjectMapper 不使用 JAXBAnnotationIntrospector,而只使用默认的 JacksonAnnotationIntrospector。我认为您应该能够只构造 ObjectMapper (默认情况下不添加 JAXB 内省),并通过标准 JAX-RS 提供程序机制注册它。这应该覆盖 POJO 映射器功能将构建的 ObjectMapper。

【讨论】:

谢谢,这就是解决方案——尽管如果没有我发现的许多其他类似的 SO 问题/答案,我将无法理解该怎么做 :-) 我将在问题中发布详细的解决方案。 谢谢。我知道有一些关于泽西岛的常见问题解答条目,但它们很难找到(以至于我经常找不到它……需要开始添加书签)。 下载 maven.java.net/service/local/artifact/maven/… 以获取使用基于 POJO 的 JSON 支持的完整示例。它还针对JAXBAnnotationIntrospectorJacksonAnnotationIntrospector...

以上是关于将 Jersey/Jackson 配置为不使用 @XmlElement 字段注释进行 JSON 字段命名的主要内容,如果未能解决你的问题,请参考以下文章

Jersey Jackson和codehaus vs. fasterxml

使用Dropwizard时配置Jackson映射器

Jersey/Jackson:如何捕获 json 映射异常?

Hibernate + Jersey + Jackson 随机获得“org.hibernate.TransactionException:不支持嵌套事务”

在 Jackson/Jersey JAVA 上发布带有多个参数 JSON 和 String 的请求

检索结果JAX-RS + Jersey + Jackson