Java调用外接设备详解(制卡机)

最近在开发的系统中,有一个接入外接设备制卡机更换,之前用的制卡机要重新采购,所以导致之前的调用接口方法无效,要用新的设备接口来进行调用。可是这个设备是外国进口过来的,资料很少。想要百度的话,网上资料都没有,中间经过了几天的摸索,最终还是弄了出来,所以把详细的分析及解决方法记录下来。

这个制卡机是打印磁卡/智能卡的,像我们常用的银行卡、饭卡、购物卡都可以用这个机器来进行设计并制卡,并最终发放给消费者使用。简要说下解决的思路吧,最开始拿到这个机器的时候,我是一头的雾水,也不知道从何下手,我当时最最简单的想法就是先把这个机器怎么使用,怎么操作,什么用途了解清楚,然后再谈接口代码啥的。但是找了半天,网上的资料也很少,也不知道怎么使用,最后看到机器上有一个二维码帮助的,扫了下,进入到了它们的官网,找到了相应的机器型号,然后的话看到了相应的使用说明和相应的视频教程,了解了一番,这才知道了产品正确的使用方法,所以拿到一个新玩意,想要快速了解它,最好的还是先去看他的说明书和官方教程。

知道了相应的使用方法,下面的操作也就很简单了。其实具体的原理方法也就是先使用软件设计出两张BMP的图片,一面是磁卡/智能卡的正面,一般的话都是张设计的好看的图片,另一张的话就是磁卡/智能卡的反面,然后图片的给相应的代码解析,读取,把信息写入到卡的磁条上,最后调用机器进行打印,用其中机器的墨纸写入到空白的卡片上就可以了。

但是一般人工都是机器自带的软件提前设计好图片,如果换做用代码驱动机器的话,那就要用代码要生成图片了。当然了,在JAVA中有相应的类来生成BMP格式的图片,然后调用相应的代码就可以了。

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;
import javax.swing.JTextArea;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.wonders.yksx.jdlk.web.util.ResponseUtil;
import com.wonders.yksx.salvation.web.action.SalvationActionParent;
import com.wonders.yksx.ylbk.web.form.MagEncodeContainer;
import com.wonders.yksx.ylbk.web.form.MagEncodeModel;
import com.wonders.yksx.ylbk.web.form.PrinterModel;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import com.zebra.sdk.common.card.containers.GraphicsInfo;
import com.zebra.sdk.common.card.containers.JobStatusInfo;
import com.zebra.sdk.common.card.enumerations.CardSide;
import com.zebra.sdk.common.card.enumerations.GraphicType;
import com.zebra.sdk.common.card.enumerations.OrientationType;
import com.zebra.sdk.common.card.enumerations.PrintType;
import com.zebra.sdk.common.card.exceptions.ZebraCardException;
import com.zebra.sdk.common.card.graphics.ZebraCardGraphics;
import com.zebra.sdk.common.card.graphics.ZebraGraphics;
import com.zebra.sdk.common.card.graphics.enumerations.RotationType;
import com.zebra.sdk.common.card.printer.ZebraCardPrinter;
import com.zebra.sdk.common.card.printer.ZebraCardPrinterFactory;
import com.zebra.sdk.device.ZebraIllegalArgumentException;
import com.zebra.sdk.printer.discovery.DiscoveredPrinter;
import com.zebra.sdk.printer.discovery.UsbDiscoverer;

public class MakeCardVolumnAction extends SalvationActionParent {

 DiscoveredPrinter[] printers = null;
 Connection connection = null;
 ZebraCardPrinter zebraCardPrinter = null;
 ZebraCardGraphics graphics = null;
 ByteArrayOutputStream baos = null;
 protected static JTextArea statusTextArea;

