你这个问题我今天遇到,排查了一上午,最后发现图片url请求返回的数据是gzip格式,在base64编码前要gzip解码,再进行base64编码。
浏览器上看到的返回头信息
Age:2829
Connection:keep-alive
Content-Encoding:gzip
Content-Type:image/jpeg
Date:Fri, 28 Sep 2018 02:29:54 GMT
EagleId:790b009515381046232548971e
ETag:"5aefed0a-3a1e"
Last-Modified:Mon, 07 May 2018 06:07:06 GMT
Server:Tengine
Timing-Allow-Origin:*
Via:cache20.l2st3-2[0,304-0,H], cache29.l2st3-2[15,0], kunlun8.cn2372[0,304-0,H], kunlun1.cn2372[1,0]
X-Cache:HIT TCP_IMS_HIT dirn:10:228113073
第三行Content-Encoding:gzip
正确的代码
/**
* 在线图片转换成base64字符串
*
* @param imgURL 图片线上路径
* @return
*/
public static String ImageToBase64ByOnline(String imgURL) {
if (StringUtils.isBlank(imgURL)) {
return null;
}
HttpURLConnection conn = null;
InputStream is = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 创建URL
URL url = new URL(imgURL);
// 创建链接
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
is = conn.getInputStream();
// 将内容读取内存中
int len = -1;
byte[] by = new byte[1024];
while ((len = is.read(by)) != -1) {
out.write(by, 0, len);
}
byte[] dataByte = out.toByteArray();
//如果 图片经过nginx就会被压缩,返回头中包含 Content-Encoding:gzip 则需要对图片数据解压缩
String contentEncoding = conn.getContentEncoding();
if("gzip".equalsIgnoreCase(contentEncoding)){
dataByte = GZIPUtils.uncompress(dataByte);
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(dataByte);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
// 关闭流
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
is = null;
}
}
if (conn != null) {
conn.disconnect();
}
}
return null;
}
gzip解码工具
/**
* GZIP解压缩
*
* @param bytes 压缩内容
* @return
*/
public static byte[] uncompress(byte[] bytes) throws IOException {
if (bytes == null || bytes.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPInputStream ungzip = null;
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[1024];
int n = 0;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
ungzip.close(); //这个会写入一些数据,所以要在out使用前调用
return out.toByteArray();
} finally {
out.close();
}
}