首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 中通過 JSON 傳輸圖片的實戰方案:Base64 替代方案與 GZIP 壓縮

     編輯:Java 綜合教學

Java 中通過 JSON 傳輸圖片的實戰方案:Base64 替代方案與 GZIP 壓縮

一、 場景與挑戰

項目需將存儲於 Oracle BLOB 字段的圖片經 JSON 接口返回給前端。JSON 無法直接承載二進制,常規做法是返回圖片 URL 由前端二次請求,但受限於架構必須內嵌圖片數據。Base64 編碼雖通用,但體積膨脹 33%,且作者實測解碼後圖片損壞;最終採用 ISO-8859-1 編碼 + GZIP 壓縮 方案成功落地。

二、 三步走核心代碼

  1. 圖片 → 字節數組
private byte[] loadImage(File file) throws IOException {
    try (FileInputStream fin = new FileInputStream(file);
         ByteArrayOutputStream bout = new ByteArrayOutputStream((int)file.length())) {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fin.read(buffer)) != -1) {
            bout.write(buffer, 0, len);
        }
        return bout.toByteArray();
    }
}
  1. 字節數組 → ISO-8859-1 字符串
private String bytesToString(byte[] data) throws UnsupportedEncodingException {
    return new String(data, "ISO-8859-1");  // 單字節編碼,無損映射 0-255
}
  1. 字符串 GZIP 壓縮 → 再轉 ISO-8859-1 字符串入 JSON
private String compress(String data) throws IOException {
    try (ByteArrayOutputStream bout = new ByteArrayOutputStream();
         GZIPOutputStream gout = new GZIPOutputStream(bout)) {
        gout.write(data.getBytes("ISO-8859-1"));
        gout.finish();
        return bout.toString("ISO-8859-1");
    }
}

三、 關鍵細節與避坑指南

  • 為何用 ISO-8859-1? 它將每個字節 (0-255) 直接映射為 Unicode 碼位 (U+0000-U+00FF),實現「字節↔字符」無損雙向轉換,避免 UTF-8 多字節編碼導致的解碼錯誤。
  • 壓縮效果:小圖(3KB)可能因頭部開銷變大(5KB);大圖(17KB)顯著縮小(10KB)。建議「大圖壓縮、小圖直傳」策略。
  • Base64 失敗原因:常見於編碼/解碼鏈路不一致(如漏用 ISO-8859-1、流未關閉、字節序錯誤)。
  • 解碼端邏輯:JSON 取字符串 → getBytes("ISO-8859-1") → GZIPInputStream 解壓 → 字節數組 → 寫文件/返回流。

四、 完整調用鏈路

// 服務端
byte[] imgBytes = loadImage(blobFile);
String jsonStr = compress(bytesToString(imgBytes));
// 放入 JSON 字段返回

// 客戶端
byte[] compressed = jsonStr.getBytes("ISO-8859-1");
try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressed));
     ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
    byte[] buf = new byte[1024];
    int len;
    while ((len = gis.read(buf)) != -1) bos.write(buf, 0, len);
    byte[] originalImg = bos.toByteArray(); // 還原圖片字節
}

此方案在「不能存文件系統、必須 JSON 內嵌二進制」的受限場景下經驗證可行,關鍵在於 ISO-8859-1 無損字節映射 與 GZIP 節省頻寬 的組合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved