2015-09-17 10 views
8

'de değiştirilmiş inputStream'e nasıl erişileceğine karar verilemiyor How to use Jersey interceptors to get request body'da açıklandığı gibi, bir ContainerRequestFilter içinde EntityInputStream öğesini değiştiriyorum.Jersey Giriş akışı, filtrede değiştirildi. Jersey Kaynak

public filter(ContainerRequest request){ 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    InputStream in = request.getEntityInputStream(); 
    try{ 
      Readerwriter.writeTo(in, out); 
      byte[] requestEntity = out.toByteArray(); 

      // DO SOMETHING WITH BYTES HERE 

      request.setEntityInputStream(new ByteArrayInputStream(requestEntity)); 

     }/// error handling code here 
} 

Ancak, daha sonra değiştirilmiş InputStream'e nasıl erişileceğimi anlayamıyorum. ServletContext'i kaynakta bulabilirim, ancak filtrede, ContainerRequest'de gerçekten değiştirdiğim nesnenin nasıl elde edileceğini anlayamıyorum.

Böyle bir şey yapabilir miyim? yöntem kamu javax.ws.rs.core.Response example.TestController.test (com.sun için

Eksik bağımlılığımızı:

@Post 
@Path("/test") 
public Response test(@Context ContainerRequest cr){ 
    // blah blah 
    return.... 
} 

Jersey hatası: Bu çalıştıklarında Jersey dışarı kadar başlatılamaz. jersey.spi.container.ContainerRequest), kaynak POST ile açıklamalı, sınıf example.TestController, geçerli bir kaynak yöntemi olarak tanınmıyor.

Jersey'in eski bir sürümünde 1.8 kaldı, bu yüzden sorunun bir parçası olup olmadığından emin değilim.

cevap

1

Yapmanız gereken tek şey, kaynak yönteminizdeki varlık birimi olarak bir InputStream kabul etmektir. ByteArrayInputStream'un sadece yayınlanmasını istiyorsanız. Jersey (POJO için örnek JSON için) Java tipe (istek gövdesi için) İstek akışı dönüştürür nasıl

@POST 
public Response post(InputStream in) { 
    ByteArrayInputStream bin = (ByteArrayInputStream)in; 
} 

Zaten bilmiyorsanız

, MessageBodyReader s geçer. Daha fazla bilgiyi JAX-RS Entity Providers adresinden okuyabilirsiniz.

Jersey zaten kolayca dönüştürülebilir tipler için bazı standart okuyucularla birlikte gelir, örneğin String. Çoğu içerik türü, String'e dönüştürülebilir. Aynı şekilde, InputStream'u işlemek için bir okuyucuya sahiptir. Muhtemelen en kolay dönüşüm, istek zaten bir InputStream olarak geldiğinden, gerçekten tüm okuyucuların yapması gereken şey orijinal akışı döndürmektir ve bu bizim metodumuza geçecektir.

InputStreamProvider numaralı uygulamaya bakarsak, gerçekte bunun gerçekleştiğini görebiliriz. The original stream is simply returned. Filtre okuyuculardan önce gerçekleştiğinden, okuyucu sadece ayarladığımız akışı döndürür. İşte

testi bağımlılık

<dependency> 
    <groupId>com.sun.jersey.jersey-test-framework</groupId> 
    <artifactId>jersey-test-framework-grizzly2</artifactId> 
    <version>1.17.1</version> 
    <scope>test</scope> 
</dependency> 
İşte Jersey Test Framework

public class StreamFilterTest extends JerseyTest { 

    public static class InputStreamFilter implements ContainerRequestFilter { 

     @Override 
     public ContainerRequest filter(ContainerRequest request) { 
      try { 
       ByteArrayOutputStream out = new ByteArrayOutputStream(); 
       InputStream in = request.getEntityInputStream(); 
       ReaderWriter.writeTo(in, out); 

       byte[] requestBytes = out.toByteArray(); 
       byte[] worldBytes = " World".getBytes(StandardCharsets.UTF_8); 
       byte[] newBytes = new byte[requestBytes.length + worldBytes.length]; 
       System.arraycopy(requestBytes, 0, newBytes, 0, requestBytes.length); 
       System.arraycopy(worldBytes, 0, newBytes, requestBytes.length, worldBytes.length); 

       request.setEntityInputStream(new ByteArrayInputStream(newBytes)); 
      } catch (IOException ex) { 
       Logger.getLogger(InputStreamFilter.class.getName()).log(Level.SEVERE, null, ex); 
       throw new RuntimeException(ex); 
      } 

      return request; 
     } 
    } 

    @Path("stream") 
    public static class StreamResource { 

     @POST 
     public String post(InputStream in) throws Exception { 
      ByteArrayInputStream bin = (ByteArrayInputStream) in; 
      StringWriter writer = new StringWriter(); 
      ReaderWriter.writeTo(new InputStreamReader(bin), writer); 
      return writer.toString(); 
     } 
    } 

    public static class AppConfig extends DefaultResourceConfig { 
     public AppConfig() { 
      super(StreamResource.class); 
      getContainerRequestFilters().add(new InputStreamFilter()); 
     } 
    } 

    @Override 
    public WebAppDescriptor configure() { 
     return new WebAppDescriptor.Builder() 
       .initParam(WebComponent.RESOURCE_CONFIG_CLASS, 
         AppConfig.class.getName()) 
       .build(); 
    } 

    @Test 
    public void should_return_hello_world() { 
     String response = resource().path("stream").post(String.class, "Hello"); 
     assertEquals("Hello World", response); 
    } 
} 

kullanarak tam bir örnek var olan