JAVA实现三方接口对接:人脸识别中的应用

JAVA实现与第三方接口对接

一、GET请求和POST请求简介

Ⅰ、定义:

  • POST请求:POST请求是向服务器提交数据的一种请求方法,通过请求体传递数据。

  • GET请求:GET请求是从服务器获取数据的一种请求方法,通过URL参数传递数据。

Ⅱ、特点:

  • POST请求的特点:

    • 数据传递方式:使用请求体来传输数据,数据不会直接暴露在URL中。

    • 数据安全性:POST请求相对于GET请求更安全,因为数据不会明文出现在URL上。

    • 请求体大小:POST请求没有限制请求体的大小,可以传输较大的数据。

    • 幂等性:POST请求不具备幂等性,即多次提交同一请求可能会产生不同的结果。

  • GET请求的特点:

    • 数据传递方式:使用URL参数来传递数据,数据会显示在URL中。

    • 数据长度限制:GET请求由于URL长度限制,传输的数据量较小。

    • 缓存支持:GET请求可以被浏览器缓存,对于相同的URL再次请求时可直接从缓存获取响应。

    • 幂等性:GET请求具备幂等性,即多次提交同一请求会产生相同的结果。

Ⅲ、关联:

  • 相同点:

    • 都是基于HTTP协议的请求方法。

    • 都可以在请求头中携带各种参数和数据进行通信。

    • 都能够接收服务器返回的响应数据。

  • 不同点:

    • 数据传递方式:POST请求使用请求体传递数据,GET请求使用URL参数传递数据。

    • 数据安全性:POST请求相对于GET请求更安全,因为数据不会明文出现在URL上。

    • 请求体大小限制:GET请求由于URL长度限制,传输的数据量较小,而POST请求没有限制请求体的大小。

    • 幂等性:POST请求不具备幂等性,GET请求具备幂等性

Ⅳ、扩展

  • 从计算机网络的角度来看:

    • POST请求可以传输大量数据,适用于需要向服务器发送表单数据或上传文件等情况,但相对地更占用服务器资源。

    • GET请求适用于获取资源,如请求网页、检索数据,它会将数据包含在URL中发送给服务器,比较简单高效。

  • 从Java Web开发的角度来看:

    • 在Java Web开发中,POST请求常用于表单提交、文件上传等需要传递大量数据的场景。

    • GET请求常用于页面转跳、获取数据、搜索等不对服务器产生副作用的操作。

需要注意的是,无论是POST请求还是GET请求,使用时都要考虑安全性和性能的因素,根据实际需求选择合适的请求方式。

二、JAVA实现GET请求

  • pom文件,引入 httpclient依赖

       <!-- httpclient --> 
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
        </dependency>
  • 构建请求参数

        Map<String, String> req = new HashMap<String, String>();
        req.put("parameter",parameter);
        String response = HttpUtils.sendGet(URL+BASE_USER_INFO_API,req);
        log.info("调用请求结果response:{}",response);
        if (StringUtils.isEmpty(response)){
            throw new BizException("请求为空");
        }
        JSONObject responseJSON = JSONObject.parseObject(response);
        /**
        * 后面就写自己的业务代码
        */
  • GET请求实现

    //调用入口
    public static String sendGet(String url, Map<String, String> paramsMap) {
        try {
            return sendGet(getUrl(url, paramsMap));
        } catch (Exception var3) {
            log.info("Exception异常 {}", var3);
            throw new HttpException("Exception异常", var3.getMessage(), var3);
        }
    }
    //转化URL
    public static String getUrl(String url, Map<String, String> paramsMap) {
        ArrayList params = new ArrayList();
​
        try {
            Iterator var3 = paramsMap.entrySet().iterator();
​
            while(var3.hasNext()) {
                Entry<String, String> entry = (Entry)var3.next();
                NameValuePair nameValuePair = new BasicNameValuePair((String)entry.getKey(), (String)entry.getValue());
                params.add(nameValuePair);
            }
​
            if (CollectionUtils.isNotEmpty(params)) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
                entity.setContentType("application/x-www-form-urlencoded");
                url = url + "?" + EntityUtils.toString(entity);
                log.info("url ==  {}", url);
            }
​
            return url;
        } catch (Exception var6) {
            log.info("Exception异常 {}", var6);
            throw new HttpException("Exception异常", var6.getMessage(), var6);
        }
    }
    //发起请求并返回响应报文:json格式数据
    public static String sendGet(String url) {
        HttpGet httpget = new HttpGet(url);
        httpget.setConfig(defaultRequestConfig);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpget);
            log.info("响应报文 response = {}", JSON.toJSONString(response));
        } catch (IOException var13) {
            log.info("IOException异常 {}", var13);
            throw new HttpException("IOException异常", var13.getMessage(), var13);
        }
        String result = null;
        try {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, "UTF-8");
                EntityUtils.consume(entity);
            }
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new HttpException(result, String.valueOf(response.getStatusLine().getStatusCode()));
            }
        } catch (IOException | ParseException var14) {
            log.info("ParseException | IOException 异常 {}", var14);
            throw new HttpException("IOException异常", var14.getMessage(), var14);
        } finally {
            try {
                response.close();
            } catch (IOException var12) {
                log.info("IOException异常 {}", var12);
            }
        }
        return result;
    }

