Jersey - Obtain the contents of an OutputStream in an Interceptor before calling context.proceed()

空扰寡人 提交于 2019-12-06 08:53:28

If you've ever worked with an AOP framework or even CDI interceptors, you'll have worked with the concept of Around-Advice or Around-Invoke, respectively. You can perform operations before and after the invocation of the advised/intercepted method. context.proceed() works the same way; it's the method invocation (or more precisely the MessageBodyWriter doing it's writing). We can perform some operations before the MessageBodyWriter does it's job, call proceed() to let the writer do it's work, then we can do some more work.

With that said, here are the steps you can take:

  1. Hold onto the old OutputStream from the context, with context.getOutputStream()
  2. Create a ByteArrayOutputStream and set that as the OutputStream on the context, with context.setOutputStream(baos)
  3. Call context.proceed(). What this does is have the MessageBodyWriter write to the ByteArrayOutputStream.
  4. Get the byte[] from the ByteArrayOutputStream with baos.toByteArray()
  5. Checksum the byte[] and set the header
  6. Write the byte[] to the old OutputStream.
  7. Finally set the OutputStream on the context to the old OutputStream.

Here's the basic implementation (tested and works as expected)

@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);
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!