在dropwizard中使用cometd

时间:2013-11-22 21:04:11

标签: java cometd dropwizard

我正在尝试使用cometd作为dropwizard的servlet,但是BayeuxServer似乎没有注入我的服务。我正在添加我的两个servlet(注意,我没有使用web.xml因此我自己定义了params):

cometdConfig.put("services", MyService.class.getCanonicalName());

System.out.print("OrderService name: " + MyService.class.getCanonicalName());

environment.addServlet(AnnotationCometdServlet.class, "/cometd/*").addInitParams(cometdConfig).setInitOrder(1);
environment.addServlet(new MyServiceServlet(), "/orders/*").setInitOrder(2);

我的服务(这是我的代码失败的地方):

public class MyService
implements MyWatcher.Listener
{
   @Inject
   private BayeuxServer bayeuxServer;
   @Session
   private LocalSession sender;

   private final String _channelName;

   private ServerChannel _channel = null;

   public OrderService() {
      _channelName = "/cometd/";
      initChannel();
   }

   private void initChannel() {
      // I get an NPE here
      bayeuxServer.createIfAbsent(_channelName, new ConfigurableServerChannel.Initializer() {
        @Override
        public void configureChannel(ConfigurableServerChannel channel) {
           // ...
        }
      });
    _channel = bayeuxServer.getChannel(_channelName);
   }
}

我还尝试创建自己的BayeuxServer实例,但随后在BayeuxServerImpl.freeze();中导致单独的NPE

任何人都知道如何使用dropwizard正确使用cometd?

1 个答案:

答案 0 :(得分:3)

为了注入BayeuxServer实例,CometD必须具有要注入的服务实例,在本例中是类MyService的实例。

不幸的是,从构造函数(我认为你在上面命名为OrderService),你调用的是initChannel()方法,它尝试使用尚未提供的BayeuxServer字段因为构造函数仍在执行而注入。

解决方案是将您的频道初始化推迟到使用@PostConstruct注释的其他方法:

public class MyService
{
    @Inject
    private BayeuxServer bayeuxServer;
    @Session
    private LocalSession sender;
    private final String _channelName;
    private ServerChannel _channel;

    public MyService() 
    {
        _channelName = "/cometd/";
    }

    @PostConstruct
    private void initChannel() 
    {
        _channel = bayeuxServer.createChannelIfAbsent(_channelName).getReference();
    }
}

使用的CometD API来自CometD 2.7.0,如果您使用较旧的CometD版本,我建议使用它。