腾讯云 人脸核身接口 移动浮层H5接入

最近接触到了这个功能,下面看代码

主要工具类




public class FacialTools {
    private static double expireTimeToken;
    private static double expireTimeTicket;

    private static final String access_token_url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/access_token";
    private static final String api_ticket_url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket";
    private static final String geth5faceid_url = "https://miniprogram-kyc.tencentcloudapi.com/api/server/h5/geth5faceid";
    private static final String ADVFACE_URL = "https://miniprogram-kyc.tencentcloudapi.com/api/server/getAdvFaceId";
    private static final String queryfacerecord_url = "https://miniprogram-kyc.tencentcloudapi.com/api/v2/base/queryfacerecord";
    private static  String accessToken = "hie-bro!!";
    private static  String signTicket = "hie-bro!!!";
    //设置wbappid等参数
    private static final String app_id = "*******";
    private static final String secret = "********";
    private static final String grant_type = "client_credential";
    private static final String version = "1.0.0";
    public static final String type = "SIGN";
    public static final String userId = "*********";//子账户id


    public static void main(String[] args) throws Exception {
        // System.out.println(FacialTools.getSignTicket(FacialTools.getAccessToken()));
    }

    /**
     * 1.获取AccessToken
     * Access Token 必须缓存在磁盘,并定时刷新,且不能并发刷新,
     * 建议每20分钟请求新的 Access Token,获取之后立即使用最新的 Access Token。
     * 旧的只有一分钟的并存期。
     *
     * 此方法会判断内存中现有的accessToken是否失效,如果没有失效就不会发送新的请求----
     */
    public static String getAccessToken() throws Exception {
        if (FacialTools.tokenIsExpired()){//判断是否超时
            FacialTools.getAccessTokenByUrl();
        }
        return FacialTools.accessToken;
    }
    private static  void getAccessTokenByUrl() throws Exception{
        // 请求链接
        String accessTokenUrl = access_token_url
                + "?app_id=" + app_id
                + "&secret=" +  secret
                + "&grant_type=" + grant_type
                + "&version=" + version;
        JSONObject accessTokenObj = HttpHelper.doGet(accessTokenUrl);
        AccessTokenEntity accessToken = JSON.parseObject(accessTokenObj.toJSONString(), AccessTokenEntity.class);
        FacialTools.expireTimeToken = Double.parseDouble(accessToken.getExpire_time());
        FacialTools.accessToken = accessToken.getAccessToken();
    }

    /**
     * 2.获取SignTicket
     * SignTicket 必须缓存在磁盘,并定时刷新,且不能并发刷新,
     * 建议每20分钟请求新的 SignTicket,获取之后立即使用最新的 SignTicket。
     * 旧的只有一分钟的并存期。
     */
    public static String getSignTicket(String accessToken) throws Exception{
        if (FacialTools.ticketIsExpired()){
            FacialTools.getSignTicketByUrl(accessToken);
        }
        return FacialTools.signTicket;
    }
    private static void getSignTicketByUrl(String accessToken) throws Exception {
        // 请求链接
        String accessTokenUrl = api_ticket_url
                +"?app_id=" + app_id
                +"&access_token=" + accessToken
                +"&type=" + type
                +"&version=" + version;
        JSONObject signTicketObj = HttpHelper.doGet(accessTokenUrl);
        SiginTicketEntity siginTicketEntity = JSON.parseObject(signTicketObj.toJSONString(), SiginTicketEntity.class);
        SiginTicket siginTicket = siginTicketEntity.getTickets().get(0);
        FacialTools.expireTimeTicket = Double.parseDouble(siginTicket.getExpire_time());
        FacialTools.signTicket = siginTicket.getValue();
    }

    /**
     * 3. 生成SIGN ticket签名
     * @param userId 用户 ID ,用户的唯一标识(不要带有特殊字符)
     * @param signTicket Sign ticket获取的值
     * @param nonce 32位随机数
     * @return
     */
    public static String getSignTicketSign(String userId, String signTicket, String nonce){
        // 获取SIGN ticket
        List<String> list = new ArrayList<>();
        // wbappid
        list.add(FacialTools.app_id);
        // userId
        list.add(userId);
        // version
        list.add("1.0.0");
        // 32位随机数
        list.add(nonce);
        // 生成签名
        String sign = FacialTools.sign(list, signTicket);
        System.out.println("=======sign:"+sign);
        return sign;
    }

