2015-09-17 15 views
8

How to use Jersey interceptors to get request bodyで説明したように、私はContainerRequestFilterのEntityInputStreamを変更しています。Jersey InputStreamはフィルターで変更されます。 Jersey Resourceで変更されたinputStreamにアクセスする方法を見つけることができません

ただし、後で私は変更されたInputStreamにアクセスする方法を理解できません。私はリソース内でServletContextを取得できますが、フィルタで実際に変更したオブジェクトのContainerRequestを取得する方法を理解できません。

私はこれを行うことはできますか?メソッドpublic javax.ws.rs.core.Response example.TestController.test(はcom.sunため

欠落dependecy:

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

ジャージーエラー:私はこれをしようとすると、ジャージーが出て起動できません。 jersey.spi.container.ContainerRequest)は、リソースのPOST(クラスexample.TestController)で注釈が付けられ、有効なリソースメソッドとして認識されません。

私は古いバージョンのジャージー1.8についているので、それが問題の一部かどうかはわかりません。

答えて

1

リソースメソッドのエンティティボディとしてInputStreamを受け入れるだけです。 ByteArrayInputStreamだけをキャストしたい場合。

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

すでにジャージーが(POJOのインスタンスJSONのための)Java型に(リクエストボディ用)要求ストリームを変換する方法を、わからない場合はMessageBodyReader Sを介して行われます。 JAX-RS Entity Providersで詳細を読むことができます。

Jerseyには、すでにStringなどの簡単に変換できるタイプの標準リーダーが付属しています。ほとんどのコンテンツタイプはStringに変換できます。同様に、それはInputStreamを扱う読者を持っています。リクエストがすでにInputStreamとして入力されているため、これはおそらく最も簡単な変換ですので、実際にはすべての読者が元のストリームを返す必要があり、それが私たちのメソッドに渡されます。

実装InputStreamProviderを見ると、それが実際に起こっていることがわかります。 The original stream is simply returned。また、フィルタは読者の前で行われるため、読者は単に設定したストリームを返します。ここで

はここでテスト依存性が

<dependency> 
    <groupId>com.sun.jersey.jersey-test-framework</groupId> 
    <artifactId>jersey-test-framework-grizzly2</artifactId> 
    <version>1.17.1</version> 
    <scope>test</scope> 
</dependency> 
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); 
    } 
} 

を使用した完全な例です。

関連する問題