如何在Quarkus(非响应式JsonB+Resteasy)序列化后添加拦截器
在Quarkus(JsonB+非响应式Resteasy)中实现序列化后加密拦截器
要实现序列化完成后对JSON字符串加密的需求,你可以通过包装响应输出流的方式,在JsonB完成序列化写入流的时机捕获内容并加密,完全复用Quarkus原有序列化机制,无需手动处理序列化逻辑。
步骤1:实现自定义加密输出流
这个流会先缓存JsonB序列化后的内容,在flush时执行加密并写入原流:
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; public class EncryptingOutputStream extends OutputStream { private final OutputStream originalStream; private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); public EncryptingOutputStream(OutputStream originalStream) { this.originalStream = originalStream; } @Override public void write(int b) throws IOException { buffer.write(b); } @Override public void flush() throws IOException { // 获取序列化完成的JSON字符串 String serializedJson = buffer.toString("UTF-8"); // 调用自定义加密工具执行加密 String encryptedJson = YourCustomEncryptionUtil.encrypt(serializedJson); // 将加密后的内容写入原输出流 originalStream.write(encryptedJson.getBytes("UTF-8")); originalStream.flush(); buffer.reset(); } @Override public void close() throws IOException { flush(); originalStream.close(); } }
步骤2:实现ContainerResponseFilter替换响应流
通过过滤器将原响应流替换为自定义加密流,让JsonB的序列化输出流向我们的缓存流:
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.Provider; @Provider public class PostSerializationEncryptionFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { // 替换原输出流为加密包装流 responseContext.setEntityStream(new EncryptingOutputStream(responseContext.getEntityStream())); } }
关键说明
@Provider注解会让Quarkus自动识别并注册这个过滤器,若未生效可检查quarkus.jaxrs.scan=true是否开启- 替换流后,JsonB会正常序列化原Java实体到包装流中,我们在
flush阶段拿到完整的序列化JSON,保证加密时机正确 - 替换
YourCustomEncryptionUtil.encrypt为你自己的加密工具实现,注意处理加密过程中的异常
内容的提问来源于stack exchange,提问作者PentaKon
相关产品推荐
相关产品推荐