三、JAVA实现POST请求

  • 构建请求参数:

        Map<String, String> req = new HashMap<String, String>();
        req.put("parameter",parameter);
        String response = HttpUtils.sendPost(URL,JSONObject.toJSONString(req));
        log.info("调用请求结果response:{}",response);
        if (StringUtils.isEmpty(response)){
            throw new BizException("请求结果为空");
        }
        JSONObject responseJSON = JSONObject.parseObject(response);
        /**
        * 后面就写自己的业务代码
        */
  • post发送请求实现方法:

​
​
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
​
            conn.setRequestProperty("Content-Type", "application/json");
​
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            log.error("发送 POST 请求出现异常!"+e);
            throw new IybException("发送 POST 请求出现异常");
        }
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                log.error("异常信息:" + ex);
            }
        }
        log.info("HttpUtil sendPost end result = {}", url);
        return result;
    }
​
}

四、项目实例:GET请求实现

Ⅰ、背景:

在工作做项目时候,需要开发一个H5的人脸识别功能,此功能调用第三方公司api实现。发起请求认证过程省略,只简单实现认证结果的查询

Ⅱ、API对接请求

  • 请求方式:GET请求

  • 请求参数:如下图所示

Ⅲ、API对接响应报文

  • 成功响应报文:

{
    "request_id": "1462259763,e2d2f8d6-204b-4c43-92ea-1d62b071f83c",
    "status": "OK",
    "biz_info": {
        "biz_extra_data": "...",
        "biz_id": "1462259748,52b13fb5-8dfb-4537-a62b-a641d5e929f1",
        "biz_no": "cc47190f-5502-44a2-ab74-ea4f0f649f61"
    },
    "idcard_info": {
        "idcard_mode": "1",
        "idcard_uneditable_feild": "idcard_number,idcard_valid_date",
        "idcard_number": "xxxxxx19910602xxxx",
        "idcard_name": "陈AB",
        "idcard_issued_by": "北京市公安局",
        "front_side": {
            "ocr_result": {
                "address": "北京市海淀区XXXX",
                "birthday": {
                    "day": "2",
                    "month": "6",
                    "year": "1991"
                },
                "gender": "男",
                "id_card_number": "xxxxxx19910602xxxx",
                "name": "陈XX",
                "race": "汉",
                "legality": {
                    "ID Photo": 0.855,
                    "Temporary ID Photo ": 0,
                    "Photocopy": 0.049,
                    "Screen": 0.096,
                    "Edited": 0
                }
            },
            "upload_times": 1
        },
        "back_side": {
            "ocr_result": {
                "issued_by": "北京市公安局海淀分局",
                "valid_date": "2010.11.13-2020.11.13",
                "legality": {
                    "ID Photo": 0.855,
                    "Temporary ID Photo ": 0,
                    "Photocopy": 0.049,
                    "Screen": 0.096,
                    "Edited": 0
                }
            },
            "upload_times": 2
        }
    },
    "liveness_result": {
        "procedure_type": "video",
        "result": "PASS/FAIL/TIMEOUT",
        "details": {
            "UPLOAD_TIMES": 5,
            "FACE_NOT_FOUND": 0,
            "LOW_FACE_QUALITY": 0,
            "INVALID_VIDEO_DURATION": 1,
            "SR_ERROR": 2,
            "NOT_SYNCHRONIZED": 1,
            "VIDEO_FORMAT_UNSUPPORTED": 0,
            "NO_AUDIO": 0
        },
        "face_genuineness": {
            "synthetic_face_confidence": 0.88,
            "synthetic_face_threshold": 0.5,
            "mask_confidence": 0.32,
            "mask_threshold": 0.5,
            "screen_replay_confidence": 0,
            "screen_replay_threshold": 0.5
        }
    },
    "verify_result": {
        "result_faceid": {
            "confidence": 68.918,
            "thresholds": {
                "1e-3": 64,
                "1e-4": 69,
                "1e-5": 74,
                "1e-6": 79.9
            }
        },
        "result_ref1": {
            "confidence": 68.918,
            "thresholds": {
                "1e-3": 64,
                "1e-4": 69,
                "1e-5": 74,
                "1e-6": 79.9
            }
        },
        "result_idcard_photo": {
            "confidence": 68.918,
            "thresholds": {
                "1e-3": 64,
                "1e-4": 69,
                "1e-5": 74,
                "1e-6": 79.9
            }
        },
        "result_idcard_datasource": {
            "confidence": 68.918,
            "thresholds": {
                "1e-3": 64,
                "1e-4": 69,
                "1e-5": 74,
                "1e-6": 79.9
            }
        },
        "id_exceptions": {
            "id_attacked": 0,
            "id_photo_monochrome": 0
        }
    },
    "images": {
        "image_idcard_back": "data: image/jpeg;base64,...",
        "image_idcard_front": "data: image/jpeg;base64,...",
        "image_best": "data: image/jpeg;base64,..."
    },
    "time_used": 93
}
  • 失败响应报文:

