gpt4 book ai didi

java - Jersey InputStream 在过滤器中被修改。无法弄清楚如何访问 Jersey Resource 中修改后的 inputStream

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:56:46 33 4
gpt4 key购买 nike

How to use Jersey interceptors to get request body 中所述,我正在修改 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。

我可以做这样的事情吗?当我尝试这个时,Jersey 无法启动:

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

Jersey 错误:

方法 public javax.ws.rs.core.Response example.TestController.test(com.sun.jersey.spi.container.ContainerRequest) 缺少依赖项,注释为资源的 POST,类 example.TestController,无法识别作为有效的资源方法。

我卡在旧版本的 Jersey 1.8 上,所以我不确定这是否是问题的一部分。

最佳答案

您需要做的就是接受 InputStream 作为资源方法中的实体主体。如果你想要 ByteArrayInputStream 就投它。

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

如果您还不知道,Jersey 如何将请求流(对于请求主体)转换为 Java 类型(例如 JSON 到 POJO)是通过 MessageBodyReader 实现的。秒。您可以在 JAX-RS Entity Providers 阅读更多关于它们的信息.

Jersey 已经为易于转换的类型(例如 String)提供了一些标准阅读器。大多数内容类型都可以转换为字符串。同样,它有一个读取器来处理 InputStream。这可能是最简单的转换,因为请求已经作为 InputStream 传入,所以实际上所有读者需要做的就是返回原始流,这就是传递给我们的方法的内容。

如果我们看一下实现 InputStreamProvider ,我们可以看到这就是实际发生的事情。 The original stream is simply returned .由于过滤器发生在读取器之前,读取器只需返回我们设置的流。

这是一个使用 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>

关于java - Jersey InputStream 在过滤器中被修改。无法弄清楚如何访问 Jersey Resource 中修改后的 inputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32632342/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com