deason 2 vuotta sitten
vanhempi
commit
c2608d2e71

+ 18 - 17
examcloud-starters/examcloud-face-verify-starter/src/main/java/cn/com/qmth/examcloud/starters/face/verify/model/FaceResult.java

@@ -10,19 +10,20 @@ public class FaceResult implements Serializable {
     private static final long serialVersionUID = -6981807543872661368L;
 
     /**
-     * 接口是否请求成功
+     * 接口是否需要重试
+     * 注:接口请求出现网络、图片加载等偶发异常时建议重试几次调用,其它情况则终止处理!
      */
-    private boolean apiSuccess;
+    private boolean apiRetry;
 
     /**
      * 人脸是否通过
      */
-    private boolean pass;
+    private boolean facePass;
 
     /**
-     * 分值
+     * 人脸分值
      */
-    private double score;
+    private double faceScore;
 
     /**
      * 人脸数
@@ -46,28 +47,28 @@ public class FaceResult implements Serializable {
         return faceNum > 1;
     }
 
-    public boolean isPass() {
-        return pass;
+    public boolean isApiRetry() {
+        return apiRetry;
     }
 
-    public void setPass(boolean pass) {
-        this.pass = pass;
+    public void setApiRetry(boolean apiRetry) {
+        this.apiRetry = apiRetry;
     }
 
-    public boolean isApiSuccess() {
-        return apiSuccess;
+    public boolean isFacePass() {
+        return facePass;
     }
 
-    public void setApiSuccess(boolean apiSuccess) {
-        this.apiSuccess = apiSuccess;
+    public void setFacePass(boolean facePass) {
+        this.facePass = facePass;
     }
 
-    public double getScore() {
-        return score;
+    public double getFaceScore() {
+        return faceScore;
     }
 
-    public void setScore(double score) {
-        this.score = score;
+    public void setFaceScore(double faceScore) {
+        this.faceScore = faceScore;
     }
 
     public int getFaceNum() {

+ 42 - 22
examcloud-starters/examcloud-face-verify-starter/src/main/java/cn/com/qmth/examcloud/starters/face/verify/model/baidu/BaiduApiHelper.java

@@ -133,20 +133,30 @@ public class BaiduApiHelper {
 
     private static FaceResult parseFaceDetectResult(BaiduResponse response) {
         FaceResult result = new FaceResult();
-        result.setApiSuccess(true);
-        result.setPass(false);
-        result.setScore(0d);
+        result.setFacePass(false);
+        result.setFaceScore(0d);
         result.setFaceNum(0);
         result.setJsonResult(new JsonHelper().style(Include.NON_NULL).toJson(response));
 
-        if (response.getError_code() != 0) {
-            result.setApiSuccess(false);
-            result.setError(response.getError_code() + " - " + response.getError_msg());
+        int errorCode = response.getError_code();
+        if (errorCode != 0) {
+            result.setApiRetry(true);// 默认值
+            result.setError(errorCode + " - " + response.getError_msg());
 
-            // 请求并发超限(约10个/秒,可按需调整)
-            if (response.getError_code() == 18) {
-                // log.warn("baidu_api_limit...");
+            if (errorCode == 222202 || errorCode == 222203 || errorCode == 222209 || errorCode == 222304) {
+                // 222202 图片中没有人脸
+                // 222203 无法解析人脸
+                // 222209 face token不存在
+                // 222304 图片尺寸太大
+
+                result.setApiRetry(false);
             }
+
+            // 请求并发超限(约10个/秒,可按需调整)
+            /*if (errorCode == 18) {
+                log.warn("facepp_api_limit...");
+            }*/
+
             return result;
         }
 
@@ -168,7 +178,7 @@ public class BaiduApiHelper {
                 }
             }
         }
