Java調(diào)用外接設(shè)備詳解(制卡機(jī))
最近在開(kāi)發(fā)的系統(tǒng)中,有一個(gè)接入外接設(shè)備制卡機(jī)更換,之前用的制卡機(jī)要重新采購(gòu),所以導(dǎo)致之前的調(diào)用接口方法無(wú)效,要用新的設(shè)備接口來(lái)進(jìn)行調(diào)用??墒沁@個(gè)設(shè)備是外國(guó)進(jìn)口過(guò)來(lái)的,資料很少。想要百度的話,網(wǎng)上資料都沒(méi)有,中間經(jīng)過(guò)了幾天的摸索,最終還是弄了出來(lái),所以把詳細(xì)的分析及解決方法記錄下來(lái)。
這個(gè)制卡機(jī)是打印磁卡/智能卡的,像我們常用的銀行卡、飯卡、購(gòu)物卡都可以用這個(gè)機(jī)器來(lái)進(jìn)行設(shè)計(jì)并制卡,并最終發(fā)放給消費(fèi)者使用。簡(jiǎn)要說(shuō)下解決的思路吧,最開(kāi)始拿到這個(gè)機(jī)器的時(shí)候,我是一頭的霧水,也不知道從何下手,我當(dāng)時(shí)最最簡(jiǎn)單的想法就是先把這個(gè)機(jī)器怎么使用,怎么操作,什么用途了解清楚,然后再談接口代碼啥的。但是找了半天,網(wǎng)上的資料也很少,也不知道怎么使用,最后看到機(jī)器上有一個(gè)二維碼幫助的,掃了下,進(jìn)入到了它們的官網(wǎng),找到了相應(yīng)的機(jī)器型號(hào),然后的話看到了相應(yīng)的使用說(shuō)明和相應(yīng)的視頻教程,了解了一番,這才知道了產(chǎn)品正確的使用方法,所以拿到一個(gè)新玩意,想要快速了解它,最好的還是先去看他的說(shuō)明書和官方教程。

知道了相應(yīng)的使用方法,下面的操作也就很簡(jiǎn)單了。其實(shí)具體的原理方法也就是先使用軟件設(shè)計(jì)出兩張BMP的圖片,一面是磁卡/智能卡的正面,一般的話都是張?jiān)O(shè)計(jì)的好看的圖片,另一張的話就是磁卡/智能卡的反面,然后圖片的給相應(yīng)的代碼解析,讀取,把信息寫入到卡的磁條上,最后調(diào)用機(jī)器進(jìn)行打印,用其中機(jī)器的墨紙寫入到空白的卡片上就可以了。
但是一般人工都是機(jī)器自帶的軟件提前設(shè)計(jì)好圖片,如果換做用代碼驅(qū)動(dòng)機(jī)器的話,那就要用代碼要生成圖片了。當(dāng)然了,在JAVA中有相應(yīng)的類來(lái)生成BMP格式的圖片,然后調(diào)用相應(yīng)的代碼就可以了。
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中設(shè)置ListOfOtherInfoModel,以及醫(yī)院和機(jī)關(guān)列表
if(!personName.equals("") && !personName.equals("null")
&& !cardNo.equals("") && !cardNo.equals("null")
&& !cardData.equals("") && !cardData.equals("null")){
JSONObject count = new JSONObject();
try {
//1,打印姓名和卡號(hào)
//======開(kāi)啟連接 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;
}
//======關(guān)閉連接 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,寫入磁卡數(shù)據(jù)(卡號(hào))
//寫數(shù)據(jù)操作
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; //傳入的第一個(gè)參數(shù)
container.track2Data = cardData; //傳入的第二個(gè)參數(shù)
container.track3Data = cardData; //傳入的第三個(gè)參數(shù)
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); //卡號(hào)
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中設(shè)置ListOfOtherInfoModel,以及醫(yī)院和機(jī)關(guān)列表
try {
//1,打印姓名和卡號(hào)
//======開(kāi)啟連接 START======
printers = UsbDiscoverer.getZebraUsbPrinters();
if (printers.length > 0) {
connection = printers[0].getConnection();
connection.open();
zebraCardPrinter = ZebraCardPrinterFactory.getInstance(connection);
}
if (zebraCardPrinter == null) {
return;
}
//======關(guān)閉連接 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,寫入磁卡數(shù)據(jù)(卡號(hào))
//寫數(shù)據(jù)操作
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調(diào)用的后臺(tái)請(qǐng)求邏輯代碼,在JSP頁(yè)面可以用AJAX請(qǐng)求,然后執(zhí)行相應(yīng)的代碼塊進(jìn)行相應(yīng)的執(zhí)行代碼進(jìn)行調(diào)用制卡機(jī)外接設(shè)備。值得一提的是,由于在調(diào)用相應(yīng)的外接設(shè)備的時(shí)候,會(huì)調(diào)用到相應(yīng)的.dll擴(kuò)展文件,這個(gè)在使用TOMCAT/WebSpare的時(shí)候,需要把.dll文件放到bin目錄下,不然的話可能會(huì)調(diào)用失敗。這一點(diǎn)要特別注意,因?yàn)樵赟DK中,java程序的話可能是執(zhí)行通過(guò)的,但是java web項(xiàng)目則必須要注意到這一點(diǎn)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java?CompletableFuture異步任務(wù)編排示例詳解
這篇文章主要為大家介紹了java?CompletableFuture異步任務(wù)編排示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
實(shí)例解析Java單例模式編程中對(duì)抽象工廠模式的運(yùn)用
這篇文章主要介紹了實(shí)例解析Java單例模式編程中對(duì)抽象工廠模式的運(yùn)用,抽象工廠模式可以看作是工廠方法模式的升級(jí)版,本需要的朋友可以參考下2016-02-02
spring boot中的properties參數(shù)配置詳解
這篇文章主要介紹了spring boot中的properties參數(shù)配置,需要的朋友可以參考下2017-09-09
java連接mysql數(shù)據(jù)庫(kù)及測(cè)試是否連接成功的方法
這篇文章主要介紹了java連接mysql數(shù)據(jù)庫(kù)及測(cè)試是否連接成功的方法,結(jié)合完整實(shí)例形式分析了java基于jdbc連接mysql數(shù)據(jù)庫(kù)并返回連接狀態(tài)的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-09-09