 public ActionForward execute(ActionMapping mapping, ActionForm form,
  HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {

 String personName = String.valueOf(new String(request.getParameter("name").getBytes("GBK"),"UTF-8"));
 String cardNo = String.valueOf(request.getParameter("cardNo"));
 String cardData = String.valueOf(request.getParameter("cardData"));
 boolean flag = false;

 // 在session中设置ListOfOtherInfoModel,以及医院和机关列表
 if(!personName.equals("") && !personName.equals("null")
  && !cardNo.equals("") && !cardNo.equals("null")
    && !cardData.equals("") && !cardData.equals("null")){

  JSONObject count = new JSONObject();
  try {
  //1,打印姓名和卡号
  //======开启连接 START======
  printers = UsbDiscoverer.getZebraUsbPrinters();
  if (printers.length > 0) {
   connection = printers[0].getConnection();

   connection.open();
   zebraCardPrinter = ZebraCardPrinterFactory.getInstance(connection);
  }

  if (zebraCardPrinter == null) {
   flag = false;
  }else{
   flag = true;
  }
  //======关闭连接 START======
  if(flag){
   List<GraphicsInfo> graphicsData = new ArrayList<GraphicsInfo>();

   BufferedImage img = null;
   GraphicsInfo grInfo = new GraphicsInfo();

   graphics = new ZebraCardGraphics(zebraCardPrinter);
   graphics.initialize(0, 0, OrientationType.Landscape, PrintType.MonoK, Color.WHITE);

   // Front MonoK  正面
   grInfo.side = CardSide.Front;
   grInfo.printType = PrintType.MonoK;
   grInfo.graphicType = GraphicType.BMP;

   img = getBufferedImage("C:\\",personName,cardNo);

   baos = new ByteArrayOutputStream();
   ImageIO.write(img, "bmp", baos);

   graphics.drawText("aaaaa", 10, 20, null);

   grInfo.graphicData = graphics.createImage(null);
   graphics.clear();

   graphicsData.add(grInfo);

   // Back MonoK  反面
   graphics.initialize(0, 0, OrientationType.Landscape, PrintType.MonoK, Color.WHITE);

   grInfo = new GraphicsInfo();
   grInfo.side = CardSide.Back;
   grInfo.printType = PrintType.MonoK;
   grInfo.graphicType = GraphicType.BMP;

   img = getBufferedImage("C:\\",personName,cardNo);
   baos = new ByteArrayOutputStream();
   ImageIO.write(img, "bmp", baos);

   graphics.drawImage(baos.toByteArray(), 0, 0, 0, 0, RotationType.RotateNoneFlipNone);
   grInfo.graphicData = graphics.createImage(null);
   graphics.clear();

   graphicsData.add(grInfo);

   int jobId = zebraCardPrinter.print(1, graphicsData);
   pollJobStatus(zebraCardPrinter, jobId);

   //JobStatusInfo jStatus = zebraCardPrinter.getJobStatus(jobId);
   zebraCardPrinter.getJobStatus(jobId);

   //2,写入磁卡数据(卡号)
   //写数据操作
   MagEncodeContainer magEncodeContainer = buildMagEncodeContainer(cardData);
   new MagEncodeModel().MagEncode(zebraCardPrinter, magEncodeContainer, statusTextArea);

   flag = true;
  }
  } catch (Exception ex) {
  if(!flag){
   count.put("cardCount",0);
  }
  } finally {
  IOUtils.closeQuietly(baos);
  cleanUp(connection, zebraCardPrinter, graphics);

  PrinterModel.cleanUpQuietly(zebraCardPrinter, connection);

  if(!flag){
   count.put("cardCount",0);
  }else if(flag){
   count.put("cardCount",1);
  }
  }

  try {
  ResponseUtil.writeToJson(count, response);
  } catch (Exception e) {
  e.printStackTrace();
  }

 }
 return null;
 }

 static boolean pollJobStatus(ZebraCardPrinter device, int actionID) throws ConnectionException, ZebraCardException, ZebraIllegalArgumentException {
 boolean success = false;
 long dropDeadTime = System.currentTimeMillis() + 40000;
 long pollInterval = 500;

 // Poll job status
 JobStatusInfo jStatus = null;

 do {
  jStatus = device.getJobStatus(actionID);
  System.out.println(String.format("Job %d, Status:%s, Card Position:%s, " + "ReadyForNextJob:%s, Mag Status:%s, Contact Status:%s, Contactless Status:%s, " + "Error Code:%d, Alarm Code:%d",
   actionID, jStatus.printStatus, jStatus.cardPosition, jStatus.readyForNextJob, jStatus.magneticEncoding, jStatus.contactSmartCard, jStatus.contactlessSmartCard,
   jStatus.errorInfo.value, jStatus.alarmInfo.value));

  if (jStatus.contactSmartCard.contains("station")) {
  success = true;
  break;
  } else if (jStatus.contactlessSmartCard.contains("station")) {
  success = true;
  break;
  } else if (jStatus.printStatus.contains("done_ok")) {
  success = true;
  break;
  } else if (jStatus.printStatus.contains("alarm_handling")) {
  System.out.println("Error Dectected: " + jStatus.alarmInfo.description);
  success = false;
  } else if (jStatus.printStatus.contains("error") || jStatus.printStatus.contains("cancelled")) {
  success = false;
  break;
  }

  if (System.currentTimeMillis() > dropDeadTime) {
  success = false;
  break;
  }

  try {
  Thread.sleep(pollInterval);
  } catch (InterruptedException e) {
  e.printStackTrace();
  }

 } while (true);

 return success;
 }

 protected static void cleanUp(Connection connection, ZebraCardPrinter genericPrinter, ZebraGraphics graphics) {
 try {
  if (genericPrinter != null) {
  genericPrinter.destroy();
  }
 } catch (ZebraCardException e) {
  e.printStackTrace();
 }

 if (graphics != null) {
  graphics.close();
 }

 if (connection != null) {
  try {
  connection.close();
  } catch (ConnectionException e) {
  e.printStackTrace();
  }
 }
 }

 private static MagEncodeContainer buildMagEncodeContainer(String cardData) {
 MagEncodeContainer container = new MagEncodeContainer();
 container.cardSource = "Feeder";
 container.cardDestination = "Eject";
 container.coercivityType = "High";
 container.verify = true;
 container.track1Data = cardData;   //传入的第一个参数
 container.track2Data = cardData;  //传入的第二个参数
 container.track3Data = cardData;  //传入的第三个参数
 container.quantity = 1;
 return container;
 }

 public static BufferedImage getBufferedImage(String path,String name,String cardNo){
 BufferedImage bimage = null;
 try{
  ImageIcon imgIcon = new ImageIcon(path);
  Image theImg = imgIcon.getImage();
  int width = theImg.getWidth(null) == -1 ? 1023 : theImg.getWidth(null);
  int height = theImg.getHeight(null) == -1 ? 639 : theImg.getHeight(null);
  bimage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
  Graphics2D g = bimage.createGraphics();
  g.setColor(Color.white);
  g.fillRect(0, 0, 1023, 639);
  g.drawImage(theImg, 0, 0, null);
  g.setColor(Color.blue);
  g.setFont(new Font("Arial",Font.BOLD,60));
  g.drawString(name,130,260);  //姓名

  g.setColor(Color.blue);
  g.setFont(new Font("Arial",Font.BOLD,60));
  g.drawString(cardNo, 600, 260);  //卡号

  g.dispose();
 }catch (Exception e) {
  e.printStackTrace();
 }
 return bimage;
 }

 public static void main(String[] args) {
 DiscoveredPrinter[] printers = null;
 Connection connection = null;
 ZebraCardPrinter zebraCardPrinter = null;
 ZebraCardGraphics graphics = null;
 ByteArrayOutputStream baos = null;
 JTextArea statusTextAreas = null;

 // 在session中设置ListOfOtherInfoModel,以及医院和机关列表
  try {
  //1,打印姓名和卡号
  //======开启连接 START======
  printers = UsbDiscoverer.getZebraUsbPrinters();
  if (printers.length > 0) {
   connection = printers[0].getConnection();

   connection.open();
   zebraCardPrinter = ZebraCardPrinterFactory.getInstance(connection);
  }

  if (zebraCardPrinter == null) {
   return;
  }
  //======关闭连接 START======
  List<GraphicsInfo> graphicsData = new ArrayList<GraphicsInfo>();

  BufferedImage img = null;
  GraphicsInfo grInfo = new GraphicsInfo();

  graphics = new ZebraCardGraphics(zebraCardPrinter);
  graphics.initialize(0, 0, OrientationType.Landscape, PrintType.MonoK, Color.WHITE);

  // Front MonoK  正面
  grInfo.side = CardSide.Front;
  grInfo.printType = PrintType.MonoK;
  grInfo.graphicType = GraphicType.BMP;

  img = getBufferedImage("E:\\","brush","111033333");

  baos = new ByteArrayOutputStream();
  ImageIO.write(img, "bmp", baos);

  graphics.drawText("aaaaa", 10, 20, null);

  grInfo.graphicData = graphics.createImage(null);
  graphics.clear();

  graphicsData.add(grInfo);

  // Back MonoK  反面
  graphics.initialize(0, 0, OrientationType.Landscape, PrintType.MonoK, Color.WHITE);

  grInfo = new GraphicsInfo();
  grInfo.side = CardSide.Back;
  grInfo.printType = PrintType.MonoK;
  grInfo.graphicType = GraphicType.BMP;

  img = getBufferedImage("E:\\","brush","111033333");
  baos = new ByteArrayOutputStream();
  ImageIO.write(img, "bmp", baos);

  graphics.drawImage(baos.toByteArray(), 0, 0, 0, 0, RotationType.RotateNoneFlipNone);
  grInfo.graphicData = graphics.createImage(null);
  graphics.clear();

  graphicsData.add(grInfo);

  int jobId = zebraCardPrinter.print(1, graphicsData);
  pollJobStatus(zebraCardPrinter, jobId);

  JobStatusInfo jStatus = zebraCardPrinter.getJobStatus(jobId);

  //2,写入磁卡数据(卡号)
  //写数据操作
  MagEncodeContainer magEncodeContainer = buildMagEncodeContainer("111033333");
  new MagEncodeModel().MagEncode(zebraCardPrinter, magEncodeContainer, statusTextAreas);

  } catch (Exception ex) {
  } finally {
  IOUtils.closeQuietly(baos);
  cleanUp(connection, zebraCardPrinter, graphics);

  PrinterModel.cleanUpQuietly(zebraCardPrinter, connection);
  }
 }
}

上面的代码是JSP调用的后台请求逻辑代码,在JSP页面可以用AJAX请求,然后执行相应的代码块进行相应的执行代码进行调用制卡机外接设备。值得一提的是,由于在调用相应的外接设备的时候,会调用到相应的.dll扩展文件,这个在使用TOMCAT/WebSpare的时候,需要把.dll文件放到bin目录下,不然的话可能会调用失败。这一点要特别注意,因为在SDK中,java程序的话可能是执行通过的,但是java web项目则必须要注意到这一点。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现获取安卓设备里已安装的软件包

