海康ISAPI 添加用户信息和下发人脸
ISAPI添加用户信息方式比SDK简单。
文中添加人脸采用的是URL方式。就是可网络访问的人脸URL。
例如:http://192.168.1.33:6000/sysFileInfo/download?id=123465
也可以通过二进制方式下发,目前还没有探讨。
有用ISAPI 通过二进制方式下发人脸的朋友麻烦把代码贴一下,谢谢。
/**
* 海康ISAPI请求URL
*/
public class IotIsapiUrlConstant {
/**
* 添加人员信息
* post
*/
public static final String ADD_USER_INFO = "/ISAPI/AccessControl/UserInfo/Record?format=json";
/**
* 添加人脸数据
* post
*/
public static final String ADD_USER_FACE = "/ISAPI/Intelligent/FDLib/FaceDataRecord?format=json";
/**
* 修改人脸数据
*/
public static final String EDIT_USER_FACE = "/ISAPI/Intelligent/FDLib/FDModify?format=json";
/**
* 添加或修改人脸数据
* put
*/
public static final String FDSETUP_USER_FACE = "/ISAPI/Intelligent/FDLib/FDSetUp?format=json";
/**
* 添加或修改人员数据
* put
*/
public static final String SETUP_USER_INFO= "/ISAPI/AccessControl/UserInfo/SetUp?format=json";
/**
* 上传人脸照片
*/
public static final String UPLOAD_STORAGE_CLOUD = "/ISAPI/Intelligent/uploadStorageCloud?format=json";
/**
* 删除人员信息
*/
public static final String DEL_USER_INFO = "/ISAPI/AccessControl/UserInfo/Delete?format=json";
/**
* 查询人员信息
*/
public static final String QUER_USER_INFO = "/ISAPI/AccessControl/UserInfo/Search?format=json";
/**
* 修改人员信息
*/
public static final String MODIFY_USER_INFO = "/ISAPI/AccessControl/UserInfo/Modify?format=json";
/**
* 获取人员权限计划模板参数配置能力
*/
public static final String USER_RIGHTPLAN_TEMPLATE = "/ISAPI/AccessControl/UserRightPlanTemplate/capabilities?format=json";
/**
* 人员权限计划模板
* 模板编号,从1开始,设备支持的最大值从能力集中获取
*/
public static String allocationUserRightPlanTemplate(String planTemplateID){
return "/ISAPI/AccessControl/UserRightPlanTemplate/"+planTemplateID+"?format=json";
}
/**
* 员权限周计划
* 周计划编号,从1开始,设备支持的最大值从能力集中获取
* 128
*/
public static String allocationUserRightWeekPlanCfg(int weekPlanID){
return "/ISAPI/AccessControl/UserRightWeekPlanCfg/"+weekPlanID+"?format=json";
}
/**
* 查询人员数量
*/
public static final String GET_USER_COUNT= "/ISAPI/AccessControl/UserInfo/Count?format=json";
}
IotCameraParam
设备信息
@Getter
@Setter
public class IotCameraParam {
/**
* 设备id
*/
private Long deviceId;
/**
* 摄像机ip
*/
private String ip;
/**
* 摄像机端口
*/
private Integer port;
/**
* 摄像机登录用户名
*/
private String username;
/**
* 摄像机登录密码
*/
private String password;
/**
* 摄像机厂家
*/
private String supplier;
}
IotAddFaceParam
用户信息
@Getter
@Setter
public class IotAddFaceParam {
/**
* 用户id
*/
private Long userId;
/**
* 用户名
*/
private String userName;
/**
* 性别
*/
private String sex;
/**
* 人脸图片
* base64
*/
// private String faceImage;
/**
* 人员身份证号
*/
private String idCard;
/**
* 图片URL
* 人脸图片URL
* http://192.168.1.33:6000/sysFileInfo/download?id=123456
*/
private String faceUrl;
/**
* 用户类型(教职工、学生、家长)
*/
private String userType;
}
IotCommDataResult
返回结果
/**
* 返回消息
*
* @author czm
* @date 2022/8/12
*/
@Data
public class IotCommDataResult {
public static final Integer SUCCESS_CODE = 200;
public static final String SUCCESS_MSG = "操作成功";
public static final Integer FAIL_CODE = 500;
public static final String FAIL_MSG = "操作失败";
public static final String USER_NOT_MSG = "用户不存在";
/**
* id
*/
private Long id;
/**
* 编码
* 500 异常
* 200 成功
*/
private int code;
/**
* 错误提示
*/
private String msg;
/**
* 判断请求是否成功
*/
public boolean isSuccess() {
return Objects.equals(SUCCESS_CODE, this.getCode());
}
public static IotCommDataResult SUCCESS_RESULT(Long id) {
IotCommDataResult result = new IotCommDataResult();
result.setId(id);
result.setCode(SUCCESS_CODE);
result.setMsg(SUCCESS_MSG);
return result;
}
public static IotCommDataResult SUCCESS_RESULT() {
IotCommDataResult result = new IotCommDataResult();
result.setCode(SUCCESS_CODE);
return result;
}
public static IotCommDataResult FAIL_RESULT(Long id) {
IotCommDataResult result = new IotCommDataResult();
result.setId(id);
result.setCode(FAIL_CODE);
result.setMsg(FAIL_MSG);
return result;
}
public static IotCommDataResult FAIL_RESULT() {
IotCommDataResult result = new IotCommDataResult();
result.setCode(FAIL_CODE);
result.setMsg(FAIL_MSG);
return result;
}
public static IotCommDataResult COMMON_FAIL_RESULT(Long id, String msg) {
IotCommDataResult result = new IotCommDataResult();
result.setId(id);
result.setCode(FAIL_CODE);
result.setMsg(msg);
return result;
}
public static IotCommDataResult COMMON_SUCCESS_RESULT(Long id, String msg) {
IotCommDataResult result = new IotCommDataResult();
result.setId(id);
result.setCode(SUCCESS_CODE);
result.setMsg(msg);
return result;
}
}
IotUserInfo
人员信息
/**
* req, object, 人员信息
*/
@Getter
@Setter
public class IotUserInfo {
/**req, string, 工号, range:[1,32]*/
private String employeeNo;
/**opt, string, 姓名, range:[,]*/
private String name;
/**req, enum, 人员类型, subType:string, [normal#普通人(主人),visitor#来宾(访客),blackList#非授权名单人,maintenance#维护人员(包括保洁、维修人员
等),patient#病患,custom1#自定义人员类型1,custom2#自定义人员类型2,custom3#自定义人员类型3,custom4#自定义人员类型4,custom5#自定义人员类型5], desc:维护人员需要
在任意时间都能进入房间*/
private String userType;
/**opt, string, 所属群组 "1,3,5",*/
private String belongGroup;
/**opt, string, 门权限 "1,3"*/
private String doorRight;
/**opt, enum, 人脸图片对应的人员性别, subType:string, [male#男,female#女,unknown#未知]*/
private String gender;
/**
* 人员有效期
*/
private IotValid Valid;
/**
* 门权限计划(锁权限计划)
*/
private List<IotRightPlan> RightPlan;
}
人员有效期
/**
* 人员有效期
*
*/
@Getter
@Setter
public class IotValid {
/**req, bool, 使能有效期, desc:1、enable为true,表示人员非长期有效,且beginTime必须严格小于endTme;2、enable为false,表示人员长期有效,这个时候上
层仍然需要下发beginTime和endTime,设备也需要校验beginTime和endTime的合法性。*/
private boolean enable;
/**req, datetime, 有效期起始时间, desc:timeType字段不存在或为local时,beginTime为设备本地时间,如:2017-08-01T17:30:08;timeType字段为UTC
时,beginTime为UTC时间,如:2017-08-01T17:30:08+08:00*/
private Date beginTime;
/**req, datetime, 有效期结束时间, desc:timeType字段不存在或为local时,beginTime为设备本地时间,如:2017-08-01T17:30:08;timeType字段为UTC
时,beginTime为UTC时间,如:2017-08-01T17:30:08+08:00*/
private Date endTime;
/**opt, enum, 时间类型, subType:string, [local#设备本地时间,UTC#UTC时间]*/
private String timeType;
}
门禁权限计划
/**
* opt, array, 门权限计划(锁权限计划), subType:object
*/
@Getter
@Setter
public class IotRightPlan {
/**opt, int, 门编号(锁ID)*/
private int doorNo;
/**opt, string, 计划模板编号, desc:同个门不同计划模板采用权限“或的”方式处理,默认无计划模板编号。
* 65535-7*24小时生效,65534-周一到周五24小时生效,65533-周六周日24小时生效
* "1,3,5"
* */
private String planTemplateNo;
}
IotUserInfoParam
/**
* req, object, 人员信息
*/
@Getter
@Setter
public class IotUserInfoParam {
private IotUserInfo UserInfo;
}
HttpClientUtil
请求工具类
@Slf4j
public class HttpClientUtil {
public static CloseableHttpClient httpUsernamePassword(String username, String password) {
Credentials creds = new UsernamePasswordCredentials(username, password);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, creds);
return HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
}
/**
* get 请求
*
* @param username 账号
* @param password 密码
* @param isapiUrl URL
* @return
*/
public static String getHttpIsapi(String username, String password, String isapiUrl) {
HttpGet httpGet = new HttpGet(isapiUrl);
CloseableHttpClient httpclient = httpUsernamePassword(username, password);
try {
HttpResponse response = httpclient.execute(httpGet);
return EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
log.error("调用接口失败", e);
}
return null;
}
/**
* post 请求
*
* @param username 账号
* @param password 密码
* @param isapiUrl URL
* @return
*/
public static String postHttpIsapi(String username, String password, String isapiUrl, String body) {
HttpPost httpPost = new HttpPost(isapiUrl);
CloseableHttpClient httpclient = httpUsernamePassword(username, password);
httpPost.setEntity(new StringEntity(body, "UTF-8"));
try {
HttpResponse response = httpclient.execute(httpPost);
return EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
log.error("调用接口失败", e);
}
return null;
}
/**
* put 请求
*
* @param username 账号
* @param password 密码
* @param isapiUrl URL
* @param putXml 参数 字符串
* @return
*/
public static String putHttpIsapi(String username, String password, String isapiUrl, String putXml) {
HttpPut httpPut = new HttpPut(isapiUrl);
CloseableHttpClient httpclient = httpUsernamePassword(username, password);
httpPut.setEntity(new StringEntity(putXml, "UTF-8"));
try {
HttpResponse response = httpclient.execute(httpPut);
return EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
log.error("调用接口失败", e);
}
return null;
}
public static String doPostModFacePicRecord(String username, String password, String url, String json, byte[] faceimage, String boundary) {
String respoon = "";
try {
CloseableHttpResponse response;
CloseableHttpClient httpsClient = httpUsernamePassword(username, password);
HttpPost method = new HttpPost(url);
method.addHeader("Accept-Language", "zh-CN");
method.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
method.addHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
method.addHeader("Accept-Encoding", "gzip, deflate");
method.addHeader("Connection", "Keep-Alive");
method.addHeader("Cache-Control", "no-cache");
String bodyParam =
"--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"FaceDataRecord\";\r\n"
+ "Content-Type: text/json\r\n"
+ "Content-Length: " + json.length() + "\r\n\r\n"
+ json + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"img\";\r\n"
+ "Content-Type: image/jpeg\r\n"
+ "Content-Length: " + faceimage.length + "\r\n\r\n"
+ faceimage
+ "\r\n--" + boundary + "--\r\n";
HttpEntity inboundInfoEntity = new StringEntity(bodyParam, "UTF-8");
method.setEntity(inboundInfoEntity);
response = httpsClient.execute(method);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
respoon = "error " + statusCode;
}
HttpEntity entity = response.getEntity();
if (entity == null) {
respoon = "error response is null";
}
respoon = EntityUtils.toString(entity, "utf-8");
// Release the connection
method.releaseConnection();
} catch (IOException e) {
log.error("添加人脸失败", e);
}
return respoon;
}
public static String doPutModFacePicRecord(String username, String password, String url, String json, byte[] faceimage, String boundary) {
String respon = "";
try {
CloseableHttpResponse response;
CloseableHttpClient httpsClient = httpUsernamePassword(username, password);
HttpPut method = new HttpPut(url);
method.addHeader("Accept", "text/html, application/xhtml+xml");
method.addHeader("Accept-Language", "zh-CN");
method.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
method.addHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
method.addHeader("Accept-Encoding", "gzip, deflate");
method.addHeader("Connection", "Keep-Alive");
method.addHeader("Cache-Control", "no-cache");
String bodyParam =
"--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"FaceDataRecord\";\r\n"
+ "Content-Type: text/json\r\n"
+ "Content-Length: " + json.length() + "\r\n\r\n"
+ json + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"img\";\r\n"
+ "Content-Type: image/jpeg\r\n"
+ "Content-Length: " + faceimage.length + "\r\n\r\n"
+ faceimage
+ "\r\n--" + boundary + "--\r\n";
HttpEntity inboundInfoEntity = new StringEntity(bodyParam, "UTF-8");
method.setEntity(inboundInfoEntity);
response = httpsClient.execute(method);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
respon = "error " + statusCode;
}
HttpEntity entity = response.getEntity();
if (entity == null) {
respon = "error response is null";
}
respon = EntityUtils.toString(entity, "utf-8");
// Release the connection
method.releaseConnection();
} catch (IOException e) {
log.error("添加人脸失败", e);
}
return respon;
}
}
添加用户信息
/**
* 添加用户信息
*
* @param camera
* @param param
* @return
*/
public IotCommDataResult addUserInfo(IotCameraParam camera, IotAddFaceParam param) {
IotUserInfo userInfo = new IotUserInfo();
userInfo.setName(param.getUserName());
userInfo.setGender(param.getSex());
userInfo.setBelongGroup("1");
userInfo.setDoorRight("1");
userInfo.setUserType("normal");
userInfo.setEmployeeNo(String.valueOf(param.getUserId()));
IotValid valid = new IotValid();
valid.setEnable(false);
valid.setBeginTime(DateUtil.date());
valid.setEndTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 50));
userInfo.setValid(valid);
//判断是否为教师。 教职工默认权限 如果不需要权限的可以去掉该代码
if(IotUserTypeEnum.TEACHER.getCode().equals(param.getUserType())){
IotRightPlan rightPlan = new IotRightPlan();
rightPlan.setDoorNo(1);
rightPlan.setPlanTemplateNo("1");
List<IotRightPlan> rightPlans = new ArrayList<>();
rightPlans.add(rightPlan);
userInfo.setRightPlan(rightPlans);
}
IotUserInfoParam userInfoParam = new IotUserInfoParam();
userInfoParam.setUserInfo(userInfo);
String url = HTTP + camera.getIp() + IotIsapiUrlConstant.SETUP_USER_INFO;
String addUserInfoRespoon = HttpClientUtil.putHttpIsapi(camera.getUsername(), camera.getPassword(), url, JSONUtil.toJsonStr(userInfoParam));
log.info("ISAPI addUser:{}", addUserInfoRespoon);
IotHkIsapiCommonResult isapiCommonResult = JSONUtil.toBean(addUserInfoRespoon, IotHkIsapiCommonResult.class);
IotCommDataResult commDataResult = new IotCommDataResult();
if (ObjectUtil.isNull(isapiCommonResult)) {
commDataResult.setId(param.getUserId());
commDataResult.setCode(500);
commDataResult.setMsg("未获取到响应信息");
}
commDataResult.setId(param.getUserId());
commDataResult.setCode(Objects.equals(isapiCommonResult.getSubStatusCode(), IotHkIsapiExceptionEnum.OK.getCode()) ? 200 : 500);
commDataResult.setMsg(IotHkIsapiExceptionEnum.getMsg(isapiCommonResult.getSubStatusCode()));
return commDataResult;
}
IotUserFaceParam
/**
*用户人脸信息
*/
@Getter
@Setter
public class IotUserFaceParam {
/**opt, string, 人脸url, desc:本字段和modelData字段二选一必填*/
private String faceURL;
/**req, enum, 人脸库类型, subType:string, [blackFD#名单库,staticFD#静态库],
* desc:人脸库类型: blackFD-名单库, staticFD-静态库, string类型, 最大长度为32*/
private String faceLibType;
/**req, string, 人脸库ID, range:[1,64]*/
private String FDID;
/**opt, string, 人脸记录ID, range:[1,64], desc:人脸记录ID(与非视频工号(人员ID)字段一致),对应门禁设备,业务上该字段为必填*/
private String FPID;
/**req, string, 人脸图片对应的人员姓名, desc:最大长度为96字节*/
private String name;
/**opt, enum, 人脸图片对应的人员性别, subType:string, [male#男,female#女,unknown#未知], desc:最大长度为32*/
private String gender;
/**opt, enum, 证件类型, subType:string,
[ID#身份证,officerID#军官证,other#其他,LawyerCertificate#律师证,
birthCertificate#出生证明,householdRegister#户口簿,judgeCertificate#法官证,studentIDCard#学生证,workCard#工作证,
policeID#警官证,foreignPermanentResidentIDCard#外国人永久居留身份证,passport#护照,pressCard#记者证,
prosecutorCard#检察官证,temporaryIDCard#临时身份证,temporaryResidencePermit#暂住证]
*/
private String certificateType;
/**opt, string, 证件号, range:[1,64], desc:由数字和字母 "0-9a-zA-Z"组成*/
private String certificateNumber;
/**opt, string, 备注信息, desc:string类型, 最大长度为192字节, {dep if type == blackFD}*/
private String caseInfo;
/**opt, string, 目标模型数据, desc:目标模型数据,字符串类型,传输过程中针对二进制非建模数据进行base64的加密处理;本字段和faceURL字段二选一必填*/
private String modelData;
}
添加用户人脸
/**
* 通过URL添加用户人脸
*
* @param camera
* @param param
* @return
*/
public IotCommDataResult addUserFaceUrl(IotCameraParam camera, IotAddFaceParam param) {
IotUserFaceParam userFaceParam = new IotUserFaceParam();
userFaceParam.setFDID("1");
userFaceParam.setFPID(String.valueOf(param.getUserId()));
userFaceParam.setFaceLibType("blackFD");
userFaceParam.setFaceURL(param.getFaceUrl());
String url = HTTP + camera.getIp() + IotIsapiUrlConstant.FDSETUP_USER_FACE;
String addUserFace = HttpClientUtil.putHttpIsapi(camera.getUsername(), camera.getPassword(), url, JSONUtil.toJsonStr(userFaceParam));
log.info("ISAPI addUser:{}", addUserFace);
IotHkIsapiCommonResult isapiCommonResult = JSONUtil.toBean(addUserFace, IotHkIsapiCommonResult.class);
IotCommDataResult commDataResult = new IotCommDataResult();
if (ObjectUtil.isNull(isapiCommonResult)) {
commDataResult.setId(param.getUserId());
commDataResult.setCode(500);
commDataResult.setMsg("未获取到响应信息");
} else {
commDataResult.setId(param.getUserId());
commDataResult.setCode(Objects.equals(isapiCommonResult.getSubStatusCode(), IotHkIsapiExceptionEnum.OK.getCode()) ? 200 : 500);
commDataResult.setMsg(IotHkIsapiExceptionEnum.getMsg(isapiCommonResult.getSubStatusCode()));
}
return commDataResult;
}