Java消费RabbitMQ的Base64编码GZIP字符串调用解压工具无输出问题
问题根因
你遇到的无输出问题主要由以下几个错误叠加导致:
- 首先是Base64字符串转码错误:你调用
new String(data)时没有指定字符编码,会默认使用操作系统的默认编码转码,如果和生产者发送Base64字符串时用的编码(通常是UTF-8)不一致,会直接导致Base64字符串乱码,解码后得到的字节数组不是合法的GZIP格式。 - 其次是Base64实现不统一:你的
GzipUtil用的是Sun内部APIcom.sun.org.apache.xml.internal.security.utils.Base64,不仅跨JDK兼容性差,和你参考逻辑里用的JDK标准java.util.Base64解码规则也有差异,很容易出现解码后字节数组错误的情况。 - 第三是日志输出混淆:你消费逻辑用
System.err打印,GzipUtil里用System.out打印,两个流输出顺序不固定;而且当isZipped()判断为false时,你直接打印字节数组,输出内容就是[B@xxxx格式的对象地址,和你消费逻辑里打印的消息体格式完全一致,你大概率把GzipUtil打印的错误内容当成了消费逻辑的输出,误以为GzipUtil没有执行。 - 最后你的
GzipUtil解压输出逻辑本身有问题:循环读取每一行时都重复打印拼接中的StringBuilder,会出现内容重复输出的情况。
修复方案
- 替换GzipUtil的Base64实现为JDK标准版本:
// 替换掉com.sun的导入,改用JDK自带的Base64 import java.util.Base64; // 解码部分修改为 byte[] compressed = Base64.getDecoder().decode(putBase64EncodedGzippedStringHere);
如果生产者用的是URL安全的Base64,就换成Base64.getUrlDecoder()。
- 转码消息体时指定编码:
// 把GzipUtil.unzip( new String(data) )改为 GzipUtil.unzip( new String(data, StandardCharsets.UTF_8) );
- 修复GzipUtil的输出逻辑:
// 非GZIP格式时打印明确提示,不要直接打印字节数组 if (!isZipped(compressed)) { System.out.println("解码后内容不是GZIP格式,原始字节长度:" + compressed.length); return; } // 解压部分改为读取完成后再打印完整内容 StringBuilder output = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { output.append(line); } // 循环结束后统一打印 System.out.println("解压后内容:" + output.toString());
- 确认生产者逻辑和消费端对齐:确保生产者侧是先对原始内容做GZIP压缩,再把压缩后的字节数组做Base64编码为UTF-8字符串,最后把字符串转成字节数组发送到RabbitMQ。
内容的提问来源于stack exchange,提问作者sjantke
相关产品推荐
相关产品推荐

