海康威视(HIKVISION) JAVA SDK 打包方法
- 问题
- 疑问
- 解决方法一
- 解决方法二
- 结语
问题
最近项目中需要调用海康的摄像头然后进行抓拍图片,由于使用的是 spring-boot
框架,然后将 DLL 动态链接库打包到 jar
包,导致 JNA
疑问
为什么在开发的时候可以加载到DLL,打包后就会获取不到?
经过检查,发现打包后,系统会将 jar
包当成一个文件,这时候我们使用 class
的 getResource()
就会获取不到DLL的绝对路径。这主要是因为jar包是一个单独的文件而非文件夹,绝对不可能通过 file:/e:/.../ResourceJar.jar/resource /res.txt
这种形式的文件URL来定位文件。所以即使是相对路径,也无法定位到jar
文件内的文件。我们不能用常规操作文件的方法来读取jar
中的资源文件。
可能这块的东西有些童鞋不太懂,可以去搜索相关的知识或者自己读取一个资源文件,打成 jar 包试试就明白了。
解决方法一
这时候就有办法了,那么获取不到怎么办,我们是不是可以将DLL放在 jar
包外面,然后给一个绝对路径,答案是可以的。
上图中 HCNetSDK
文件夹中放的是海康的DLL文件,hcnet-0.0.1-SNAPSHOT.jar
是项目的 jar
包。
还有一个问题,我们在部署的时候不知道运维人员到底会将项目部署到哪里,我们不能限定运维人员说必须部署到哪个盘哪个位置。这样的话,估计运维小伙伴会跟我们兵戎相见
。那么我们可以在运行的时候指定 JNA
的运行路径。
@echo off
TITLE 拍照服务
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_111
path path;C:\Program Files\Java\jdk1.8.0_111\bin
java -Dfile.encoding=UTF-8 -Djna.library.path=C:\cam -jar hcnet-0.0.1-SNAPSHOT.jar
pause
脚本中第二行是设置标题,第二行和第三行是设置运行的 JDK
环境。-Djna.library.path=C:\cam
是设置 JNA
的运行路径为 C:\cam
文件夹。这样我们在开发的时候 load
方法中直接写DLL的名称即可。
获取文件路径 DllLoad
类
import java.io.UnsupportedEncodingException;
public class DllLoad {
public static String DLL_PATH;
static {
String root = DllLoad.class.getResource("/").getPath();
if (root.startsWith("file:/")) { // jar包中获取到的路径
DLL_PATH = "";
} else { // 实际开发中获取到的路径不带 file:/
root = root.replaceAll("%20", " ").substring(1);
try {
DLL_PATH = java.net.URLDecoder.decode(root, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
在引用的地方使用:
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(DllLoad.DLL_PATH + "HCNetSDK\\Win32\\HCNetSDK",
HCNetSDK.class);
这样就解决了打 jar
后获取不到文件的尴尬情况。
解决方法二
这个方法很简单,直接打成 war
一了百了。spring-boot
如何打包成 war
网上有太多的文章,此处不在赘述。
结语
其实打成 war
包是我当初没研究成打成 jar
的方法,最后将项目上线后,自己也反思了,回去花了半晚上的时间研究了打成 jar
包的方法,如果哪位大神有更好的方法也可以借鉴。
最后说一些题外话吧,我觉得,干技术行业,没有钻研精神是不行的,而且当一个具有挑战性难题解决的时候,相信心中的成就感对于每一个干技术的都不言而喻。可能这个问题对于大神来说都是很简单的事情。说了这么多,还是希望大家读到我文章的兄弟们都能具有钻研解决问题的精神,人人都成为大佬。
Keep Calm And Make Epic Shit.