2012-10-14 18 views
2

我有一個ServerResource,它通過發回二進制數據來響應GET請求。問題在於二進制數據的來源將通過單獨的REST調用異步下載(可能通過HttpAsyncClient)。是否有可能創建一個表示形式,可以將數據提供給從異步下載到達的數據?我需要能夠做到這一點而不會阻塞任何線程,因此需要某種NIO解決方案。管道數據從NIO HTTP下載到Restlet ServerResource響應

我懷疑我可以WriteableRepresetation做到這一點,但我不完全知道如何與文檔說

爲此,您只需要創建一個子類並覆蓋抽象Representation.write(與WritableByteChannel)方法。當需要實際表示的內容時,稍後將由連接器回調該方法。

暗示當調用該方法時,所有內容必須已經可用。

我正在使用v2.1。

回答

1

在玩了一會之後,看起來好像可以使用ReadableRepresentation。我不知道是否有更好的方式來創建ReadableByteChannel而不是使用Pipe,但這是我看到的唯一途徑,而不必實現我自己的Channel。

private static final byte[] HELLO_WORLD = "hello world\n".getBytes(Charsets.UTF_8); 

public static class HelloWorldResource extends ServerResource { 
    @Get 
    public Representation represent() throws Exception { 
     final Pipe pipe = Pipe.open(); 

     // this simulates another process generating the data 
     Thread t = new Thread(new Runnable() { 
      private final ByteBuffer buf = ByteBuffer.allocate(1); 
      private final Pipe.SinkChannel sink = pipe.sink(); 

      private int offset = 0; 

      @Override 
      public void run() { 
       while (offset < HELLO_WORLD.length) { 
        try { 
         buf.clear(); 
         buf.put(HELLO_WORLD[offset++]); 
         buf.flip(); 

         while (buf.hasRemaining()) { 
          sink.write(buf); 
         } 

         Thread.sleep(500); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 

       try { 
        sink.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     t.setDaemon(true); 
     t.start(); 

     return new ReadableRepresentation(pipe.source(), MediaType.TEXT_PLAIN); 
    } 
} 

public static class HelloWorldApplication extends Application { 
    @Override 
    public synchronized Restlet createInboundRoot() { 
     Router router = new Router(getContext()); 
     router.attach("/hello", HelloWorldResource.class); 

     return router; 
    } 
} 

public static void main(String[] args) throws Exception { 
    Component component = new Component(); 
    component.getDefaultHost().attach("", new HelloWorldApplication()); 

    Server server = component.getServers().add(Protocol.HTTP, 8090); 

    component.start(); 
} 
+0

爲此乾杯,它非常有用。 – tom

0

玩弄上述方案後,我發現,你可以這樣創建的ReadableByteChannel:

 ByteArrayInputStream stream = new ByteArrayInputStream(myByteArray); 
     ReadableByteChannel channel = Channels.newChannel(stream); 

大回答上面雖然救了我很多麻煩。

相關問題