    之前的文章向大家介绍了几个项目中常用的实用功能,那么在这篇文中,我将向大家介绍如何获取Android手机中已经安装的手机应用程序,好了,废话不多说,直接上代码 private String getInstalledAppListAsString(){ PackageManager pm = context.getPackageManager(); List<ApplicationInfo> apps = pm.getInstalledApplications(PackageManager.GE

  • Java调用外接设备详解(制卡机)

    最近在开发的系统中,有一个接入外接设备制卡机更换,之前用的制卡机要重新采购,所以导致之前的调用接口方法无效,要用新的设备接口来进行调用.可是这个设备是外国进口过来的,资料很少.想要百度的话,网上资料都没有,中间经过了几天的摸索,最终还是弄了出来,所以把详细的分析及解决方法记录下来. 这个制卡机是打印磁卡/智能卡的,像我们常用的银行卡.饭卡.购物卡都可以用这个机器来进行设计并制卡,并最终发放给消费者使用.简要说下解决的思路吧,最开始拿到这个机器的时候,我是一头的雾水,也不知道从何下手,我当时最最简

  • java调用回调机制详解

    调用和回调机制 在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种: 1.同步调用 同步调用是最基本并且最简单的一种调用方式, 类A的方法a()调用类B的方法b(), 一直等待b()方法执行完毕, a()方法继续往下走. 这种调用方式适用于方法b()执行时间不长的情况, 因为b()方法执行时间一长或者直接阻塞的话, a()方法的余下代码是无法执行下去的, 这样会造成整个流程的阻塞. 2.异步调用 异步调用是为了解决同步调用可能出现阻塞, 导致整个流程卡住而产

  • Java调用Oracle存储过程详解

    Java调用Oracle存储过程详解 步骤: 1.编写Oracle存储过程 2.编写数据库获取连接工具类 3.编写简单应用调用存储过程 实现: 1.Oracle存储过程: /*测试表*/ create table test( id varchar2(32), name varchar2(32) ); /*存储过程 插入数据*/ CREATE OR REPLACE PROCEDURE insert_procedure( PARA1 IN VARCHAR2, PARA2 IN VARCHAR2 )

  • Java 调用天气Webservice详解及实例代码

    Java调用天气Webservice的小应用 废话不多说,直接贴代码: CityReq.java package com.weather; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="getWeatherbyCityName",namespace="http://WebXml.com.cn/

  • java中构造器内部调用构造器实例详解

    可能为一个类写了多个构造器,有时可能想在一个构造器里面调用另外一个构造器,为了减少代码的重复,可用this关键字做到这一点. public class Flower { private String string; private int age; public Flower() { // 先调用public Flower(String string, int age) this("leon", 120); // 先调用public Flower(String string, int

  • Java RandomAccessFile的用法详解

    RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream类系的.实际上,除了实现DataInput和 DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫

  • Java NIO服务器端开发详解

    一.NIO类库简介 1.缓冲区Buffer Buffer是一个对象,包含一些要写入和读出的数据. 在NIO中,所有的数据都是用缓冲区处理的,读取数据时,它是从通道(Channel)直接读到缓冲区中,在写入数据时,也是从缓冲区写入到通道. 缓冲区实质上是一个数组,通常是一个字节数组(ByteBuffer),也可以是其它类型的数组,此外缓冲区还提供了对数据的结构化访问以及维护读写位置等信息. Buffer类的继承关系如下图所示: 2.通道Channel Channel是一个通道,网络数据通过Chan

  • java 抽象类的实例详解

    java 抽象类的实例详解 前言: 什么是抽象类?这名字听着就挺抽象的,第一次听到这个名字还真有可能被唬住.但是,就像老人家所说的,一切反动派都是纸老虎,一切有着装x名字的概念也是纸老虎.好吧,我们已经从战略上做到了藐视它,现在就要战术上重视它,如同要解决纸老虎,就要一个牙齿一个牙齿地敲,一个爪子一个爪子地拔:解决这种抽象概念也一样,先要把它具体化,细分化,然后一个一个地来. 我一般遇到新的概念都会问三个问题: 1.这个东西有什么用?用来干什么的?它的意义在哪里?(显然,如果是没用的东西,就没必

  • Java 反射机制实例详解

    Java 反射机制实例详解 一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,Java和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反射.通过反射,Java可以于运行时加载.探知和使用编译期间完全求和的类.生成其对象实体,调用其方法或者对属性设值.所以Java算是一个半动态的语言吧. 反射的概念: 在Java中的反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对

  • java回调机制实例详解

    java回调机制实例详解 以前不理解什么叫回调,天天听人家说加一个回调方法啥的,心里想我草,什么叫回调方法啊?然后自己就在网上找啊找啊找,找了很多也不是很明白,现在知道了,所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法,这样子说你是不是有点晕晕的,其实我刚开始也是这样不理解,看了人家说比较经典的回调方式: Class A实现接口CallBack callback--背景1 class A中包含一个class B的引用b --背景2 clas

随机推荐