使用OkHttp對接微信小程序接口,獲取到小程序返回的二維碼照片信息后保存到騰訊云COS進行存儲喜爷。
1. 問題描述:
最終上傳到騰訊云的照片打開是黑屏的(問題的原因就是照片損壞)琳水。
但是:調(diào)用原生微信接口是可以獲取到小程序碼向臀。
問題就是出在自己的業(yè)務(wù)代碼芥吟。
注意點:當微信返回異常時获列,不會返回照片byte[]逗爹,返回的JSON格式的byte[]亡嫌,不能轉(zhuǎn)換為Base64后上傳到騰訊云COS,否則就會出現(xiàn)照片“黑屏”的情況掘而。
但是:微信接口能正常返回小程序碼挟冠。所以不是上面的情況。
2. 問題定位:
原因是微信小程序接口返回的body的source字段本身就是照片流袍睡,將其轉(zhuǎn)換字符串知染,然后獲取字符串的流,導(dǎo)致文件損壞斑胜,出現(xiàn)黑屏現(xiàn)象控淡。
正確代碼:
public class WxQrCodeServiceImpl implements WxQrCodeService {
private Logger logger = LoggerFactory.getLogger(WxQrCodeServiceImpl.class);
public static final String IMAGE_GIF_VALUE = "image/gif";
public static final String IMAGE_JPEG_VALUE = "image/jpeg";
public static final String IMAGE_PNG_VALUE = "image/png";
@Override
public WxQrCode getWxQrCode(String accessToken, QrCodeDTO qrCodeDTO) {
if (Objects.isNull(accessToken) || Objects.isNull(qrCodeDTO.getScene()) || qrCodeDTO.getScene().length() > SCENE_MAX_LENGTH) {
throw new IllegalArgumentException("參數(shù)不正確");
}
//使用OkHttp調(diào)用微信接口返回Response對象
Response response = OkHttpUtil.postForResponse(String.format(GET_QR_CODE_URL, accessToken), null, GSON.toJson(qrCodeDTO));
if (Objects.nonNull(response) && response.isSuccessful() && Objects.nonNull(response.body())) {
try {
WxQrCode wxQrCode = new WxQrCode();
Optional.ofNullable(response.body().contentType()).ifPresent(s -> wxQrCode.setContentType(s.toString()));
wxQrCode.setContentLength(response.body().contentLength());
//圖片類型轉(zhuǎn)換為Base64
if (isImg(wxQrCode.getContentType())) {
wxQrCode.setCode(new String(Base64.getEncoder().encode(response.body().bytes())));
} else {
//非圖片類型直接拋出異常
throw new RuntimeException("獲取微信二維碼接口失敗:" + response.body().string());
}
return wxQrCode;
} catch (Exception e) {
logger.error("獲取二維碼系統(tǒng)失敗", e);
}
}
return null;
}
/**
* 判斷是否是照片類型
* @param type 請求的content-type
* @return true:照片類型止潘,false:非照片類型
*/
private boolean isImg(String type) {
// 返回的類型若為圖片掺炭,則成功
if (type != null && (type.equals(IMAGE_GIF_VALUE)
|| type.equals(IMAGE_JPEG_VALUE)
|| type.equals(IMAGE_PNG_VALUE))) {
return true;
}
return false;
}
}
3. 擴展—讀取照片轉(zhuǎn)換為Base64的方式
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
public class Imagebase64 {
/**
* base64照片的前綴
*/
public static String BASE64_PREFIX = "data:image/png;base64,";
public static void main(String[] args) {
//獲取到Base64
String imageBinary = getImageBinary();
base64StringToImage(imageBinary);
}
/**
* 讀取照片獲取base64
* @return
*/
static String getImageBinary() {
File f = new File("/Users/xxx/Downloads/input.png");
try {
BufferedImage bi = ImageIO.read(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
//讀出的是流
byte[] bytes = baos.toByteArray();
//轉(zhuǎn)換為base64
return BASE64_PREFIX + new String(Base64.getEncoder().encode(bytes));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
static void base64StringToImage(String base64String) {
try {
//截取base64照片的前綴
String[] d = base64String.split("base64,");
//原始照片流
String base64 = d[1];
//base64轉(zhuǎn)換為數(shù)組
byte[] decode = Base64.getDecoder().decode(base64);
//IO讀取到本地
ByteArrayInputStream bais = new ByteArrayInputStream(decode);
BufferedImage bi1 = ImageIO.read(bais);
File f1 = new File("/Users/xxx/Downloads/out.jpg");
ImageIO.write(bi1, "jpg", f1);
} catch (IOException e) {
e.printStackTrace();
}
}
}