人脸检测与分析和接口鉴权
--来自腾讯al开放平台
代码中用到的方法会在文末给出
人脸检测与分析文档地址:https://ai.qq.com/doc/detectface.shtml
分为两步,1接口鉴权,2调用人脸检测与分析接口,接口鉴权这步有坑,文档上的示例代码是PHP,上面多传了一个参数,去掉即可正常访问(搞到半夜人都要疯了,偶然也是才发现)
接口鉴权代码
-注意不同的接口接口鉴权的参数是不一样的
TreeMap<String, Object> param = new TreeMap<>();
param.put("time_stamp", System.currentTimeMillis()/1000);
param.put("nonce_str", new Random().nextInt(Integer.MAX_VALUE));
param.put("image", Base64Util.requestUrlToBase64(imagePath));
param.put("mode", "0");
param.put("app_id", appID);
//得到Authorization
String sign = Sign.getSign(param, appKey);// sign 就是我们要的参数了import java.math.BigInteger; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.TreeMap; public class Sign { public static String getSign(TreeMap<String, Object> param, String appKey) throws Exception { StringBuffer str = new StringBuffer(""); for (String k : param.keySet()) { str.append(k).append("=").append(URLEncoder.encode(param.get(k).toString(),"UTF-8")).append("&"); } str.append("app_key=").append(appKey); System.out.println(str); return (md5(str.toString())).toUpperCase(); } /** * 使用md5的算法进行加密 */ public static String md5(String plainText) { byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字 // 如果生成数字未满32位,需要前面补0 int mixNum = 32 - md5code.length(); for (int i = 0; i < mixNum; i++) { md5code = "0" + md5code; } return md5code.toUpperCase(); } }
调用人脸检测与分析接口
/** * 人脸检测与分析 * @param imagePath 图片路径 * appID appKey 可登陆自己的账号查看 image是原始图片的base64编码数据 * @return * @throws Exception */ public static String getDetectFace(String imagePath, String appID, String appKey) throws Exception{ TreeMap<String, Object> param = new TreeMap<>(); param.put("time_stamp", System.currentTimeMillis()/1000); param.put("nonce_str", new Random().nextInt(Integer.MAX_VALUE)); param.put("image", Base64Util.requestUrlToBase64(imagePath)); param.put("mode", "0"); param.put("app_id", appID); //得到Authorization String sign = Sign.getSign(param, appKey); param.put("sign", sign); System.out.println(sign); String result = HttpUtil.httpPost(DETECTFACE_URL, param); return result; }
腾讯云-实名核身-活体人脸核身
--开始用的上一个方法做的,后来客户感觉效果不太好,又做了腾讯云活体人脸核身,
l流程,app打开相机,面部动态识别(鉴权、调腾讯api),后台调用结果查询(腾讯api)获取相关信息入库
参数文档:https://cloud.tencent.com/document/product/1007/31320
鉴权操作与获取获取实名核身结果信息
/** * getBizToken * @return * @throws Exception */ public static String getBizToken(String secretId, String secretKey) { try { Credential cred = new Credential(secretId, secretKey); HttpProfile httpProfile = new HttpProfile(); httpProfile.setEndpoint("faceid.tencentcloudapi.com"); ClientProfile clientProfile = new ClientProfile(); clientProfile.setHttpProfile(httpProfile); FaceidClient client = new FaceidClient(cred, "ap-shanghai", clientProfile); String params = "{\"RuleId\":\"0\"}"; DetectAuthRequest req = DetectAuthRequest.fromJsonString(params, DetectAuthRequest.class); DetectAuthResponse resp = client.DetectAuth(req); // return DetectAuthRequest.toJsonString(resp); return resp.getBizToken(); } catch (TencentCloudSDKException e) { e.printStackTrace(); return null; } } /** * 获取实名核身结果信息 此处的bizToken,为app人脸识别成功后的bizToken,不是上个方法里的,bizToken不对的话会报异常 * @return * @throws Exception */ public static String getDetectInfo(String secretId, String secretKey, String bizToken) { try{ Credential cred = new Credential(secretId, secretKey); HttpProfile httpProfile = new HttpProfile(); httpProfile.setEndpoint("faceid.tencentcloudapi.com"); ClientProfile clientProfile = new ClientProfile(); clientProfile.setHttpProfile(httpProfile); FaceidClient client = new FaceidClient(cred, "ap-shanghai", clientProfile); String params = "{\"BizToken\":\"bizToken\",\"InfoType\":\"0\",\"RuleId\":\"0\"}".replace("bizToken", bizToken); GetDetectInfoRequest req = GetDetectInfoRequest.fromJsonString(params, GetDetectInfoRequest.class); GetDetectInfoResponse resp = client.GetDetectInfo(req); return resp.getDetectInfo(); } catch (TencentCloudSDKException e) { e.printStackTrace(); return null; } }
maven依赖
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.6</version>
</dependency>
||||||下面是代码中用到的方法|||||||
图片转换成Base64编码,详情可参考另一篇:
Java 图片与Base64字符串互相转换 :https://blog.csdn.net/qq_44695727/article/details/104597390
/**
* 将网络图片转换成Base64编码
*
* @param imgUrl 网络图片地址
* @return
*/
public static String requestUrlToBase64(String imgUrl) {
String result = null;
HttpURLConnection connection = null;
try {
URL url = new URL(imgUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 获取请求输入流
InputStream inputStream = connection.getInputStream();
// inputStream流数据转ByteArrayOutputStream
int len = -1;
byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
// ByteArrayOutputStream编码成base64字符串
result = new String(java.util.Base64.getEncoder().encode(out.toByteArray()));
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(connection != null){
connection.disconnect();
}
}
return result;
}
发送http请求
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
/**
* http 工具类
*/
public class HttpUtil {
protected static final Log LOGGER = LogFactory.getLog(HttpUtil.class);
public static String doHttpPost(String url, String data) throws NoSuchAlgorithmException, KeyManagementException, IOException {
String response = null;
try {
CloseableHttpClient httpclient = null;
CloseableHttpResponse httpresponse = null;
try {
httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost(url);
StringEntity stringentity = new StringEntity(data,
ContentType.create("text/json", "UTF-8"));
httppost.setEntity(stringentity);
httpresponse = httpclient.execute(httppost);
response = EntityUtils
.toString(httpresponse.getEntity());
} finally {
if (httpclient != null) {
httpclient.close();
}
if (httpresponse != null) {
httpresponse.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
public static final ContentType TEXT_PLAIN = ContentType.create("text/plain", StandardCharsets.UTF_8);
/**
* HttpClient 连接池
*/
private static PoolingHttpClientConnectionManager cm = null;
static {
// 初始化连接池,可用于请求HTTP/HTTPS(信任所有证书)
cm = new PoolingHttpClientConnectionManager(getRegistry());
// 整个连接池最大连接数
cm.setMaxTotal(200);
// 每路由最大连接数,默认值是2
cm.setDefaultMaxPerRoute(5);
}
/**
* 发送 HTTP POST请求
* <p>带请求参数,不带请求头</p>
*
* @param url 地址
* @param params 参数
* @return
* @throws Exception
*/
public static String httpPost(String url, Map<String, Object> params) throws Exception {
// 转换请求参数
List<NameValuePair> pairs = covertParams2NVPS(params);
HttpPost httpPost = new HttpPost(url);
// 设置请求参数
httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8.name()));
return doHttp(httpPost);
}
/**
* 发送 HTTP 请求
*
* @param request
* @return
* @throws Exception
*/
private static String doHttp(HttpRequestBase request) throws Exception {
// 通过连接池获取连接对象
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
return doRequest(httpClient, request);
}
/**
* 处理Http/Https请求,并返回请求结果
* <p>注:默认请求编码方式 UTF-8</p>
*
* @param httpClient
* @param request
* @return
* @throws Exception
*/
private static String doRequest(CloseableHttpClient httpClient, HttpRequestBase request) throws Exception {
String result = null;
CloseableHttpResponse response = null;
try {
// 获取请求结果
response = httpClient.execute(request);
// 解析请求结果
HttpEntity entity = response.getEntity();
// 转换结果
result = EntityUtils.toString(entity, StandardCharsets.UTF_8.name());
// 关闭IO流
EntityUtils.consume(entity);
} finally {
if (null != response){
response.close();}
}
return result;
}
/**
* 转换请求参数
*
* @param params
* @return
*/
public static List<NameValuePair> covertParams2NVPS(Map<String, Object> params) {
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for (Map.Entry<String, Object> param : params.entrySet()){
pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue())));}
return pairs;
}
/**
* 获取 HTTPClient注册器
*
* @return
* @throws Exception
*/
private static Registry<ConnectionSocketFactory> getRegistry() {
Registry<ConnectionSocketFactory> registry = null;
try {
registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()).register("https", getSSLFactory()).build();
} catch (Exception e) {
// Log.error("获取 HTTPClient注册器失败", e);
}
return registry;
}
/**
* 获取HTTPS SSL连接工厂
* <p>跳过证书校验,即信任所有证书</p>
*
* @return
* @throws Exception
*/
private static SSLConnectionSocketFactory getSSLFactory() throws Exception {
// 设置HTTPS SSL证书信息,跳过证书校验,即信任所有证书请求HTTPS
SSLContextBuilder sslBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
});
// 获取HTTPS SSL证书连接上下文
SSLContext sslContext = sslBuilder.build();
// 获取HTTPS连接工厂
SSLConnectionSocketFactory sslCsf = new SSLConnectionSocketFactory(sslContext, new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
return sslCsf;
}
}