中所讨论的,我正在修改ContainerRequestFilter中的EntityInputStream.
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 }
但是,后来我无法弄清楚如何访问修改后的InputStream.我可以在资源中获取ServletContext,但我无法弄清楚如何获取我在过滤器中实际修改的对象ContainerRequest.
我可以这样做吗?当我尝试这个时,泽西岛无法启动:
@Post @Path("/test") public Response test(@Context ContainerRequest cr){ // blah blah return.... }
泽西岛错误:
方法public javax.ws.rs.core.Response example.TestController.test(com.sun.jersey.spi.container.ContainerRequest)缺少依赖性,用资源的POST注释,类example.TestController,不被识别为有效资源方法.
我被困在一个旧版本的球衣,1.8,所以我不确定这是否是问题的一部分.
您需要做的就是接受一个InputStream作为资源方法中的实体主体.如果你想要ByteArrayInputStream只是强制转换它.
@POST public Response post(InputStream in) { ByteArrayInputStream bin = (ByteArrayInputStream)in; }
如果你还不知道,Jersey如何将请求流(对于请求体)转换为Java类型(例如JSON到POJO)的时间是
MessageBodyReader
s.您可以在 JAX-RS Entity Providers
阅读更多相关信息.
Jersey已经附带了一些易于转换类型的标准阅读器,例如String.大多数内容类型都可以转换为String.同样,它有一个处理InputStream的阅读器.这可能是最简单的转换,因为请求已经作为InputStream进入,所以读者真正需要做的就是返回原始流,这就是传递给我们方法的内容.
如果我们查看实现
InputStreamProvider
,我们可以看到实际发生的情况. 0700 3.由于过滤器发生在读者之前,读者只需返回我们设置的流.
这是一个使用 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); } }
这是测试依赖
<dependency> <groupId>com.sun.jersey.jersey-test-framework</groupId> <artifactId>jersey-test-framework-grizzly2</artifactId> <version>1.17.1</version> <scope>test</scope> </dependency>
翻译自:https://stackoverflow.com/questions/32632342/jersey-inputstream-is-modified-in-filter-unable-to-figure-out-how-to-access-mod