{
    "error_message": "RESULT_NOT_FOUND",
    "request_id": "1462259901,fa79992d-ca61-48de-aa50-ea337c6aad42",
    "time_used": 4
}

Ⅳ、代码实现:

这代码中的发起请求方法可以上述关于get接口请求的定义。

    public FaceAuthResultVO queryFaceAuthResult(String serialNo) throws Exception {
        FaceAuthResultVO faceAuthResultVO = new FaceAuthResultVO();
        Map<String, String> req = new HashMap<String, String>() {{
            put("api_key", apiKey);
            put("api_secret", secretKey);
            put("biz_id", serialNo);
            put("return_image", "1");
        }};
        try{
            String faceAuthResult = HttpUtils.sendGet(resultUrl, req);
            log.info("人脸识别结果查询出参faceAuthResult{}",faceAuthResult);
            JSONObject resultData = JSONObject.parseObject(faceAuthResult);
            if(StringUtils.isEmpty(faceAuthResult)
                    || Objects.isNull(resultData.getJSONObject("liveness_result"))
                    || Objects.isNull(resultData.getJSONObject("verify_result"))
                    || Objects.isNull(resultData.getJSONObject("verify_result").getJSONObject("result_faceid"))){
                throw new BizException("人脸识别结果查询失败");
            }

/**
* 首先判断“status”是否为“OK”,status为OK表示完成了FaceID Lite验证
* 在判断“result”是否为“PASS”,为活体检测结果,检测是否被攻击(在getToken的时候fmp_mode为0时,该字段有效。)
* 最后判断“confidence”是否大于“1e-4”,大于的话我们认为是同一个人
*/
            if (resultData.getJSONObject("liveness_result").getString("result").equals(FACE_AUTH_PASS)){
                JSONObject verifyResult = resultData.getJSONObject("verify_result").getJSONObject("result_faceid");
                JSONObject thresholds = verifyResult.getJSONObject("thresholds");
                double confidence = verifyResult.getDouble("confidence");
                double threshold = thresholds.getDouble("1e-4");
                if (confidence>threshold){
                    faceAuthResultVO.setStatus("SUCCESS");
                    return faceAuthResultVO;
                }
            }
            JSONObject images = resultData.getJSONObject("images");
            if (Objects.nonNull(images)) {
                faceAuthResultVO.setImageBase64(images.getString("image_best"));
            }
            faceAuthResultVO.setStatus("FAIL");
        } catch (Exception e) {
            log.warn("人脸识别结果查询失败",e);
            e.printStackTrace();
        }
        return faceAuthResultVO;
    }
  • Ⅴ、人脸识别扩展:

  • 关于人脸识别结果计算:

    • 首先判断“status”是否为“OK”,status为OK表示完成了FaceID Lite验证。

    • 在判断“result”是否为“PASS”,为活体检测结果,检测是否被攻击(在getToken的时候fmp_mode为0时,该字段有效)。

    • 最后判断“confidence”是否大于“1e-4”,大于的话我们认为是同一个人

  • 接口文档:FaceID 文档中心 获取比对结果

  • TIP:旷世对接人脸识别中,在获取人脸识别请求时,用户名必须是中文,不然无法进行人脸识别,上述示例只是人脸识别的结果查询。

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值