将 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 支持的完整示例。它还针对JAXBAnnotationIntrospector
和JacksonAnnotationIntrospector
...以上是关于将 Jersey/Jackson 配置为不使用 @XmlElement 字段注释进行 JSON 字段命名的主要内容,如果未能解决你的问题,请参考以下文章
Jersey Jackson和codehaus vs. fasterxml
Jersey/Jackson:如何捕获 json 映射异常?
Hibernate + Jersey + Jackson 随机获得“org.hibernate.TransactionException:不支持嵌套事务”