<!-- Java Native Access -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
创建接口加载该dll:
public interface SuctionCardReaderService extends Library{
SuctionCardReaderService Instance = Native.loadLibrary("ID81DLL", SuctionCardReaderService.class);
}
二代证电子信息结构体宏定义:
typedef struct IDInfo
{
char name[32]; //姓名
char sex[4]; //性别
char nation[12]; //民族
char birthday[20]; //出生日期
char address[72]; //住址信息
char number[40]; //身份证号码
char department[32];//签发机关
char timeLimit[36]; //有效日期
char Image[256]; //头像信息
}IDInfo;
创建相关实体类:
public class IDInfo extends Structure {
/**
* 姓名
*/
public byte[] name = new byte[32];
/**
* 性别
*/
public byte[] sex = new byte[4];
/**
* 民族
*/
public byte[] nation = new byte[12];
/**
* 出生日期
*/
public byte[] birthday = new byte[20];
/**
* 住址信息
*/
public byte[] address = new byte[72];
/**
* 身份证号码
*/
public byte[] number = new byte[40];
/**
* 签发机关
*/
public byte[] department = new byte[32];
/**
* 有效日期
*/
public byte[] timeLimit = new byte[36];
/**
* 头像信息
*/
public byte[] Image = new byte[256];
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"name", "sex", "nation", "birthday", "address", "number", "department", "timeLimit", "Image"});
}
}
设备信息结构体宏定义:
typedef struct ScannerInfoRec
{
unsigned DeviceID; //设备ID
}ScannerInfoRec;
创建相关实体类:
public class ScannerInfoRec extends Structure {
public int DeviceID;
@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"DeviceID"});
}
}
dll中相关方法定义:
枚举扫描设备USB内部ID号
int EnumScannerDevice(ScannerInfoRec *ScannerInfo, unsigned *DeviceNumber)
形式参数
ScannerInfo:[输出] 获取USB设备内部ID号的结构体,内部ID号取值范围0-16。
DeviceNumber:[输出] 枚举到的设备数量,不能为空。
打开设备
int OpenConnection(unsigned DeviceID)
形式参数
DeviceID:[输入] USB设备内部ID号,取值范围0-16。
读取当前图像数据块到内存
int SavePicToMemory(unsigned DeviceID, char* cFrontImgBuf,char* cRearImgBuf, int* iFrontLen, int* iRearLen)
形式参数
DeviceID:[输入] USB设备内部ID号,取值范围0-16。
cFrontImgBuf:[输出] 保存正面图像数据信息指针,不能为空。
cRearImgBuf:[输出] 保存反面图像数据信息指针,不能为空。
iFrontLen:[输出] 正面图像数据长度。
iRearLen:[输出] 反面图像数据长度。
获取二代证信息
int GetID2Info(unsigned DeviceID, IDInfo *mIDInfo, char *HeadImageName)
形式参数
DeviceID:[输入] USB设备内部ID号,取值范围0-16。
mIDInfo:[输出] 身份证信息结构体指针,不能为空。
HeadImageName:[输入] 图像名称,如果只传入路径则按照配置文件项HeadImgName动态名称[0-姓名+生日,1-身份证号]。
在接口中新建对应方法:
/**
* 枚举设备
* @param ScannerInfo
* @param DeviceNumber
* @return
*/
int EnumScannerDevice(ScannerInfoRec[] ScannerInfo, IntByReference DeviceNumber);
/**
* 打开设备
* @param DeviceID
* @return
*/
int OpenConnection(int DeviceID);
/**
* 读取当前图像数据块到内存
* @param DeviceID
* @return
*/
int SavePicToMemory(int DeviceID, Pointer cFrontImgBuf, Pointer cRearImgBuf, IntByReference iFrontLen, IntByReference iRearLen);
/**
* 获取身份证信息
* @param DeviceID
* @param mIDInfo
* @param HeadImageName
* @return
*/
int GetID2Info(int DeviceID, IDInfo mIDInfo, String HeadImageName);
调用接口
/**
* 获取二代证信息
*/
@GetMapping("/getPersonalInfo")
public ResponseEntity<PersonalInfo> getPersonalInfo() {
//设备ID
Integer deviceID = null;
PersonalInfo personalInfo = new PersonalInfo();
try {
//枚举设备获取设备ID
ScannerInfoRec[] deviceArray = (ScannerInfoRec[]) new ScannerInfoRec().toArray(1);
IntByReference deviceNumber = new IntByReference();
int enumScannerDevice = SuctionCardReaderService.Instance.EnumScannerDevice(deviceArray, deviceNumber);
if (enumScannerDevice == SuctionCardReaderService.IDDIGITALCOPIER_NO_ERROR && deviceNumber.getValue() > 0) {
for (ScannerInfoRec rec : deviceArray) {
deviceID = rec.DeviceID;
}
log.info("deviceID -- "+ deviceID);
//连接设备
int openConnection = SuctionCardReaderService.Instance.OpenConnection(deviceID);
log.info("openConnection -- "+ openConnection);
//获取身份证信息
IDInfo idInfo = new IDInfo();
int getID2Info = SuctionCardReaderService.Instance.GetID2Info(deviceID, idInfo, SuctionCardReaderService.HEAD_IMAGE_NAME);
log.info("getID2Info -- "+ getID2Info);
//获取个人信息成功
if (getID2Info == SuctionCardReaderService.IDDIGITALCOPIER_NO_ERROR) {
personalInfo.setName(StringUtils.replace(new String(idInfo.name), "\u0000", ""));
personalInfo.setNumber(StringUtils.replace(new String(idInfo.number), "\u0000", ""));
personalInfo.setAddress(StringUtils.replace(new String(idInfo.address), "\u0000", ""));
personalInfo.setBirthday(StringUtils.replace(new String(idInfo.birthday), "\u0000", ""));
personalInfo.setDepartment(StringUtils.replace(new String(idInfo.department), "\u0000", ""));
personalInfo.setNation(StringUtils.replace(new String(idInfo.nation), "\u0000", ""));
personalInfo.setSex(StringUtils.replace(new String(idInfo.sex), "\u0000", ""));
personalInfo.setTimeLimit(StringUtils.replace(new String(idInfo.timeLimit), "\u0000", ""));
personalInfo.setImage(Base64Utils.encodeToString(Files.readAllBytes(Paths.get(SuctionCardReaderService.HEAD_IMAGE_NAME))));
}
//读取当前图像数据块到内存
Pointer cFrontImgBuf = new Memory(16*1024*1024);
Pointer cRearImgBuf = new Memory(16*1024*1024);
IntByReference iFrontLen = new IntByReference();
IntByReference iRearLen = new IntByReference();
int savePicToMemory = SuctionCardReaderService.Instance.SavePicToMemory(deviceID, cFrontImgBuf, cRearImgBuf, iFrontLen, iRearLen);
log.info("savePicToMemory -- "+ savePicToMemory);
//保存身份证正反照照片
personalInfo.setImagePositive(Base64Utils.encodeToString(cFrontImgBuf.getByteArray(0, iFrontLen.getValue())));
personalInfo.setImageContrary(Base64Utils.encodeToString(cRearImgBuf.getByteArray(0, iRearLen.getValue())));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (deviceID == null) {
log.info("未找到设备.");
}
}
return ResponseEntity.ok(personalInfo);
}
注:
若需要把项目打包成jar运行,将dll文件至于jar包同目录,编辑start.bat文件 :start jre1.8.0_221/bin/java -Djna.library.path=./Lib -jar project.jar