使用OkHttp对接微信小程序接口,获取到小程序返回的二维码照片信息后保存到腾讯云COS进行存储。
1. 问题描述:
上传到腾讯云显示的照片.png最终上传到腾讯云的照片打开是黑屏的(问题的原因就是照片损坏)。
但是:调用原生微信接口是可以获取到小程序码。
问题就是出在自己的业务代码。
image.png注意点:当微信返回异常时,不会返回照片byte[],返回的JSON格式的byte[],不能转换为Base64后上传到腾讯云COS,否则就会出现照片“黑屏”的情况。
但是:微信接口能正常返回小程序码。所以不是上面的情况。
2. 问题定位:
原因是微信小程序接口返回的body的source字段本身就是照片流,将其转换字符串,然后获取字符串的流,导致文件损坏,出现黑屏现象。
image.png image.png正确代码:
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("参数不正确");
}
//使用OkHttp调用微信接口返回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());
//图片类型转换为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("获取二维码系统失败", 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. 扩展—读取照片转换为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();
//转换为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转换为数组
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();
}
}
}
网友评论