[IBM DW] 使用 Jackson JSON 处理器和 Apache Wink

红薯 发布于 2010/11/04 18:01
阅读 3K+
收藏 9

简介: Apache Wink 正在快速成长为 JAX-RS 1.0 规范的标准实现之一。Apache Wink 版本附带的面向 JSON 编组和解组的提供程序,例如 JSON.org 和 Jettison,在数组表示方面有一些问题,并且返回类型比较有限。编写 JAX-RS 服务及其客户 Asynchronous JavaScript and XML (Ajax)应用程序非常困难。在本文中,学习如何配置一个现有的支持 Apache Wink 的 Web 应用程序,从而使用 Jackson JSON 提供程序来解决一些问题。将使用一个简单的支持 Jackson 的 JAX-RS Web 服务的代码示例演示这个提供程序的优点。

Apache Wink 正在快速成长为 JAX-RS 1.0 规范的标准实现之一。JSON.org 和 Jettison 是 JSON 同步的默认提供程序,但是它们自身存在某些问题。例如,它们的数组表示和有限的返回类型使编写 JAX-RS 服务及其客户 Ajax 应用程序变得很困难。

本文概述了一个配置现有的支持 Apache Wink 的 Web 应用程序来使用 Jackson JSON 提供程序的方法。通过使用一个简单的支持 Jackson 的 JAX-RS Web 服务的 样例代码 来了解这种提供程序的优点。

Apache Wink 附带的 JSON 提供程序

Apache Wink 打包了两个 JSON 提供程序作为标准版本的一部分:JSON.org 和 Jettison 实施。这两个提供程序都会使 Wink 服务和 AjaxBoth 应用程序的集成复杂化。这两个提供程序都不能直接将一个 Java 列表作为返回类型序列化到 JSON,因为 JAXB 需要一个封装的 XML 元素。这两者还有一些其他问题,例如:

JSON.org
JSON.org 提供程序的数组序列化是可预见的,但是这个行为在和 Ajax 交互时是不可取的。当它显示各种大小不同的数组时,JSON.org 会以不同的方式呈现它们:
  • 2+:“正确的” 数组序列化。例如:object : { array : ["element1", "element2"] }
  • 1:折叠数组。例如:object : { array : "element1" }
  • 0:完全删除数组。例如:object : { }

很明显,在 Javascript 中对不同结构的编码限制会导致多余的、不必要的复杂性。

Jettison
Jettison 对 JSON 生成使用 Badgerfish 惯例,这将生成一种结构,这种结构在转换为 Javascript 对象后很难进行导航。

Jackson

Jackson 本质上就是一个 JSON 处理器,用于 Java 对象的 JSON 表示的生成和解析。还可以对 Jackson 进行配置,作为 JAX-RS 实现的一个 JSON 序列化提供程序。

作为一个 JAX-RS JSON 序列化提供程序,如下所述,Jackson 有几个 JSON.org 和 Jettison 所没有的优点。


表 1. Jackson 的优点

优点 描述
在本地序列化列表的能力 Jackson 可以直接从服务中返回一个字符串对象的列表,无需一个封装的 XML 元素。
数组处理 Jackson 拥有良好的、可预见的数组序列化设施。
速度 具有比其他提供程序更快的速度。
许可 Apache License 2.0 得到了很好的理解。使用该许可的组件被用于商业和免费软件产品。

针对 Jackson 配置 Apache Wink

本文中的示例假设:

  • 您有一个现有的动态 Web 项目,该项目被配置为使用 Apache Wink 作为一个 JAX-RS 提供程序。
  • Wink servlet org.apache.wink.server.internal.servlet.RestServlet,在 web.xml 文件中进行配置,使用一个 JAX-RS 应用程序,如清单 1 所示。


清单 1. Wink servlet 的 web.xml 片段

				
<servlet>
<servlet-name>WinkServlet</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.ibm.developerworks.winkJackson.WinkApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WinkServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

 

下载和安装 Jackson 库

从 Jackson Web 网站下载 Jackson 的最新版本(链接见 参考资源)。在编写本文时,Jackson 团队还没有提供使用 Jackson 和 Apache Wink 所需的所有库的独立下载资源。您会需要 JAR 文件的 ASL 或者 LGPL 版本,如下所示。

  • core-(asl/lgpl):Jackson 核心功能
  • mapper-(asl/lgpl):POJO <-> JSON 序列化
  • jax-rs:Wink 和 Jackson 之间的接口
  • jax-xc:和 JAXB 注释的向后兼容性

JAR 文件必须显示在您的 Web 项目的类路径下。实现此目的的最简单的方法就是将它们放置在您的 WEB-INF/lib 目录。(您的 Apache Wink JAR 文件可能已经在这个目录下。)

配置 Apache Wink 来使用 Jackson 提供程序进行 JSON 序列化

现在,Jackson JSON 提供程序作为您的 Web 应用程序的一部分进行加载,但是 Apache Wink 还尚未使用它来进行 JSON 序列化。

调整 Wink servlet 的已配置过的应用程序来加载提供应用程序,如清单 2 所示。


清单 2. WinkApplication.java 示例

				
package com.ibm.developerworks.winkJackson;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

// Jackson imports
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;

public class WinkApplication extends Application {

/**
* Get the list of service classes provided by this JAX-RS application
*/
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> serviceClasses = new HashSet<Class<?>>();
serviceClasses.add(HelloWorlds.class);
return serviceClasses;
}

@Override
public Set<Object> getSingletons() {
Set<Object> s = new HashSet<Object>();

// Register the Jackson provider for JSON

// Make (de)serializer use a subset of JAXB and (afterwards) Jackson annotations
// See http://wiki.fasterxml.com/JacksonJAXBAnnotations for more information
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
mapper.getSerializationConfig().setAnnotationIntrospector(pair);

// Set up the provider
JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();
jaxbProvider.setMapper(mapper);

s.add(jaxbProvider);
return s;
}

}

Direct List<?> 序列化

Jackson 使您能够轻松地从其函数返回 Java 列表,不需要包装器 JAXB XML 元素。如清单 3 所示。


清单 3. HelloWorlds.java

				
package com.ibm.developerworks.winkJackson;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("helloworlds")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorlds {

@GET
public List<String> helloWorlds() {
return Arrays.asList(new String [] {"Hello Earth!", "Hello Mars!" });
}

}

结束语

Apache Wink 作为 JAX-RS 规范的实现得到了日益广泛的应用。JSON.org、Jettison 和 JSON 等面向 JSON 同步的默认提供程序存在某些问题。在本文中,您了解了如何配置已有的支持 Apache Wink 的 Web 应用程序来使用 Jackson JSON 提供程序。本文中的例子通过使用一个支持 Jackson 的简单 JAX-RS Web 服务的示例代码展示了该提供程序的优点。

加载中
0
我是潮汐
我是潮汐
想问一下怎么越过一个属性不解析。。除了那个在属性上直接添加注解过滤的方法外,还有其他方式吗,比如类似于struts2的jsonplugin使用正则过滤属性的方式。
返回顶部
顶部