-        result.setScore(faceLiveness);
+        result.setFaceScore(faceLiveness);
 
         if (data.getFace_num() != null) {
             result.setFaceNum(data.getFace_num());
@@ -178,7 +188,7 @@ public class BaiduApiHelper {
 
         // 活体分数值,推荐阈值0.393241
         if (faceLiveness >= 0.39d) {
-            result.setPass(true);
+            result.setFacePass(true);
         } else {
             result.setError("faceLiveness=" + faceLiveness + " but less than 0.39");
         }
@@ -192,20 +202,30 @@ public class BaiduApiHelper {
         }
 
         FaceResult result = new FaceResult();
-        result.setApiSuccess(true);
-        result.setPass(false);
-        result.setScore(0d);
+        result.setFacePass(false);
+        result.setFaceScore(0d);
         result.setFaceNum(0);
         result.setJsonResult(new JsonHelper().style(Include.NON_NULL).toJson(response));
 
-        if (response.getError_code() != 0) {
-            result.setApiSuccess(false);
-            result.setError(response.getError_code() + " - " + response.getError_msg());
+        int errorCode = response.getError_code();
+        if (errorCode != 0) {
+            result.setApiRetry(true);// 默认值
+            result.setError(errorCode + " - " + response.getError_msg());
 
-            // 请求并发超限(约10个/秒,可按需调整)
-            if (response.getError_code() == 18) {
-                // log.warn("baidu_api_limit...");
+            if (errorCode == 222202 || errorCode == 222203 || errorCode == 222209 || errorCode == 222304) {
+                // 222202 图片中没有人脸
+                // 222203 无法解析人脸
+                // 222209 face token不存在
+                // 222304 图片尺寸太大
+
+                result.setApiRetry(false);
             }
+
+            // 请求并发超限(约10个/秒,可按需调整)
+            /*if (errorCode == 18) {
+                log.warn("facepp_api_limit...");
+            }*/
+
             return result;
         }
 
@@ -216,10 +236,10 @@ public class BaiduApiHelper {
         }
 
         double score = data.getScore() != null ? data.getScore() : 0d;
-        result.setScore(score);
+        result.setFaceScore(score);
 
         if (score >= expectFaceCompareScore) {
-            result.setPass(true);
+            result.setFacePass(true);
         } else {
             result.setError("faceScore=" + score + " but less than " + expectFaceCompareScore);
         }

+ 51 - 22
examcloud-starters/examcloud-face-verify-starter/src/main/java/cn/com/qmth/examcloud/starters/face/verify/model/faceplus/FacePlusApiHelper.java

@@ -35,20 +35,31 @@ public class FacePlusApiHelper {
         FacePlusResponse response = callApi(Constants.FACEPP_FACE_DETECT_URL, request);
 
         FaceResult result = new FaceResult();
-        result.setApiSuccess(true);
-        result.setPass(false);
-        result.setScore(0d);
+        result.setFacePass(false);
+        result.setFaceScore(0d);
         result.setFaceNum(0);
         result.setJsonResult(new JsonHelper().style(Include.NON_NULL).toJson(response));
 
-        if (StringUtils.isNotEmpty(response.getError_message())) {
-            result.setApiSuccess(false);
-            result.setError(response.getError_message());
+        String errorMessage = response.getError_message();
+        if (StringUtils.isNotEmpty(errorMessage)) {
+            result.setApiRetry(true);// 默认值
+            result.setError(errorMessage);
 
-            // 请求并发超限(约20个/秒,可按需调整)
-            if ("CONCURRENCY_LIMIT_EXCEEDED".equals(response.getError_message())) {
-                // log.warn("facepp_api_limit...");
+            if (errorMessage.startsWith("INVALID_IMAGE_SIZE")
+                    || errorMessage.startsWith("INVALID_IMAGE_URL")
+                    || errorMessage.startsWith("IMAGE_FILE_TOO_LARGE")) {
+                // INVALID_IMAGE_SIZE 上传的图像像素尺寸太大或太小
+                // INVALID_IMAGE_URL 图片URL错误或者无效
+                // IMAGE_FILE_TOO_LARGE 图像文件太大,图片文件大小不超过2MB
+
+                result.setApiRetry(false);
             }
+
+            // 请求并发超限(约20个/秒,可按需调整)
+            /*if (errorMessage.startsWith("CONCURRENCY_LIMIT_EXCEEDED")) {
+                log.warn("facepp_api_limit...");
+            }*/
+
             return result;
         }
 
@@ -57,7 +68,7 @@ public class FacePlusApiHelper {
 
         if (faceNum == 1) {
             // 是否人脸检测通过 (只有一张人脸算成功,否则算失败)
-            result.setPass(true);
+            result.setFacePass(true);
         } else {
             result.setError("faceNum=" + faceNum + " but notEq 1");
         }
@@ -78,31 +89,42 @@ public class FacePlusApiHelper {
         FacePlusResponse response = callApi(Constants.FACEPP_FACE_COMPARE_URL, request);
 
         FaceResult result = new FaceResult();
-        result.setApiSuccess(true);
-        result.setPass(false);
-        result.setScore(0d);
+        result.setFacePass(false);
+        result.setFaceScore(0d);
         result.setFaceNum(0);
         result.setJsonResult(new JsonHelper().style(Include.NON_NULL).toJson(response));
 
-        if (StringUtils.isNotEmpty(response.getError_message())) {
-            result.setApiSuccess(false);
-            result.setError(response.getError_message());
+        String errorMessage = response.getError_message();
+        if (StringUtils.isNotEmpty(errorMessage)) {
+            result.setApiRetry(true);// 默认值
+            result.setError(errorMessage);
 
-            // 请求并发超限(约20个/秒,可按需调整)
-            if ("CONCURRENCY_LIMIT_EXCEEDED".equals(response.getError_message())) {
-                // log.warn("facepp_api_limit...");
+            if (errorMessage.startsWith("INVALID_IMAGE_SIZE")
+                    || errorMessage.startsWith("INVALID_IMAGE_URL")
+                    || errorMessage.startsWith("IMAGE_FILE_TOO_LARGE")) {
+                // INVALID_IMAGE_SIZE 上传的图像像素尺寸太大或太小
+                // INVALID_IMAGE_URL 图片URL错误或者无效
+                // IMAGE_FILE_TOO_LARGE 图像文件太大,图片文件大小不超过2MB
+
+                result.setApiRetry(false);
             }
+
+            // 请求并发超限(约20个/秒,可按需调整)
+            /*if (errorMessage.startsWith("CONCURRENCY_LIMIT_EXCEEDED")) {
+                log.warn("facepp_api_limit...");
+            }*/
+
             return result;
         }
 
         FacePlusThresholds thresholds = response.getThresholds();
         if (thresholds != null) {
             float confidence = response.getConfidence() != null ? response.getConfidence() : 0f;
-            result.setScore(confidence);
+            result.setFaceScore(confidence);
 
             // 是否人脸对比通过
             if (confidence >= thresholds.getLe_4()) {
-                result.setPass(true);
+                result.setFacePass(true);
             } else {
                 result.setError("faceConfidence=" + confidence + " but less than " + thresholds.getLe_4());
             }
@@ -126,13 +148,20 @@ public class FacePlusApiHelper {
             long cost = System.currentTimeMillis() - start;
             // System.out.println("response:" + code + " cost:" + cost + "ms body:" + bodyStr);
 
-            if (response.isSuccessful() || code == 400 || code == 401 || code == 403) {
+            if (response.isSuccessful() || code == 400 || code == 401 || code == 403 || code == 412) {
                 FacePlusResponse result = new JsonHelper().parseJson(bodyStr, FacePlusResponse.class);
                 if (result != null) {
                     return result;
                 }
             }
 
+            if (code == 413) {
+                // 客户发送的请求大小超过了2MB限制。该错误的返回格式为纯文本,不是json格式。
+                FacePlusResponse result = new FacePlusResponse();
+                result.setError_message("IMAGE_FILE_TOO_LARGE");
+                return result;
+            }
+
             log.warn("[FACE++] url:{} response:{} cost:{}ms body:{}", requestUrl, code, cost, bodyStr);
         } catch (IOException e) {
             log.error(e.getMessage(), e);