Fel*_*vic 2 java jersey jersey-2.0
在 Jersey 中使用拦截器我可以操作输出,但是,我还想向响应添加一个 Header,该值是根据输出结果计算的。
@Sha256Sum
public class Sha256SumInterceptor implements WriterInterceptor {
public static final String SHA256_HASH_HEADER_NAME = "SHA256-SUM";
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
// Retrieve the OutputStream, read the contents and calculate the hashsum.
// Set the header value in context.
context.proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,问题是当我最终阅读了整个流时,我无法将标题设置为调用 context.proceed 和写入的内容(从而使我能够对其进行任何操作)我无法再设置标题。
简而言之,我的问题是:如何将整个流输出捕获为字节 [],从字节数组计算结果,并最终在对计算结果的响应中设置标头?我不想耗尽输出流。
如果您曾经使用过 AOP 框架甚至 CDI 拦截器,那么您将分别使用过Around-Advice 或Around-Invoke 的概念。您可以在调用通知/拦截方法之前和之后执行操作。context.proceed()工作方式相同;它是方法调用(或者更准确地说是MessageBodyWriter正在编写)。我们可以在MessageBodyWriter做它的工作之前执行一些操作,调用proceed()让作家做它的工作,然后我们可以做更多的工作。
话虽如此,您可以采取以下步骤:
OutputStream自context, 与context.getOutputStream()ByteArrayOutputStream并将其设置为OutputStream上下文,使用context.setOutputStream(baos)context.proceed()。它的作用是MessageBodyWriter写入ByteArrayOutputStream.byte[]从ByteArrayOutputStreamwith 中获取baos.toByteArray()byte[]和并设置标题byte[]旧的OutputStream。OutputStream就context老了OutputStream。这是基本实现(经过测试并按预期工作)
@Provider
public class ChecksumInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
OutputStream old = context.getOutputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
context.setOutputStream(buffer);
// let MessageBodyWriter do it's job
context.proceed();
// get bytes
byte[] entity = buffer.toByteArray();
String checksum = ChecksumUtil.createChecksum(entity);
context.getHeaders().putSingle("X-Checksum", checksum);
old.write(entity);
} finally {
context.setOutputStream(old);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
709 次 |
| 最近记录: |