今天在测公司的中间件时发现,增加netty自带的zlib codec压缩处理后,就报decompress failed, invalid head之类的异常。后来发现,直接用bytebuf处理报文体是正常的,但是增加了stringencoder/decoder之后,就会出现这个异常。本来之前就想把这一步逻辑优化成报文体尽可能delay解压的,于是干脆给调整了。
因为java中,string\byte尤其是各种加密、加密操作增加的各种辅助信息,使得他们俩不能跟大部分普通操作的字符串转换一样互转,需要适用base64特殊处理后才能互转,如下:
public class ZlibUtils { public static String compress(String data) { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ZOutputStream zOut = new ZOutputStream(out, JZlib.Z_BEST_COMPRESSION); ObjectOutputStream objOut = new ObjectOutputStream(zOut); objOut.writeObject(data); zOut.close(); return Base64.encodeBase64String(out.toByteArray()); } catch (IOException e) { e.printStackTrace(); } return null; } public static String decompress(String data) { try { ByteArrayInputStream in = new ByteArrayInputStream( Base64.decodeBase64(data)); ZInputStream zIn = new ZInputStream(in); ObjectInputStream objIn = new ObjectInputStream(zIn); return (String) objIn.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) throws UnsupportedEncodingException { String compressed = compress("0000007901qqqq.qq.qqqqqqqq0000002171779ad0dfdb4a4f9ac4be18ef3a78080837403181000drpcpqq"); System.out.println(compressed.length()); System.out.println(decompress(compressed)); System.out.println(System.currentTimeMillis()); compressed = compress("兼容性要求(参考OS/浏览器市场份额调查报告http://www.jiangweishan.com/article/marketData.htmlhttp://www.jiangweishan.com/article/marketData.htmlhttp://www.jiangweishan.com/article/marketData.html|http://www.jiangweishan.com/article/marketData2016.html):兼容性要求(参考OS/浏览器市场份额调查报告http://www.jiangweishan.com/article/marketData.html|http://www.jiangweishan.com/article/marketData2016.html):"); System.out.println(decompress(compressed)); }}
这样就可以完全做到string进string出了,不过因为base64会增加大约1/3的额外大小,抵消了部分压缩的效果。
Base64编码说明
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。