硬件设备(门禁人脸识别机)调试总结

 公司让我开发几个对接硬件设备(门禁人脸识别机)等,有多台不同型号的人脸识别机,每种型号需要参考不同的厂家协议,再开发过程中遇到了很多坑,故需要将这些坑提炼出来,避免以后继续踩坑,如下:
  1. 硬件设备需要配置访问服务器的心跳URL、上传考勤数据URL和拍照图片上传URL,设备是主动通过这三个接口请求,并带相关参数(协议上提供)访问以上三个URL,服务器在接收到请求后给以json格式的响应,其中心跳是具有一定时间间隔的,每个时间间隔会访问一次心跳URL,服务器在每次心跳过来时查询数据库,查找是否有需要下发的数据(即新增人员信息或删除人员信息)以协议上规定的格式下发给硬件设备,硬件设备根据下发的规定格式(JSON)的数据更新设备人员信息到设备数据库。当有人员门禁信息比如人员人脸发生识别时会产生门禁记录,则会主动调用设置的上传考勤数据URL访问服务器对应接口,然后将数据以协议上规定格式上传服务器,服务器接收数据后保存数据库对应表。
  2. 有些硬件设备会提供操作设备API,而这种API的请求分为form-data类型或application/x-www-form-urlencoded类型,其中form-data中的POST方式采用以下代码:
// 创建远程url连接对象
  URL url = new URL(strurl);
  // 通过远程url连接对象打开一个连接,强转成httpURLConnection类

  connection = (HttpURLConnection) url.openConnection();
  // 设置连接方式:GET,POST
  connection.setRequestMethod("POST");

  connection.setDoInput(true);
  connection.setDoOutput(true);

  connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
  //这里必须要写,否则出错
  connection.setRequestProperty("SOAPAction", "");


  // 设置连接主机服务器的超时时间:15000毫秒
  connection.setConnectTimeout(15000);
  // 设置读取远程返回的数据时间:60000毫秒
  connection.setReadTimeout(60000);

  // 发送请求
  connection.connect();
  out = connection.getOutputStream(); // 获取输出流对象
  connection.getOutputStream().write(param.getBytes("UTF-8")); // 将要提交服务器的SOAP请求字符流写入输出流
  out.flush();
  out.close();

  //System.out.println(connection.getResponseCode());

  // 通过connection连接,获取输入流
  if (connection.getResponseCode() == 200) {
      is = connection.getInputStream();
      // 封装输入流is,并指定字符集
      br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
      // 存放数据
      StringBuffer sbf = new StringBuffer();
      String temp = null;
      while ((temp = br.readLine()) != null) {
          sbf.append(temp);
          sbf.append("\r\n");
      }
      result = sbf.toString();
  }
  1. GET方式是不能在body里面带有数据的,不能有**connection.setDoOutput(true) **,故采用以下代码:
		HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;// 返回结果字符串
        OutputStream out = null;

        Date d1 = new Date();

        try {

            // 创建远程url连接对象
            URL url = new URL(strurl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类

            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:GET,POST
            connection.setRequestMethod("GET");

            connection.setDoInput(true);
//            connection.setDoOutput(true);

//            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            //这里必须要写,否则出错
//            connection.setRequestProperty("SOAPAction", "");


            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);

            // 发送请求
            connection.connect();
            //out = connection.getOutputStream(); // 获取输出流对象
            //connection.getOutputStream().write(param.getBytes("UTF-8")); // 将要提交服务器的SOAP请求字符流写入输出流
            //out.flush();
            //out.close();

            //System.out.println(connection.getResponseCode());

            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 封装输入流is,并指定字符集
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            connection.disconnect();// 关闭远程连接

        }
  1. 设备是人脸图片都是采用Base64位存储和解析人脸数据,包括三种方案:base64位图片下发,将图片上传到云服务器,然后传递url,或者前两种方式综合提供,设备拍照也是传递base64位字符串给后台,后台可以将其存储到数据库字段,代码如下:
ImgBase64.getImgStr(path+"static\\temp\\"+filename)

import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
 
import java.io.*;

public class ImgBase64 {
	/**
     * 将图片转换成Base64编码
     * @param imgFile 待处理图片
     * @return
     */
    public static String getImgStr(String imgFile) {
        // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
 
        InputStream in = null;
        byte[] data = null;
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64.encodeBase64String(data);
    }
 
    /**
     * 对字节数组字符串进行Base64解码并生成图片
     * @param imgStr 图片数据
     * @param imgFilePath 保存图片全路径地址
     * @return
     */
    public static boolean generateImage(String imgStr, String imgFilePath) {
        //
        if (imgStr == null) // 图像数据为空
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            // 生成jpg图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
# 数据库如果存储二进制数据,可以将二进制数据读出,并将其转换为临时图片文件存储到云服务器,然后转换为base64位字符串传递给用户
			byte[] data=(byte[]) map.get("fileblob");
            if(data.length>0) {
                InputStream in = new ByteArrayInputStream(data);
                //logger.info("filename--->"+filename);
                File p = new File(path+"static\\temp");
                if(!p.exists()){
                    p.mkdirs();
                }
                FileUtil.getFile(in,path+"static\\temp\\"+filename);
  1. 硬件设备调试可能出现各种未知错误,协议可能没写全,比如可能是图片清晰度不够、图片文件超过设备允许范围,各大参数是否必须,这些都需要重视将其设备返回信息打印出来,因为在客户那里是不允许上外网的,也不能现场调试,所以必须有足够多的日志信息输出,比如接口进入日志,接口传递参数,方法名和参数值调用,调用远程接口返回值一定要都打印出来,以便了解远程报错情况,可以通过AOP切面方式捕获服务接口和方法调用情况。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值