    /**
     * 4. 调用AdvFaceId接口
     * @param orderNo 订单号,字母/数字组成的字符串,每次(同一次人脸核身)唯一,不能超过32位
     * @param name 姓名
     * @param idCard 证件号码
     * @param userId 用户 ID ,用户的唯一标识(不能带有特殊字符),需要跟生成签名的 userId 保持一致
     * @param ticketSign 签名:使用上面生成的签名
     * @param nonce 随机数(和上面签名随机数保持一致)
     * @return
     */
    public static FaceidRsultEntity getAdvFaceId(String orderNo, String name, String idCard, String userId, String ticketSign, String nonce) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", FacialTools.app_id);
        jsonObject.put("orderNo", orderNo);
        jsonObject.put("name", name);
        jsonObject.put("idNo", idCard);
        jsonObject.put("userId", userId);
        jsonObject.put("version", FacialTools.version);
        jsonObject.put("sign", ticketSign);
        jsonObject.put("nonce", nonce);
        // post请求
        JSONObject h5faceidResult = HttpHelper.doPost(ADVFACE_URL+"?orderNo="+orderNo, jsonObject);
        FaceidRsultEntity faceidRsultEntity = JSON.parseObject(h5faceidResult.toJSONString(), FaceidRsultEntity.class);
        return faceidRsultEntity;
    }

    /**
     *  5. 获取NONCE ticket
     * @param accessToken
     * @param userId
     * @return
     */
    public static SiginTicketEntity getNonceTicket(String accessToken, String userId)  throws Exception{
        // 请求链接
        String accessTokenUrl = api_ticket_url
                +"?app_id=" + FacialTools.app_id
                +"&access_token=" + accessToken
                +"&type=" + FacialTools.type
                +"&version=" + FacialTools.version
                +"&user_id=" + userId;
        JSONObject signTicketObj = HttpHelper.doGet(accessTokenUrl);
        SiginTicketEntity siginTicketEntity = JSON.parseObject(signTicketObj.toJSONString(), SiginTicketEntity.class);
        return siginTicketEntity;
    }

    /**
     *  6. 生成Nonce签名
     * @param orderNo
     * @param userId
     * @param faceId
     * @param noceTicketSign
     * @param nonce
     * @return
     */
    public static String getNonceTicketSign(String orderNo, String userId, String faceId, String noceTicketSign, String nonce){
        // 获取SIGN ticket
        List<String> list = new ArrayList<>();
        // wbappid
        list.add(FacialTools.app_id);
        // orderNo
        list.add(orderNo);
        // userId
        list.add(userId);
        // faceId
        list.add(faceId);
        // version
        list.add("1.0.0");
        // 32位随机数
        list.add(nonce);
        // 生成签名
        String sign = FacialTools.sign(list, noceTicketSign);
        System.out.println("=======sign:"+sign);
        return sign;
    }
    /**
     * 7. 生成“启动H5人脸核身”链接
     * @param optimalDomain 必填;使用getAdvFaceId接口返回的 optimalDomain 域名
     * @param nonce 必填;随机数:32位随机串(字母 + 数字组成的随机数),需与Nonce签名保持一致
     * @param orderNo 必填;订单号,字母/数字组成的字符串,每次唯一,此信息为本次人脸核身上送的信息,不能超过32位
     * @param faceId 必填;getAdvFaceId接口返回的唯一标识
     * @param url 必填;H5 人脸核身完成后回调的第三方 URL,需要第三方提供完整 URL 且做 URL Encode
     * @param resultType 非必填;是否显示结果页面,参数值为“1”时直接跳转到 url 回调地址,null 或其他值跳转提供的结果页面
     * @param userId 必填;用户 ID ,用户的唯一标识(不要带有特殊字符)
     * @param noceSign 必填;签名:使用上面Nonce生成的签名
     * @param from 必填;browser:表示在浏览器启动刷脸;App:表示在 App 里启动刷脸,默认值为 App;公众号属于浏览器
     * @param redirectType 非必填;跳转模式,参数值为“1”时,刷脸页面使用 replace 方式跳转,不在浏览器 history 中留下记录;不传或其他值则正常跳转
     * @return
     */
    public static String getLoginUrl(String optimalDomain, String nonce, String orderNo, String faceId,
                                     String url, String resultType, String userId, String noceSign, String from,
                                     String redirectType){
        StringBuilder sb = new StringBuilder("https://");
        sb.append(optimalDomain).append("/api/web/login");
        sb.append("?webankAppId=").append(FacialTools.app_id);
        sb.append("&version=").append(FacialTools.version);
        sb.append("&nonce=").append(nonce);
        sb.append("&orderNo=").append(orderNo);
        sb.append("&faceId=").append(faceId);
        sb.append("&url=").append(url);
        sb.append("&resultType=").append(resultType);
        sb.append("&userId=").append(userId);
        sb.append("&sign=").append(noceSign);
        sb.append("&from=").append(from);
        sb.append("&redirectType=").append(redirectType);
        System.out.println("=========h5Url:"+ sb);
        return sb.toString();
    }

    /**
     * 8、人脸核身结果查询接口(升级)
     * @param orderNo 订单号,字母/数字组成的字符串,是您需要查询结果的人脸核身订单号
     * @param ticketSign 签名值,使用本页第一步生成的签名
     * @param nonce 随机数
     * 附加参数 getFile 是否需要获取人脸识别的视频和文件,值为1则返回视频和照片、值为2则返回照片、值为3则返回视频;其他则不返回
     * 附加参数 queryVersion 	查询接口版本号(传1.0则返回 sdk 版本号和 trtc 标识)
     * @return
     * @throws Exception
     */
    public static FaceidRsultEntity getFacialResult(String orderNo, String ticketSign, String nonce) throws Exception {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appId", FacialTools.app_id);
        jsonObject.put("orderNo", orderNo);
        jsonObject.put("version", FacialTools.version);
        jsonObject.put("sign", ticketSign);
        jsonObject.put("nonce", nonce);
        // post请求
        JSONObject h5faceidResult = HttpHelper.doPost(queryfacerecord_url+"?orderNo="+orderNo, jsonObject);
        FaceidRsultEntity faceidRsultEntity = JSON.parseObject(h5faceidResult.toJSONString(), FaceidRsultEntity.class);
        return faceidRsultEntity;
    }
    /**
     * 9. 生成SIGN ticket签名--- [8、人脸核身结果查询接口(升级)]专用
     * @param orderNo 唯一订单流水号
     * @param signTicket Sign ticket获取的值
     * @param nonce 32位随机数
     * @return
     */
    public static String getSignTicketSignForQuery(String orderNo, String signTicket, String nonce){
        // 获取SIGN ticket
        //WBappid、orderNo、version、ticket、nonce
        List<String> list = new ArrayList<>();
        // wbappid
        list.add(FacialTools.app_id);
        // orderNo
        list.add(orderNo);
        // version
        list.add("1.0.0");
        // 32位随机数
        list.add(nonce);
        // 生成签名
        String sign = FacialTools.sign(list, signTicket);
        System.out.println("=======sign:"+sign);
        return sign;
    }
    /**
     * 签名公共方法
     * @param values
     * @param ticket
     * @return
     */
    protected static String sign(List<String> values, String ticket) { //values传ticket外的其他参数
        if (values == null) {
            throw new NullPointerException("values is null");
        }
        values.removeAll(Collections.singleton(null));// remove null
        values.add(ticket);
        java.util.Collections.sort(values);

        StringBuilder sb = new StringBuilder();
        for (String s : values) {
            sb.append(s);
        }
        return Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase();
    }
    // 获取任意长度随机字符串
    public static String randomAlphanumeric(){
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        //指定字符串长度,拼接字符并toString
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 32; i++) {
            //获取指定长度的字符串中任意一个字符的索引值
            int number = random.nextInt(str.length());
            //根据索引值获取对应的字符
            char charAt = str.charAt(number);
            sb.append(charAt);
        }
        System.out.println("===========32位字符串:"+sb.toString());
        return sb.toString();
    }
    /**
     * 判断是否超时
     * @return
     */
    private static boolean tokenIsExpired(){
        Date date = new Date(); // 返回当前时间戳格式
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyyMMddHHmmss"); // 改变格式
        double now = Double.parseDouble(dateFormat.format(date));
        return now>FacialTools.expireTimeToken;
    }
    private static boolean ticketIsExpired(){
        Date date = new Date(); // 返回当前时间戳格式
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyyMMddHHmmss"); // 改变格式
        double now = Double.parseDouble(dateFormat.format(date));
        return now>FacialTools.expireTimeTicket;
    }
}

