You've already forked FrameTour-BE
feat(facebody): 添加图片下载及base64重试机制
- 当添加人脸因无法访问URL图片失败时,自动下载图片并转换为base64后重试 - 新增downloadImageAsBase64方法用于图片下载与编码 - 替换阿里云OSS域名以支持内网访问 - 增加对png和jpg格式图片的支持 - 使用hutool库进行base64编码 - 添加详细的日志记录以便追踪重试过程
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.ycwl.basic.facebody.adapter;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import com.baidu.aip.face.AipFace;
|
||||
import com.ycwl.basic.facebody.entity.AddFaceResp;
|
||||
import com.ycwl.basic.facebody.entity.BceFaceBodyConfig;
|
||||
@@ -15,8 +16,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -152,10 +158,34 @@ public class BceFaceBodyAdapter implements IFaceBodyAdapter {
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
JSONObject response = client.addUser(faceUrl, "URL", dbName, entityId, options);
|
||||
if (response.getInt("error_code") == 0) {
|
||||
int errorCode = response.getInt("error_code");
|
||||
if (errorCode == 0) {
|
||||
AddFaceResp resp = new AddFaceResp();
|
||||
resp.setScore(100f);
|
||||
return resp;
|
||||
} else if (errorCode == 222204) {
|
||||
// error_code: 222204 表示无法正常访问URL图片,尝试下载并转换为base64后重试
|
||||
log.warn("无法正常访问URL图片,错误码: 222204,尝试下载图片转base64后重试,URL: {}", faceUrl);
|
||||
String base64Image = downloadImageAsBase64(faceUrl);
|
||||
if (base64Image != null) {
|
||||
try {
|
||||
addEntityLimiter.acquire();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
JSONObject retryResponse = client.addUser(base64Image, "BASE64", dbName, entityId, options);
|
||||
if (retryResponse.getInt("error_code") == 0) {
|
||||
log.info("使用base64重试添加人脸成功,entityId: {}", entityId);
|
||||
AddFaceResp resp = new AddFaceResp();
|
||||
resp.setScore(100f);
|
||||
return resp;
|
||||
} else {
|
||||
log.warn("使用base64重试添加人脸仍失败!{}", retryResponse);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.error("下载图片转base64失败,无法重试,URL: {}", faceUrl);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
log.warn("创建人脸失败!{}", response);
|
||||
return null;
|
||||
@@ -395,7 +425,53 @@ public class BceFaceBodyAdapter implements IFaceBodyAdapter {
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载图片并转换为base64字符串
|
||||
*
|
||||
* @param imageUrl 图片URL
|
||||
* @return base64编码的图片字符串,失败返回null
|
||||
*/
|
||||
private String downloadImageAsBase64(String imageUrl) {
|
||||
BufferedImage image = null;
|
||||
ByteArrayOutputStream baos = null;
|
||||
try {
|
||||
// 下载图片
|
||||
URL url = new URL(imageUrl.replace("oss-cn-shanghai.aliyuncs.com", "oss-cn-shanghai-internal.aliyuncs.com"));
|
||||
image = ImageIO.read(url);
|
||||
if (image == null) {
|
||||
log.error("无法读取图片,URL: {}", imageUrl);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 转换为字节数组
|
||||
baos = new ByteArrayOutputStream();
|
||||
String format = "jpg";
|
||||
if (imageUrl.toLowerCase().endsWith(".png")) {
|
||||
format = "png";
|
||||
}
|
||||
ImageIO.write(image, format, baos);
|
||||
byte[] imageBytes = baos.toByteArray();
|
||||
|
||||
// 编码为base64
|
||||
return Base64.encode(imageBytes);
|
||||
} catch (IOException e) {
|
||||
log.error("下载图片或转换base64失败,URL: {}", imageUrl, e);
|
||||
return null;
|
||||
} finally {
|
||||
if (image != null) {
|
||||
image.flush();
|
||||
}
|
||||
if (baos != null) {
|
||||
try {
|
||||
baos.close();
|
||||
} catch (IOException e) {
|
||||
log.warn("关闭ByteArrayOutputStream失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IRateLimiter getLimiter(LOCK_TYPE type) {
|
||||
return switch (type) {
|
||||
case ADD_DB ->
|
||||
|
||||
Reference in New Issue
Block a user