分享

CometD 2 JSON 库插件能力

 phoneone 2011-11-18

原文地址:

                http:///documentation/2.x/cometd-java/json

 

 

CometD 2 JSON 库插件能力

 

sbordet 提交于星期二,2011/8/16-9:11

 

CometD 2 JSON 库插件能力

 

自版本 2.4.0开始,CometD 允许自定义JSON 库,用于把传入 JSON 转换成Bayeux 消息以及用 Bayeux 消息生成 JSON

 

这里有两种实现方法,一种是利用jettyorg.eclipse.jetty.util.ajax.JSON类,一种是Jackson库。默认的方法是利用jetty库。

 

这两个库几乎一样快,但也有区别,在特殊CometD情况下,jetty的库解析要比jackson快,但生成要比它慢。

 

Jackson库有丰富的API去自定义json且它是用注解的方式解析,所以如果你想用自定义的类作为bayeux消息的数据(代替java.util.Map对象),它将会很有优势。请阅读jackson的文档获取详细信息。

 

Jetty库也允许插入自定义的序列化和反序列化,也行太简单但不失为重新的方法(你想自定义类必须实现jetty库的接口)。请阅读org.eclipse.jetty.util.ajax.JSON的文档获取详细信息。

 

CometD json上下文 API

 

Json库在CometD java客户端实现中被用来生成json和把json解析成org.cometd.bayeux.Message实例。

 

执行生成/解析的json类的客户端必须实现org.cometd.common.JSONContext.Client

 

类似的,在服务端,一个org.cometd.common.JSONContext.Server的实现产生json或把json解析成org.cometd.bayeux.server.ServerMessage实例。

 

客户端配置

 

在客户端,org.cometd.common.JSONContext.Client实例必须直接传到配置的传输中,如果省略,默认使用jetty库。

 

例如:

 

 

 

 

 

HttpClient httpClient = ...;

 

Map clientOptions = new HashMap();

 

// Use the Jackson implementation

JSONContext.Client jsonContext = new JacksonJSONContextClient();

clientOptions.put(ClientTransport.JSON_CONTEXT, jsonContext);

 

ClientTransport transport = new LongPollingTransport(clientOptions, httpClient);

 

BayeuxClient client = new BayeuxClient(cometdURL, transport);

 

 

org.cometd.common.JSONContext.Client必须被所有的客户端传输共享(因为唯一的传输必须在任何时候都要被使用)。

 

你可以自定义json实现并添加你自己序列化和反序列化方法,例如:

 

public class MyJacksonJSONContextClient extends org.cometd.common.JacksonJSONContextClient
{
    public MyJacksonJSONContextClient()
    {
        org.codehaus.jackson.map.ObjectMapper objectMapper = getObjectMapper();
        objectMapper.registerModule(new MyModule());
    }
 
    private class MyModule extends org.codehaus.jackson.map.module.SimpleModule
    {
        public MyModule()
        {
            // Add your custom serializers/deserializers here
            addSerializer(Foo.class, new FooSerializer());
        }
    }
}

 

 

 

 

服务端配置

 

 

在服务端,实现org.cometd.common.JSONContext.Server的类可能在CometdServlet的初始化参数中指定了,如果省略,默认使用jetty库。

 

 

例如:

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java./xml/ns/javaee"
         xmlns:xsi="http://www./2001/XMLSchema-instance"
         xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
 
    <servlet>
        <servlet-name>cometd</servlet-name>
        <servlet-class>org.cometd.server.CometdServlet</servlet-class>
        ... other parameters
        <init-param>
            <param-name>jsonContext</param-name>
            <param-value>org.cometd.server.JacksonJSONContextServer</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>cometd</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>
 
</web-app>

 

这个类必须被默认的初始化参数构造器实例化并实现org.cometd.common.JSONContext.Server

以及它可以用添加序列化和反序列化的扩展来自定义。

 

 

 

 

可移植性注意事项

 

它能够从一个json的实现库转换成另一个json库,例如从jetty库换成jackson库,提供如此功能,应用程序的代码编写要特别小心。

 

1.8.4版本开始,jackson当序列化json数组时只能提供java.util.List的实例。

但是jetty库在序列化json数组能提供Object[]

类似的,jackson能提供lava.lang.Integer,而jetty库能提供java.lang.Long

 

为了编写可移植的应用程序代码,我们使用下面的代码模式:

 

Message message = ...;
Map<String, Object> data = message.getDataAsMap();
 
// Expecting a JSON array
 
// WRONG
Object[] array = (Object[])data.get("array");
 
// CORRECT
Object field = data.get("array");
Object[] array = field instanceof List ? ((List)field).toArray() : (Object[])field;
 
 
// Expecting a long
 
// WRONG
long value = (Long)data.get("value");
 
// CORRECT
long value = ((Number)data.get("value")).longValue();

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多