http请求工具类



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


/**
 * HTTP请求封装,建议直接使用sdk的API
 */
public class HttpHelper {

    /**
     * @desc :1.发起GET请求
     *
     * @param url
     * @return JSONObject
     * @throws Exception
     */
    public static JSONObject doGet(String url) throws Exception {

        //1.生成一个请求
        HttpGet httpGet = new HttpGet(url);
        //2.配置请求的属性
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();//2000
        httpGet.setConfig(requestConfig);

        //3.发起请求,获取响应信息
        //3.1 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            //3.2 发起请求,获取响应信息
            response = httpClient.execute(httpGet, new BasicHttpContext());

            //如果返回结果的code不等于200,说明出错了
            if (response.getStatusLine().getStatusCode() != 200) {

                System.out.println("request url failed, http code=" + response.getStatusLine().getStatusCode()
                        + ", url=" + url);
                return null;
            }
            //4.解析请求结果
            HttpEntity entity = response.getEntity();      //reponse返回的数据在entity中
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");  //将数据转化为string格式
                System.out.println("GET请求结果:"+resultStr);
                JSONObject result = JSON.parseObject(resultStr);    //将String转换为 JSONObject

                if(result.getInteger("errcode")==null) {
                    return result;
                }else if (0 == result.getInteger("errcode")) {
                    return result;
                }else {
                    System.out.println("request url=" + url + ",return value=");
                    System.out.println(resultStr);
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:"+errCode+", error message:"+errMsg);
                }
            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();                     //释放资源

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }


    /** 2.发起POST请求
     * @desc :
     *
     * @param url   请求url
     * @param data  请求参数(json)
     * @return
     * @throws Exception JSONObject
     */
    public static JSONObject doPost(String url, Object data) throws Exception {
        //1.生成一个请求
        HttpPost httpPost = new HttpPost(url);

        //2.配置请求属性
        //2.1 设置请求超时时间
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        httpPost.setConfig(requestConfig);
        //2.2 设置数据传输格式-json
        httpPost.addHeader("Content-Type", "application/json");
        //2.3 设置请求实体,封装了请求参数
        StringEntity requestEntity = new StringEntity(JSON.toJSONString(data), "utf-8");
        httpPost.setEntity(requestEntity);

        //3.发起请求,获取响应信息
        //3.1 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        try {


            //3.3 发起请求,获取响应
            response = httpClient.execute(httpPost, new BasicHttpContext());

            if (response.getStatusLine().getStatusCode() != 200) {

                System.out.println("request url failed, http code=" + response.getStatusLine().getStatusCode()
                        + ", url=" + url);
                return null;
            }

            //获取响应内容
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");
                System.out.println("POST请求结果:"+resultStr);

                //解析响应内容
                JSONObject result = JSON.parseObject(resultStr);

                if(result.getInteger("errcode")==null) {
                    return result;
                }else if (0 == result.getInteger("errcode")) {
                    return result;
                }else {
                    System.out.println("request url=" + url + ",return value=");
                    System.out.println(resultStr);
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:"+errCode+", error message:"+errMsg);
                }
            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();              //释放资源

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     * @desc : 3.上传文件
     *
     * @param url   请求url
     * @param file  上传的文件
     * @return
     * @throws Exception JSONObject
     */
    public static JSONObject uploadMedia(String url, File file) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
        httpPost.setConfig(requestConfig);

        //2.3 设置请求实体,封装了请求参数
        HttpEntity requestEntity = MultipartEntityBuilder.create().addPart("media",
                new FileBody(file, ContentType.create("multipart/form-data", Consts.UTF_8), file.getName())).build();

        //FileEntity requestEntity = new FileEntity(file,ContentType.MULTIPART_FORM_DATA);


        httpPost.setEntity(requestEntity);

        try {
            response = httpClient.execute(httpPost, new BasicHttpContext());

            if (response.getStatusLine().getStatusCode() != 200) {

                System.out.println("request url failed, http code=" + response.getStatusLine().getStatusCode()
                        + ", url=" + url);
                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");

                JSONObject result = JSON.parseObject(resultStr);

                //上传临时素材失败
                if (result.getInteger("errcode") != null && 0 != result.getInteger("errcode") ) {
                    System.out.println("request url=" + url + ",return value=");
                    System.out.println(resultStr);
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:"+errCode+", error message:"+errMsg);

                    //上传临时素材成功
                }else {
                    //result.remove("errcode");
                    //result.remove("errmsg");
                    return result;
                }

            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();                  //释放资源


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     * @desc : 上传PDF
     * 见微信电子发票章节
     * 9. 向用户提供发票或其它消费凭证PDF
     *
     * @param url
     * @param file
     * @return
     * @throws Exception
     *   JSONObject
     */
    public static JSONObject uploadPDF(String url, File file) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
        httpPost.setConfig(requestConfig);

        //2.3 设置请求实体,封装了请求参数
        HttpEntity requestEntity = MultipartEntityBuilder.create().addPart("media",
                new FileBody(file, ContentType.create("multipart/form-data", Consts.UTF_8), file.getName())).build();

        httpPost.setEntity(requestEntity);

        try {
            response = httpClient.execute(httpPost, new BasicHttpContext());

            if (response.getStatusLine().getStatusCode() != 200) {

                System.out.println("request url failed, http code=" + response.getStatusLine().getStatusCode()
                        + ", url=" + url);
                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");

                JSONObject result = JSON.parseObject(resultStr);
                //上传临时素材成功
                if (result.getString("errcode")== null) {
                    // 成功
                    //result.remove("errcode");
                    //result.remove("errmsg");
                    return result;
                } else {
                    System.out.println("request url=" + url + ",return value=");
                    System.out.println(resultStr);
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:"+errCode+", error message:"+errMsg);
                }
            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();                  //释放资源


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }
    /**
     * @desc : 4.下载文件 -get
     *
     * @param url  请求url
     * @param fileDir  下载路径
     * @return
     * @throws Exception File
     */
    public static File downloadMedia(String url, String fileDir) throws Exception  {
        //1.生成一个请求
        HttpGet httpGet = new HttpGet(url);
        //2.配置请求属性
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        httpGet.setConfig(requestConfig);

        //3.发起请求,获取响应信息
        //3.1 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        //4.设置本地保存的文件
        //File file = new File(fileDir);
        File file = null;
        try {
            //5. 发起请求,获取响应信息
            response = httpClient.execute(httpGet, new BasicHttpContext());
            System.out.println("HttpStatus.SC_OK:"+HttpStatus.SC_OK);
            System.out.println("response.getStatusLine().getStatusCode():"+response.getStatusLine().getStatusCode());
            System.out.println("http-header:"+JSON.toJSONString( response.getAllHeaders() ));
            System.out.println("http-filename:"+getFileName(response) );

            //请求成功
            if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){

                //6.取得请求内容
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    //这里可以得到文件的类型 如image/jpg /zip /tiff 等等 但是发现并不是十分有效,有时明明后缀是.rar但是取到的是null,这点特别说明
                    System.out.println(entity.getContentType());
                    //可以判断是否是文件数据流
                    System.out.println(entity.isStreaming());

                    //6.1 输出流
                    //6.1.1获取文件名,拼接文件路径
                    String fileName=getFileName(response);
                    fileDir=fileDir+fileName;
                    file = new File(fileDir);
                    //6.1.2根据文件路径获取输出流
                    FileOutputStream output = new FileOutputStream(file);

                    //6.2 输入流:从钉钉服务器返回的文件流,得到网络资源并写入文件
                    InputStream input = entity.getContent();

                    //6.3 将数据写入文件:将输入流中的数据写入到输出流
                    byte b[] = new byte[1024];
                    int j = 0;
                    while( (j = input.read(b))!=-1){
                        output.write(b,0,j);
                    }
                    output.flush();
                    output.close();
                }
                if (entity != null) {
                    entity.consumeContent();
                }
            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();                       //释放资源


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return file;
    }


    /**
     * @desc : 5.下载文件 - post
     *
     * @param url  请求url
     * @param data  post请求参数
     * @param fileDir 文件下载路径
     * @return
     * @throws Exception File
     */
    public static File downloadMedia(String url, Object data, String fileDir) throws Exception  {
        //1.生成一个请求
        HttpPost httpPost = new HttpPost(url);

        //2.配置请求属性
        //2.1 设置请求超时时间
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build();
        httpPost.setConfig(requestConfig);
        //2.2 设置数据传输格式-json
        httpPost.addHeader("Content-Type", "application/json");
        //2.3 设置请求参数
        StringEntity requestEntity = new StringEntity(JSON.toJSONString(data), "utf-8");
        httpPost.setEntity(requestEntity);

        //3.发起请求,获取响应信息
        //3.1 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        //4.设置本地保存的文件
        //File file = new File(fileDir);
        File file = null;
        try {
            //5. 发起请求,获取响应信息
            response = httpClient.execute(httpPost, new BasicHttpContext());
            System.out.println("HttpStatus.SC_OK:"+HttpStatus.SC_OK);
            System.out.println("response.getStatusLine().getStatusCode():"+response.getStatusLine().getStatusCode());
            System.out.println("http-header:"+JSON.toJSONString( response.getAllHeaders() ));
            System.out.println("http-filename:"+getFileName(response) );

            //请求成功
            if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){

                //6.取得请求内容
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    //这里可以得到文件的类型 如image/jpg /zip /tiff 等等 但是发现并不是十分有效,有时明明后缀是.rar但是取到的是null,这点特别说明
                    System.out.println(entity.getContentType());
                    //可以判断是否是文件数据流
                    System.out.println(entity.isStreaming());

                    //6.1 输出流
                    //6.1.1获取文件名,拼接文件路径
                    String fileName=getFileName(response);
                    fileDir=fileDir+fileName;
                    file = new File(fileDir);
                    //6.1.2根据文件路径获取输出流
                    FileOutputStream output = new FileOutputStream(file);

                    //6.2 输入流:从钉钉服务器返回的文件流,得到网络资源并写入文件
                    InputStream input = entity.getContent();

                    //6.3 将数据写入文件:将输入流中的数据写入到输出流
                    byte b[] = new byte[1024];
                    int j = 0;
                    while( (j = input.read(b))!=-1){
                        output.write(b,0,j);
                    }
                    output.flush();
                    output.close();
                }
                if (entity != null) {
                    entity.consumeContent();
                }
            }
        } catch (IOException e) {
            System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();                       //释放资源


            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return file;
    }


    /** 5. 获取response header中Content-Disposition中的filename值
     * @desc :
     *
     * @param response  响应
     * @return String
     */
    public static String getFileName(HttpResponse response) {
        Header contentHeader = response.getFirstHeader("Content-Disposition");
        String filename = null;
        if (contentHeader != null) {
            HeaderElement[] values = contentHeader.getElements();
            if (values.length == 1) {
                NameValuePair param = values[0].getParameterByName("filename");
                if (param != null) {
                    try {
                        //filename = new String(param.getValue().toString().getBytes(), "utf-8");
                        //filename=URLDecoder.decode(param.getValue(),"utf-8");
                        filename = param.getValue();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return filename;
    }



}
AccessTokenEntity



import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class AccessTokenEntity extends FaceBaseEntity {
    /**
     * 是否成功
     */
    private Boolean success;
    /**
     * access_token 的值
     */
    private String accessToken;
    /**
     * access_token 失效的绝对时间
     */
    private int expire_in;
    /**
     * access_token 的最大生存时间
     */
    private String expire_time;

//    public Boolean getSuccess() {
//        return success;
//    }

//    public void setSuccess(Boolean success) {
//        this.success = success;
//    }

//    public String getAccessToken() {
//        return accessToken;
//    }
//
//    public void setAccessToken(String accessToken) {
//        this.accessToken = accessToken;
//    }
//
//    public int getExpire_in() {
//        return expire_in;
//    }
//
//    public void setExpire_in(int expire_in) {
//        this.expire_in = expire_in;
//    }
//
//    public String getExpire_time() {
//        return expire_time;
//    }
//
//    public void setExpire_time(String expire_time) {
//        this.expire_time = expire_time;
//    }
}


FaceBaseEntity



import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class FaceBaseEntity {
    /**
     * 0:成功
     * 非0:失败
     */
    private String code;
    /**
     * 请求结果描述
     */
    private String msg;
    /**
     * 调用接口的时间
     */
    private String transactionTime;
//    public String getCode() {
//        return code;
//    }
//
//    public void setCode(String code) {
//        this.code = code;
//    }
//
//    public String getMsg() {
//        return msg;
//    }
//
//    public void setMsg(String msg) {
//        this.msg = msg;
//    }
//
//    public String getTransactionTime() {
//        return transactionTime;
//    }
//
//    public void setTransactionTime(String transactionTime) {
//        this.transactionTime = transactionTime;
//    }
}

FaceDetectUserVO


import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class FaceDetectUserVO {
    private String name;//姓名
    private String idNo;//证件号码
    private String userId;//用户 ID ,用户的唯一标识(不能带有特殊字符),需要跟生成签名的 userId 保持一致
    private String from = "browser";//来源 App || browser)
    private String orderNo;
    private String returnUrl;//人脸核身结束后的回调url
}
FaceidRsultEntity



import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class FaceidRsultEntity extends FaceBaseEntity{
    /**
     * 请求业务流水号
     */
    private String bizSeqNo;
    /**
     * 结果
     */
    private ResultEntity result;
}
ResultEntity


import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ResultEntity {
    /**
     * 请求业务流水号
     */
    private String bizSeqNo;
    /**
     * 接口请求的时间
     */
    private String transactionTime;

    private String oriCode;
    /**
     * 订单编号
     */
    private String orderNo;
    /**
     * 此次刷脸用户标识-pc端
     */
    private String h5faceId;
    /**
     * 此次刷脸用户标识-移动端
     */
    private String faceId;
    /**
     * 启动 H5 人脸核身步骤中调用 login 接口使用的域名
     */
    private String optimalDomain;
    /**
     * 请求是否成功
     */
    private Boolean success;
}
SiginTicket


import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class SiginTicket {
    //ticket_string
    private String value;
    // 有效时间/秒
    private String expire_in;
    //截至过期时间
    private String expire_time;
}
SiginTicketEntity


import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

@Setter
@Getter
public class SiginTicketEntity  {
    /**
     * 0:成功
     * 非0:失败
     */
    private String code;
    /**
     * 请求结果描述
     */
    private String msg;
    /**
     * 调用接口的时间
     */
    private String transactionTime;

    private String bizSeqNo;

    private List<SiginTicket> tickets  = new ArrayList<>();
}

service层

 @Override
    public String facialNuclearBody(FaceDetectUserVO faceDetectUserVO) throws Exception {
        try {
            String orderNo = FacialTools.randomAlphanumeric();//获取32位随机数
            String userId = FacialTools.userId;
            String nonce = FacialTools.randomAlphanumeric();//获取32位随机数
            String name = faceDetectUserVO.getName();
            String idCard = faceDetectUserVO.getIdNo();
            String from = "browser";
            //1、获取 access_token
            String accessToken = FacialTools.getAccessToken();
            //2、获取 sign_ticket
            String signTicket = FacialTools.getSignTicket(accessToken);
            //3、生成 sign_ticket 签名
            String ticketSign = FacialTools.getSignTicketSign(userId,signTicket,nonce);
            //4、调用AdvFaceId接口---获取 faceId
            FaceidRsultEntity faceidRsultEntity = FacialTools.getAdvFaceId(orderNo, name, idCard, userId, ticketSign, nonce);
            String faceId = faceidRsultEntity.getResult().getFaceId();//移动端faceId
            String optimalDomain = faceidRsultEntity.getResult().getOptimalDomain()==null?"kyc.qcloud.com":faceidRsultEntity.getResult().getOptimalDomain();//获取域名
            //5、获取nonce_ticket签名
            SiginTicketEntity siginTicketEntity = FacialTools.getNonceTicket(accessToken,userId);
            String noceTicketSign = siginTicketEntity.getTickets().get(0).getValue();
            //6、 生成Nonce签名---sign
            String nonceSign = FacialTools.getNonceTicketSign(orderNo,userId,faceId,noceTicketSign,nonce);//nonce签名
            //7. 生成“启动H5人脸核身”链接
            String returnUrl = faceDetectUserVO.getReturnUrl();
            String sendUrl = URLEncoder.encode(returnUrl);
            String facialUrl = FacialTools.getLoginUrl(optimalDomain,nonce,orderNo,faceId,sendUrl,"",userId,nonceSign,from,"");


            return facialUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值