近日,在做项目的时候,有用到JAVA调用制卡机的一个功能。在之前的博客中,有提到过,参照api文档和相关的SDK,已经成功的在本地代码中调用到了制卡机,实现制卡的打印功能。but,后来测试才发现,原来本地代码调用成功了,但是相关的加载制卡机的USB驱动都是在本地代码中执行的,而不是在浏览器端执行的。额,知道这意味着什么吗?一个字描述,“ 坑 ”,真是坑死人不偿命呀。
当时我以为功能开发完了,就直接把代码SVN提交了上去,但是在部署到正式服务器的时候,却怎么也调不了,一直提示“ 制卡失败 ”。当时以后失败的原因是dll 文件加载失败,因为正式服务器上的中间件是WebSphere,而本地的中间件是Tomcat,Tomcat加载制卡机的DLL文件的时候,只需要将其放置在bin目录下就可以了,但是WebSphere之前没用过,我尝试着将dll文件放到了WebSphere下的所有bin目录文件夹下,但是还是不成功。后来公司同事提醒说,加载制卡机的代码都在Action后台执行的,会不会制卡机必须放在服务器端才可以调用成功。当时听到这,第一感觉就是TMD的坑了,当然也怪自己之前光顾着实现功能去了,没有全局思考考虑,这也是我的失误。
有了这个思路,就开始考虑,怎么在本地调用制卡功能,起初想了很多办法,比如什么把Action的代码给放到JSP中,打开JSP执行,后来发现JSP其实也是在后台变成Servlet中执行的,所以这个方案失败。后来又想过更改官方的JAR包代码,但是后来测试还是不行。尝试了很多办法,最后的话,想出了一个简单粗暴的方案,那就是服务器端调用客户端的代码。也就是说把制卡的代码打包到Tomcat中,然后Tomcat放到本地,需要用制卡的功能的时候,点击系统的制卡菜单,系统会用AJAX或者WebService远程调用相关的服务,执行代码,最后调用本地的Tomcat启动制卡机。当然了,这个方法总感觉比较LOW,但是没办法呀,时间有限,工作中还有其他的任务,加之客户也催的很紧,情急之下,只能先应急了。
在这个过程中,之前已经把JAVA调用制卡的功能都写好了,现在只需要在系统的相关JSP页面中,当用户访问这个JSP页面的时候,获取其真实的IP地址,然后根据其IP地址,访问其提供的制卡服务地址就OK了。在这里的话,就涉及到AJAX远程跨域访问的问题,最终找到的跨域解决方案是使用JSONP的方案:(这个githup上的一个开源项目,如要使用,先下载 https://github.com/webmodules/jsonp)
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<%@ page import="com.wonders.yksx.salvation.model.*"%>
<%@ page import="com.wonders.yksx.common.model.*"%>
<%@ page import="com.wonders.yksx.common.util.*"%>
<%@ page isELIgnored="false"%>
<%@ page import="java.io.IOException"%>
<%@ page import="java.io.PrintWriter"%>
<%@ page import="java.net.Inet4Address"%>
<%@ page import="java.net.InetAddress"%>
<%@ page import="java.net.NetworkInterface"%>
<%@ page import="java.util.Enumeration"%>
<%@ page import="javax.servlet.ServletException"%>
<%@ page import="javax.servlet.http.HttpServletRequest"%>
<%@ page import="javax.servlet.http.HttpServletResponse"%>
<jsp:useBean id="pageStyle" class="java.lang.String" scope="session" />
<%
ListOfDicModel listOfHospitalModel = (ListOfDicModel) session
.getAttribute("listOfHospitalModel");
ListOfOtherInfoModel listOfOtherInfoModel = (ListOfOtherInfoModel) request
.getAttribute("listOfOtherInfoModel");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<link href="css/<%=pageStyle%>" rel="stylesheet" type="text/css">
<script src="http://apps.bdimg.com/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
/**
*打印采用8*6inch的纸张设置(203.2*152.4mm)
*/
var PRINT_UNIT = "mm";
var PRINT_WINDOW_WIDTH = 203.2;
var PRINT_WINDOW_HEIGHT = 152.4;
var PRINT_WORD_TOP = 82.9;
var PRINT_WORD_HEIGHT = 4.5;
var PRINT_WORD_INTERVAL = 5;
var PRINT_WORD_LEFT = 65.2;
var PRINT_OFFSET = 1;
var IPAddress;
//获取IP地址
getIPAddr();
function getNewWindowContent(i)
{
var str = "<html>";
str += "<head><title>医疗帮困就医记录册封面打印</title></head>";
str += "<body font-size='"+PRINT_WORD_HEIGHT+PRINT_UNIT+"' style='filter:flipv()fliph();'>";
str += "<div id='box' background-color=blue style='width:"+PRINT_WINDOW_WIDTH+PRINT_UNIT+";height:"+PRINT_WINDOW_HEIGHT+PRINT_UNIT+"'></div>";
//str += "<form action='#'>";
//str += "<input type='button' value='打印' class='hidden' onclick='document.body.style.filter = \"fliph()flipv()\";window.opener.printWindow.print();document.body.style.filter = \"\";' />";
//str += "</form>";
//str += "<a href='#' onclick='window.print()'>打印</a>";
str += "</body>";
str += "</html>";
return str;
}
function makeVolumn(btn)
{
var i = btn.id.substring(6,btn.id.length);
var str = getNewWindowContent(i);
printWindow = window.open("","print","menubar=yes");
printWindow.document.write(str);
var hospDiv = printWindow.document.createElement("div");
var noDiv = printWindow.document.createElement("div");
var nameDiv = printWindow.document.createElement("div");
var genderDiv = printWindow.document.createElement("div");
var cetfidDiv = printWindow.document.createElement("div");
hospDiv.appendChild(printWindow.document.createTextNode(getHospital(i)));
noDiv.appendChild(printWindow.document.createTextNode(getVolumnNo(i)));
nameDiv.appendChild(printWindow.document.createTextNode(getName(i)));
genderDiv.appendChild(printWindow.document.createTextNode(getGender(i)));
cetfidDiv.appendChild(printWindow.document.createTextNode(getCetfId(i)));
hospDiv.style.position = "absolute";
noDiv.style.position = "absolute";
nameDiv.style.position = "absolute";
genderDiv.style.position = "absolute";
cetfidDiv.style.position = "absolute";
var temp = PRINT_WORD_LEFT+PRINT_UNIT;
hospDiv.style.left = temp;
noDiv.style.left = temp;
nameDiv.style.left = temp;
genderDiv.style.left = temp;
cetfidDiv.style.left = temp;
temp = PRINT_WORD_HEIGHT+PRINT_UNIT;
hospDiv.style.height = temp;
noDiv.style.height = temp;
nameDiv.style.height = temp;
genderDiv.style.height = temp;
cetfidDiv.style.height = temp;
var interval = PRINT_WORD_HEIGHT + PRINT_WORD_INTERVAL;
var currentDepth = PRINT_WORD_TOP;
hospDiv.style.top = (currentDepth+PRINT_OFFSET)+PRINT_UNIT;
currentDepth += interval;
noDiv.style.top = (currentDepth+PRINT_OFFSET)+PRINT_UNIT;
currentDepth += interval;
nameDiv.style.top = (currentDepth+PRINT_OFFSET)+PRINT_UNIT;
currentDepth += interval;
genderDiv.style.top = (currentDepth+PRINT_OFFSET)+PRINT_UNIT;
currentDepth += interval;
cetfidDiv.style.top = (currentDepth+PRINT_OFFSET)+PRINT_UNIT;
var box = printWindow.document.getElementById("box");
box.appendChild(hospDiv);
box.appendChild(noDiv);
box.appendChild(nameDiv);
box.appendChild(genderDiv);
box.appendChild(cetfidDiv);
}
function getHospital(i)
{
return document.getElementById("hospital"+i).innerHTML;
}
function getVolumnNo(i)
{
return document.getElementById("volumnNo"+i).innerHTML;
}
function getCardNo(i)
{
return document.getElementById("cardNo"+i).innerHTML;
}
function getName(i)
{
return document.getElementById("personName"+i).innerHTML;
}
function getGender(i)
{
return document.getElementById("gender"+i).innerHTML;
}
function getCetfId(i)
{
return document.getElementById("personId"+i).innerHTML;
}
function getCardData(i)
{
return document.getElementById("cardData"+i).value;
}
function checkCetfId()
{
var card = document.getElementById("card");
//身份证为15或18位,18位时最后一位可能为x
var isValid = /^\d{15}$/.test(card.value) || /^\d{17}[\dXx]$/.test(card.value);
if(!isValid)
{
alert("身份证号未输入或格式不正确!");
card.focus();
return false;
}
return true;
}
function makeCard(btn)
{
var i = btn.id.substring(4,btn.id.length);
var name = getName(i);
var cardNo = getCardNo(i);
var cardData = getCardData(i);
sbpub_ctrl1MakeCard(name,cardNo,cardData);
}
function makeCard_now_1(btn){
var i = btn.id.substring(7,btn.id.length);
var name = getName(i);
var cardNo = getCardNo(i);
var cardData = getCardData(i);
window.open('makeCardVolumn.jsp?personName='+name+'&cardNo='+cardNo+'&cardData='+cardData);
<%--
$.ajax({
type: "GET",
url: "makeCradAction.do",
data: {"name":name,"cardNo":cardNo,"cardData":cardData},
dataType: "json",
success: function(data){
if(data.cardCount==1){alert("制卡成功!");}
else{alert("制卡失败!");}
}
});
--%>
}
function makeCard_now(btn){
var i = btn.id.substring(7,btn.id.length);
var name = getName(i);
var cardNo = getCardNo(i);
var cardData = getCardData(i);
$.jsonp({
type: "get",
url: "http://"+IPAddress,
timeout: 8000,
dataType: "jsonp",
callback: "jsonSuccess",
data: {"name":name,"cardNo":cardNo,"cardData":cardData},
complete: function() {
alert('制卡成功!');
},
success: function(data) {
if(data["flag"]=="1"){alert("制卡成功!");}
else{alert("制卡失败!");}
},
error: function(){
alert("异常,请联系管理员");
}
});
}
function getIPAddr(){
<%
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (Exception e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
%>
IPAddress = "<%=ipAddress%>"+":8081/MakCard/makCardVolumn";
}
</script>
<title>Insert title here</title>
<script src="<%=request.getContextPath() %>/js/jdlk/json2.js" type="text/javascript"></script>
<script src="<%=request.getContextPath() %>/js/jsonp/jquery.jsonp.js" type="text/javascript"></script>
</head>
<body>
<jsp:include flush="true" page="../../frame/position.jsp" />
<form action="queryCardVolumn.do" method="POST"
onsubmit="return checkCetfId();">
<div class="cbody">
<div class="cxtj">
<table width="98%" border="0" align="center" cellpadding="0"
cellspacing="0" class="top_select">
<tr>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="3%">
</td>
<td width="15%" class="tselect_btn">
<span class="select_ico1"><nobr>
查 询
</nobr>
</span>
</td>
<td width="82%">
</td>
</tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0"
class="selectnr_bj">
<tr>
<td>
<table width="98%" border="0" align="center" cellpadding="0"
cellspacing="0" class="sytable">
<tr>
<td align="right">
姓名:
</td>
<td align="left">
<input type="text" name="name" id="name">
</td>
<td align="right">
身份证:
</td>
<td align="left">
<input type="text" name="card" id="card">
</td>
<td align="right">
<input type="submit" value="查询" class="nbnt1">
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="cxlb">
<table width="98%" border="0" align="center" cellpadding="0"
cellspacing="0" class="top_select">
<tr>
<td>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="3%">
</td>
<td width="15%" class="tselect_btn">
查询结果
</td>
<td width="82%">
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="98%" border="0" align="center" cellpadding="0"
cellspacing="0" class="ntable_list">
<tr>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
姓名
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
身份证
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
性别
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
发卡单位
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
医院名称
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
卡号
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
册号
</th>
<th onmouseover="this.className='over'"
onmouseout="this.className='out'" class="out">
</th>
</tr>
<%
if (listOfOtherInfoModel != null && listOfHospitalModel != null)
for (int i = 0; i < listOfOtherInfoModel.size(); i++) {
OtherInfoModel oim = (OtherInfoModel) listOfOtherInfoModel
.getValue(i);
%>
<tr onmouseover="this.className='td_over'"
onmouseout="this.className=''">
<td align="center" class="textValue">
<%=i + 1%>
</td>
<td align="center" class="textValue" id="personName<%=i%>">
<%=oim.getPersonName()%>
</td>
<td align="center" class="textValue" id="personId<%=i%>">
<%=oim.getCetfId()%>
</td>
<td align="center" class="textValue" id="gender<%=i%>">
<%=Util.nullToNbspString(DictionaryUtil.getInstance().getGenders().getItemName(oim.getGender()))%>
</td>
<td align="center" class="textValue">
<%=DictionaryUtil.getInstance().getListOfOrgan()
.getOrganName(oim.getOrganId())%>
</td>
<%
String hospitalString = "";
if (oim.getHospitalCode1() != null) {
if (oim.getHospitalCode1().length() == 9) {
for (int j = 0; j < listOfHospitalModel.size(); j++) {
DicModel hospital = (DicModel) listOfHospitalModel
.getValue(j);
if (hospital.getId().substring(0, 9).equals(
oim.getHospitalCode1())) {
hospitalString += hospital.getName();
break;
}
}
} else
hospitalString += Util
.toNotNullString(listOfHospitalModel
.getItemName(oim.getHospitalCode1()));
}
if (oim.getHospitalCode2() != null) {
if (oim.getHospitalCode2().length() == 9) {
for (int j = 0; j < listOfHospitalModel.size(); j++) {
DicModel hospital = (DicModel) listOfHospitalModel
.getValue(j);
if (hospital.getId().substring(0, 9).equals(
oim.getHospitalCode2())) {
hospitalString += " " + hospital.getName();
break;
}
}
} else
hospitalString += " "
+ Util
.toNotNullString(listOfHospitalModel
.getItemName(oim
.getHospitalCode2()));
}
%>
<td align="center" class="textValue" id="hospital<%=i%>">
<%=hospitalString%>
</td>
<td align="center" class="textValue" id="cardNo<%=i%>">
<%=oim.getCardNo()%>
</td>
<td align="center" class="textValue" id="volumnNo<%=i%>">
<%=oim.getVolumeNo()%>
</td>
<td align="center" class="textValue">
<input type="hidden" id="cardData<%=i%>"
value="<%=oim.getCardData()%>">
<input id="card<%=i%>" type="button" value="制卡"
onclick="makeCard(this);" />
<input id="volumn<%=i%>" type="button" value="制册"
onclick="makeVolumn(this);" />
<input id="nowcard<%=i%>" type="button" value="ZXP制卡"
onclick="makeCard_now(this);" />
</td>
</tr>
<%
}
%>
</table>
</div>
</div>
</form>
</body>
<OBJECT ID="sbpub_ctrl1"
CLASSID="CLSID:DE440B82-BA77-4EFC-A3F7-520BD79A367D"></OBJECT>
</html>
<SCRIPT LANGUAGE="VBScript">
Function sbpub_ctrl1MakeCard(ByVal name,ByVal cardNo,ByVal cardData)
call sbpub_ctrl1.writeCardDefault("",name,cardNo,"",cardData)
if sbpub_ctrl1.p_return <>0 then
msgbox sbpub_ctrl1.p_errormsg
exit Function
end if
end function
</script>
大致的解决方案就是这样,后续的话我会把代码及相关的DEMO发出来,大家有需要的可以借鉴,谢谢。
------------------------
相关资料下载: