gpt4 book ai didi

java - Jersey - 在调用 context.proceed() 之前获取拦截器中 OutputStream 的内容

转载 作者:行者123 更新时间:2023-11-30 06:57:20 25 4
gpt4 key购买 nike

在 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();
}
}

但是,问题是当我最终阅读了整个流时,我无法设置 header ,因为当调用 context.proceed 并写入内容时(从而使我能够用它做任何事情)我可以不再设置表头。

我的问题简而言之:如何将整个流输出捕获为 byte[]、从字节数组计算结果并最终在对计算结果的响应中设置 header ?我不想耗尽输出流。

最佳答案

如果您曾经使用过 AOP 框架甚至 CDI 拦截器,那么您将分别使用过 Around-Advice 或 Around-Invoke 的概念。您可以在调用建议/拦截方法之后执行 之前的操作。 context.proceed() 的工作方式相同;它是方法调用(或者更准确地说是 MessageBodyWriter 正在编写)。我们可以在 MessageBodyWriter 完成它的工作之前执行一些操作,调用 proceed() 让编写器完成它的工作,然后我们可以做更多的工作。

话虽如此,以下是您可以采取的步骤:

  1. 使用 context.getOutputStream()
  2. context 保留旧的 OutputStream
  3. 创建一个 ByteArrayOutputStream 并将其设置为上下文中的 OutputStream,使用 context.setOutputStream(baos)
  4. 调用 context.proceed()。它所做的是让 MessageBodyWriter 写入 ByteArrayOutputStream
  5. 使用baos.toByteArray()ByteArrayOutputStream获取byte[]
  6. 校验byte[]并设置header
  7. byte[]写入旧的OutputStream
  8. 最后将 context 上的 OutputStream 设置为旧的 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);
}
}
}

关于java - Jersey - 在调用 context.proceed() 之前获取拦截器中 OutputStream 的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33518790/

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