客户端通过二维传输数据的情况较多,但是直接传输可能因为数据过长导致二维码生成的太密不好扫描

可以使用GZIP字符串缩短进行传输,下面直接代码

public class GZipUtils {
    public static String compress(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return android.util.Base64.encodeToString(out.toByteArray(),android.util.Base64.NO_WRAP);
        //return new String(Base64.getEncoder().encode(out.toByteArray()));
    }

    /**
     * 使用gzip解压缩
     *
     * @param compressedStr 压缩字符串
     */
    public static String uncompress(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = null;
        GZIPInputStream ginzip = null;
        byte[] compressed = null;
        String decompressed = null;
        try {
           // compressed = Base64.getDecoder().decode(compressedStr);
            compressed = android.util.Base64.decode(compressedStr,android.util.Base64.NO_WRAP);
            in = new ByteArrayInputStream(compressed);
            ginzip = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = ginzip.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ginzip != null) {
                try {
                    ginzip.close();
                } catch (IOException ignored) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ignored) {
                }
            }
            try {
                out.close();
            } catch (IOException ignored) {
            }
        }
        return decompressed;
    }

}

测试一下:

    private fun test() {
        logDebug("--------------开始任务---------------------")
        val str =
            "qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名"

        val compress = GZipUtils.compress(str)
        logDebug("compress = " + compress)
        val uncompress = GZipUtils.uncompress(compress)
        logDebug("uncompress = " + uncompress)

        logDebug("--------------任务结束---------------------")
    }

打印结果

2022-09-08 10:27:55 --------------开始任务---------------------
compress = H4sIAAAAAAAAACssTy0qqSzNzC9ILE5JS8/Iys6pqkguS8rLNTA0MjYxNTO3sKxTdFBWUY1T09LQjNdOOLT0UcMyMJoCRNo1jxu6Hjd0v98zX0dP/+n8vqc7mhSeLp/8dEJv4ajRo0aPGk2K0QBuPT1YjgMAAA==
uncompress = qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名
2022-09-08 10:27:55任务结束---------------------

可以看到整个过程在1s内。

java和Android中的差异

java中的import java.util.Base64 (在Android中使用需要api>26)

Base64.getEncoder().encode(out.toByteArray())
Base64.getDecoder().decode(compressedStr)
等同于
Android的import android.util.Base64
Base64.encodeToString(out.toByteArray(),Base64.NO_WRAP);
Base64.decode(compressedStr,Base64.NO_WRAP)
可以直接使用Android包中自带的。

android包中的第二个参数:Base64.NO_WRAP 有好几种类型

需要注意的是,在android.util.Base64源码 发现Encoder有以下一行注释

static class Encoder extends Coder {
        /**
         * Emit a new line every this many output tuples.  Corresponds to
         * a 76-character line length (the maximum allowable according to
         * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
         */
       

大意就是超过76字符就会自动一行
对接其他平台时,有些平台使用base64对换行后的字符串不一定能正确decode,所以需要

android.util.Base64.encodeToString(input, Base64.DEFAULT);

换成

android.util.Base64.encodeToString(input, Base64.NO_WRAP);

我们来写个简单例子对比下DEFAULT、NO_PADDING、NO_WRAP和URL_SAFE,看看几种区别

    public static void test() {
        String str = "qwertyuiopasdfghjklzxcvbnm0123456789~!@#$%^&*()_+`¥……——+|《》?,./城市 姓名";
        byte[] byteStr = str.getBytes(StandardCharsets.UTF_8);
        String encode_DEFAULT = android.util.Base64.encodeToString(byteStr, android.util.Base64.DEFAULT);
        String encode_NO_PADDING = android.util.Base64.encodeToString(byteStr, android.util.Base64.NO_PADDING);
        String encode_NO_WRAP = android.util.Base64.encodeToString(byteStr, android.util.Base64.NO_WRAP);
        String encodeURL_SAFE = android.util.Base64.encodeToString(byteStr, android.util.Base64.URL_SAFE);


        Log.v("wlike","encode_DEFAULT = "+encode_DEFAULT);
        Log.v("wlike","encode_NO_PADDING = "+encode_NO_PADDING);
        Log.v("wlike","encode_NO_WRAP = "+encode_NO_WRAP);
        Log.v("wlike","encodeURL_SAFE = "+encodeURL_SAFE);


    }

打印结果:
在这里插入图片描述
相对于DEFAULT比较我们可以看见
NO_PADDING只是将末尾自动补全的=号去除了
NO_WRAP去除了换行输出始终为一整行
URL_SAFE将结果中的+变成-

总结
1.在android客户端自己解码,只要encode和decode使用对应flag即可。encode时flag为Base64.URL_SAFE,decode的flag必须为Base64.URL_SAFE。

2.如果需要第三方对接时,因为一般第三方http请求时会主动对参数参数urlencode 防止乱码,所以不需要处理+等字符直接使用NO_WRAP来encode。如果是自己封装http请求没有参数参数urlencode,则需要在请求时对参数参数urlencode下。

更多:
android.util.Base64使用
java实现生成二维码并压缩内容
Gzip在线转换测试

原文地址:https://blog.csdn.net/zx_android/article/details/126758761

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_37806.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注