1、下載大華官方設備網絡sdk_java64,地址:https://www.dahuatech.com/service/downloadlists/836.html
2、sdk里面有例子,盡量使用大華封裝好的東西,獲取門禁卡記錄用到了如下java類:
com/netsdk/lib
NetSDKLib.java
ToolKits.java
Utils.java
com/netsdk/demo/module
LoginModule.java
本以為com.netsdk.demo.module.GateModule.java里面會有現成的獲取門禁刷卡記錄的實現方法,可惜沒有。比葫蘆畫瓢,自己寫了一個。
3、在自己的spring boot項目中引入libs/jna.jar。
com/netsdk/lib
NetSDKLib.java
ToolKits.java
Utils.java
com/netsdk/demo/module
LoginModule.java
本以為com.netsdk.demo.module.GateModule.java里面會有現成的獲取門禁刷卡記錄的實現方法,可惜沒有。比葫蘆畫瓢,自己寫了一個。
3、在自己的spring boot項目中引入libs/jna.jar。
<dependency>
<groupId>com.dahua</groupId>
<artifactId>jna</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jna.jar</systemPath>
</dependency>
<groupId>com.dahua</groupId>
<artifactId>jna</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jna.jar</systemPath>
</dependency>
libs/win64下的dll文件是大華的類庫,運行時要讀取,在Utils.java中有讀取的方法,
可以按照里面的路徑存放於自己項目對應的路徑。我的是spring boot項目,就把libs放在了啟動工程的src文件夾的同級文件夾。
len-web
-src
-libs
-win64
可以按照里面的路徑存放於自己項目對應的路徑。我的是spring boot項目,就把libs放在了啟動工程的src文件夾的同級文件夾。
len-web
-src
-libs
-win64
4、大華的坑:文檔和類的注釋中,都寫明可以通過時間段來檢索門禁刷卡記錄,但是有的門禁設備不支持,只會把所有記錄全都給你;
注意LoginModule中的初始化方法init,對於javaweb項目來講,在服務啟動時,初始化一次就行了,后面直接調用登錄、登出方法即可,
千萬不要多次調用init方法,這樣java內存會爆掉,我開始就是這樣干的(郁悶)……還有就是刷卡記錄的時間不是北京時間,而是0時區
時間,所以獲取到以后要加8個小時才是北京時間。
注意LoginModule中的初始化方法init,對於javaweb項目來講,在服務啟動時,初始化一次就行了,后面直接調用登錄、登出方法即可,
千萬不要多次調用init方法,這樣java內存會爆掉,我開始就是這樣干的(郁悶)……還有就是刷卡記錄的時間不是北京時間,而是0時區
時間,所以獲取到以后要加8個小時才是北京時間。
5、用maven打包時,如果漏掉了jna.jar,就在pom.xml中的spring-boot-maven-plugin加上<includeSystemScope>true</includeSystemScope>
內容如下:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
內容如下:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
6、GateModule.java代碼
package com.dahua.module;
import com.dahua.lib.NetSDKLib;
import com.dahua.lib.ToolKits;
import com.sun.jna.Memory;
import com.dahua.lib.ToolKits;
import com.sun.jna.Memory;
public class GateModule {
/**
* 查詢刷卡記錄,獲取查詢句柄
* @param findCondition 查詢條件
* @return
*/
public static NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] findRecords(NetSDKLib.NET_TIME startTime, NetSDKLib.NET_TIME endTime) {
// 接口入參
NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX findCondition = new NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX();
findCondition.bCardNoEnable = 0;
findCondition.stStartTime = startTime;
findCondition.stEndTime = endTime;
// CLIENT_FindRecord 接口入參
NetSDKLib.NET_IN_FIND_RECORD_PARAM stIn = new NetSDKLib.NET_IN_FIND_RECORD_PARAM();
stIn.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARDREC_EX;
stIn.pQueryCondition = findCondition.getPointer();
// CLIENT_FindRecord 接口出參
NetSDKLib.NET_OUT_FIND_RECORD_PARAM stOut = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM();
/**
* 查詢刷卡記錄,獲取查詢句柄
* @param findCondition 查詢條件
* @return
*/
public static NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] findRecords(NetSDKLib.NET_TIME startTime, NetSDKLib.NET_TIME endTime) {
// 接口入參
NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX findCondition = new NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX();
findCondition.bCardNoEnable = 0;
findCondition.stStartTime = startTime;
findCondition.stEndTime = endTime;
// CLIENT_FindRecord 接口入參
NetSDKLib.NET_IN_FIND_RECORD_PARAM stIn = new NetSDKLib.NET_IN_FIND_RECORD_PARAM();
stIn.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARDREC_EX;
stIn.pQueryCondition = findCondition.getPointer();
// CLIENT_FindRecord 接口出參
NetSDKLib.NET_OUT_FIND_RECORD_PARAM stOut = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM();
findCondition.write();
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecordEx = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[0];
// 獲取查詢句柄
if(LoginModule.netsdk.CLIENT_FindRecord(LoginModule.m_hLoginHandle, stIn, stOut, 5000)) {
findCondition.read();
// 用於申請內存,假定2000次刷卡記錄
int nFindCount = 2000;
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecord = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[nFindCount];
for(int i = 0; i < nFindCount; i++) {
pstRecord[i] = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC();
}
NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM stNextIn = new NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM();
stNextIn.lFindeHandle = stOut.lFindeHandle;
stNextIn.nFileCount = nFindCount;
NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM stNextOut = new NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM();
stNextOut.nMaxRecordNum = nFindCount;
// 申請內存
stNextOut.pRecordList = new Memory(pstRecord[0].dwSize * nFindCount);
stNextOut.pRecordList.clear(pstRecord[0].dwSize * nFindCount);
// 將數組內存拷貝給指針
ToolKits.SetStructArrToPointerData(pstRecord, stNextOut.pRecordList);
if(LoginModule.netsdk.CLIENT_FindNextRecord(stNextIn, stNextOut, 5000)) {
if(stNextOut.nRetRecordNum == 0) {
return pstRecordEx;
}
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecordEx = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[0];
// 獲取查詢句柄
if(LoginModule.netsdk.CLIENT_FindRecord(LoginModule.m_hLoginHandle, stIn, stOut, 5000)) {
findCondition.read();
// 用於申請內存,假定2000次刷卡記錄
int nFindCount = 2000;
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecord = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[nFindCount];
for(int i = 0; i < nFindCount; i++) {
pstRecord[i] = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC();
}
NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM stNextIn = new NetSDKLib.NET_IN_FIND_NEXT_RECORD_PARAM();
stNextIn.lFindeHandle = stOut.lFindeHandle;
stNextIn.nFileCount = nFindCount;
NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM stNextOut = new NetSDKLib.NET_OUT_FIND_NEXT_RECORD_PARAM();
stNextOut.nMaxRecordNum = nFindCount;
// 申請內存
stNextOut.pRecordList = new Memory(pstRecord[0].dwSize * nFindCount);
stNextOut.pRecordList.clear(pstRecord[0].dwSize * nFindCount);
// 將數組內存拷貝給指針
ToolKits.SetStructArrToPointerData(pstRecord, stNextOut.pRecordList);
if(LoginModule.netsdk.CLIENT_FindNextRecord(stNextIn, stNextOut, 5000)) {
if(stNextOut.nRetRecordNum == 0) {
return pstRecordEx;
}
// 獲取卡信息
ToolKits.GetPointerDataToStructArr(stNextOut.pRecordList, pstRecord);
// 獲取有用的信息
pstRecordEx = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[stNextOut.nRetRecordNum];
for(int i = 0; i < stNextOut.nRetRecordNum; i++) {
pstRecordEx[i] = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC();
pstRecordEx[i] = pstRecord[i];
}
}
LoginModule.netsdk.CLIENT_FindRecordClose(stOut.lFindeHandle);
}
return pstRecordEx;
}
}
ToolKits.GetPointerDataToStructArr(stNextOut.pRecordList, pstRecord);
// 獲取有用的信息
pstRecordEx = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[stNextOut.nRetRecordNum];
for(int i = 0; i < stNextOut.nRetRecordNum; i++) {
pstRecordEx[i] = new NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC();
pstRecordEx[i] = pstRecord[i];
}
}
LoginModule.netsdk.CLIENT_FindRecordClose(stOut.lFindeHandle);
}
return pstRecordEx;
}
}
7、調用方式
boolean flag = LoginModule.login(hall.getGateIp(), 37777, "admin", "123456");
if (flag) {
// 檢索結束時間:當前時間
Date endDateTime = calendar.getTime();
NetSDKLib.NET_TIME endTime = new NetSDKLib.NET_TIME();
endTime.setTime(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
// 獲取檢索開始時間:當前時間 - 5分鍾
calendar.add(Calendar.MINUTE, -5);
Date startDateTime = calendar.getTime();
NetSDKLib.NET_TIME startTime = new NetSDKLib.NET_TIME();
startTime.setTime(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] cardRecords = GateModule.findRecords(startTime, endTime);
for (NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC cardRecord : cardRecords) {
// 卡號
String cardNo = new String(cardRecord.szCardNo).trim();
// 如果刷卡狀態不正確,或者是按鍵開門,就不錄入數據
if (cardRecord.bStatus != 1 || "00000000".equals(cardNo)) {
continue;
}
// 刷卡時間 轉換為北京時間 +8小時
Date stuTime = DateUtil.convertStringToDate(cardRecord.stuTime.toStringTimeEx(), "yyyy-MM-dd HH:mm:ss");
Calendar stuCalendar = DateUtil.getCalendar(stuTime);
stuCalendar.add(Calendar.HOUR, 8);
}
}
boolean flag = LoginModule.login(hall.getGateIp(), 37777, "admin", "123456");
if (flag) {
// 檢索結束時間:當前時間
Date endDateTime = calendar.getTime();
NetSDKLib.NET_TIME endTime = new NetSDKLib.NET_TIME();
endTime.setTime(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
// 獲取檢索開始時間:當前時間 - 5分鍾
calendar.add(Calendar.MINUTE, -5);
Date startDateTime = calendar.getTime();
NetSDKLib.NET_TIME startTime = new NetSDKLib.NET_TIME();
startTime.setTime(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] cardRecords = GateModule.findRecords(startTime, endTime);
for (NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC cardRecord : cardRecords) {
// 卡號
String cardNo = new String(cardRecord.szCardNo).trim();
// 如果刷卡狀態不正確,或者是按鍵開門,就不錄入數據
if (cardRecord.bStatus != 1 || "00000000".equals(cardNo)) {
continue;
}
// 刷卡時間 轉換為北京時間 +8小時
Date stuTime = DateUtil.convertStringToDate(cardRecord.stuTime.toStringTimeEx(), "yyyy-MM-dd HH:mm:ss");
Calendar stuCalendar = DateUtil.getCalendar(stuTime);
stuCalendar.add(Calendar.HOUR, 8);
}
}