正如在如何使用Jersey拦截器获取请求主体中所讨论的,我正在修改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....
}
我被困在旧版本的球衣1.8上,所以我不确定这是否是问题的一部分。
您所需要做的就是接受inputstream
作为资源方法中的实体主体。如果需要ByteArrayInputStream
,只需强制转换即可。
@POST
public Response post(InputStream in) {
ByteArrayInputStream bin = (ByteArrayInputStream)in;
}
如果您还不知道,Jersey如何将请求流(用于请求正文)转换为Java类型(例如,JSON转换为POJO)是通过MessageBodyReader
的。您可以在JAX-RS实体提供程序中了解更多关于它们的信息。
Jersey已经提供了一些易于转换的类型的标准阅读器,例如String。大多数内容类型可以转换为字符串。同样,它也有一个读取器来处理InputStream
。这可能是最简单的转换,因为请求已经作为inputstream
传入,所以阅读器所需要做的就是返回原始流,这就是传递给我们方法的内容。
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>
问题内容: 我正在尝试制作一个包含名称的列表。该列表应该是可修改的(添加,删除,排序等)。但是,每当我尝试更改ArrayAdapter中的项目时,程序都会崩溃,并显示错误。这是我的代码: 我尝试插入,删除和清除方法,但没有一个起作用。有人可以告诉我我做错了什么吗? 问题答案: 我自己尝试了一下…发现它没有用。所以我检查了ArrayAdapter的源代码并发现了问题。由数组初始化后,将其转换为不能修
Swift 5.x Set 访问和修改 1.遍历 Set 可以使用for-in遍历Set 因为Set是无序的, 如果要顺序遍历Set, 使用sorted()方法 let courses: Set = ["Math", "English", "History"] for course in courses { print(course) } print("--- 分割线 ---") for
求你了,我需要你的帮助。每当我试图运行下面的程序时,它会说不兼容的类型,字符串不能转换为整数。
问题内容: 我正在尝试将我的项目目录添加到GOPATH,在Linux中,我可以这样做 在〜/ .bashrc中 Powershell中的等效性是什么 问题答案: 这应该遵循您使用Powershell设置任何Environment变量的方式(如本文所述): 如果您希望它永久存在(即将来将适用于任何外壳程序): 需要注意的一件事:当我们用来创建新的用户或计算机级环境变量时,在Windows Power
问题内容: 我需要在Java中更改JSON属性的值,我可以正确获取该值,但无法修改JSON。 这是下面的代码 做这个的最好方式是什么? 问题答案: 是不可变的,旨在进行解析操作。但是,可以将其转换为允许突变的(和): 对于数组,可以使用:
问题内容: 有没有理由可以更改覆盖方法的访问修饰符?例如, 然后将package-private访问修饰符更改为, 我只是出于好奇而问这个问题。 问题答案: Java不允许您对access修饰符进行 更严格的限制 ,因为这会违反以下规则:子类实例应该可以代替超类实例使用。但是当涉及到 减少 访问限制时……好吧,也许超类是由另一个人编写的,他们没有想到您要使用其类的方式。 人们编写的程序以及编程时所