最近网上值机电子客票后台开发,其中的有个需求要求一次导入多个PNR(Passenger Name Record),并且判断这些导入的PNR是否满足同时导入的要求,并且完成相关PNR信息的提取和整理。开始我按照一般的思路完成了需求的功能,然而我发现导入一个PNR一般都在2秒钟以上,要是网络不好的话4、5秒都出现过,所以对自己开发的功能很不满意,这样的程序自己都接受不了,何况真正在生产线上工作的客服人员呢?于是,并发提取PNR的念头产生了。对于刚刚工作,又对Java多线程不熟悉的我这也许是个挑战,因为我只是知道有多线程这个概念,而没有真正的去使用过,去实践过。于是我到网上去找资料,查API文档,终于把这个难题放倒了。
GetPnrInfo.java类提取Pnr信息,实现了Ruable接口:
package com.feinar.cbs.ibe;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import com.feinar.cbs.delivery.pojo.Deliveryorders;
import com.feinar.cbs.flight.order.pojo.Passenger;
import com.feinar.cbs.flight.order.pojo.Segment;
import com.feinar.cbs.flight.order.pojo.SegmentId;
import com.feinar.cbs.flight.order.pojo.Segmentprice;
import com.feinar.cbs.flight.order.pojo.SegmentpriceId;
import com.travelsky.ibe.client.FD;
import com.travelsky.ibe.client.FDResult;
import com.travelsky.ibe.client.FF;
import com.travelsky.ibe.client.FFResult;
import com.travelsky.ibe.client.pnr.PNRAirSeg;
import com.travelsky.ibe.client.pnr.PNRContact;
import com.travelsky.ibe.client.pnr.PNRInfant;
import com.travelsky.ibe.client.pnr.PNRPassenger;
import com.travelsky.ibe.client.pnr.PNRSSR;
import com.travelsky.ibe.client.pnr.RT;
import com.travelsky.ibe.client.pnr.RTResult;
public class GetPnrInfo implements Runnable ...{
private final String ptype[][] = ...{ ...{ "", "CH", "IN" }, ...{ "成人", "儿童", "婴儿" } };
private String pnr;
private String errormsg;
private List<Passenger> passengerlist[];
private List<Segment> segmentlist;
private Deliveryorders deliveryorders;
private CountDownLatch latch;
public GetPnrInfo(String pnr, CountDownLatch latch) ...{
this.pnr = pnr;
this.latch = latch;
this.errormsg = "";
this.deliveryorders = new Deliveryorders();
this.segmentlist = new ArrayList<Segment>();
this.passengerlist = new ArrayList[3];
for (int i = 0; i < 3; i++) ...{
this.passengerlist[i] = new ArrayList<Passenger>();
}
}
public GetPnrInfo(String pnr, String errormsg,
List<Passenger> passengerlist[], List<Segment> segmentlist,
Deliveryorders deliveryorders, CountDownLatch latch) ...{
this.pnr = pnr;
this.errormsg = errormsg;
this.passengerlist = passengerlist;
this.segmentlist = segmentlist;
this.deliveryorders = deliveryorders;
this.latch = latch;
}
public void run() ...{
try ...{
parsePnr();
} catch (Exception e) ...{
this.setErrormsg(e.getMessage());
}
latch.countDown();
}
public void parsePnr() throws Exception ...{
try ...{
RT rt = new RT();
RTResult rtresult = new RTResult();
rtresult = rt.retrieve(this.getPnr());
// System.out.println("****** "+this.getPnr());
// 获取Pnr中的旅客信息
// 获得证件号组,常旅客号组
String foidcard[] = new String[rtresult.getPassengersCount()];
String fqtvcard[] = new String[rtresult.getPassengersCount()];
for (int j = 0; j < rtresult.getSSRsCount(); j++) ...{
PNRSSR pnrssr = rtresult.getSSRAt(j);
// System.out.println(pnrssr.getPsgrID().substring(1)+" card
// "+pnrssr.getServeInfo().substring(12));
if (pnrssr.getSSRType().equalsIgnoreCase("foid"))
foidcard[Integer.parseInt(pnrssr.getPsgrID().substring(1)) - 1] = pnrssr
.getServeInfo().substring(12);
else if (pnrssr.getSSRType().equalsIgnoreCase("fqtv"))
fqtvcard[Integer.parseInt(pnrssr.getPsgrID().substring(1)) - 1] = pnrssr
.getServeInfo().substring(12);
}
// 获取成人组,儿童组 getPassengers
for (int j = 0; j < rtresult.getPassengersCount(); j++) ...{
Passenger passenger = new Passenger();
PNRPassenger pnrp = rtresult.getPassengerAt(j);
passenger.setPsgname(pnrp.getName());
passenger.setType(String.valueOf(pnrp.getType()));
passenger.setPnrno(rtresult.getPnrcode());
// System.out.println("*** " + j + " **** " + foidcard[j]);
passenger.setIdtype(foidcard[j].substring(0, 2));
passenger.setIdcard(foidcard[j].substring(2, foidcard[j]
.indexOf("/")));
passenger.setMembercardnumber(fqtvcard[j] == null ? null
: fqtvcard[j].substring(2, fqtvcard[j].indexOf("/")));
this.passengerlist[pnrp.getType()].add(passenger);
passenger = null;
}
foidcard = null;
fqtvcard = null;
// 获取婴儿组 getInfants
for (int j = 0; j < rtresult.getInfantsCount(); j++) ...{
Passenger passenger = new Passenger();
passenger.setType("2");
PNRInfant infant = rtresult.getInfantAt(j);
passenger.setPsgname(infant.getName());
passenger.setBirthdate(infant.getBrith());
passenger.setCarriedby(rtresult.getPassengerAt(
Integer.parseInt(infant.getCarrier().substring(1)) - 1)
.getName());
this.passengerlist[2].add(passenger);
passenger = null;
}
// 获取Pnr 中的航班信息
// 提取航段信息
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < rtresult.getAirSegsCount(); i++) ...{
Segment seg = new Segment();
PNRAirSeg pnrseg = rtresult.getAirSegAt(i);
seg.setId(new SegmentId(null, new Long(i)));
seg.setCarrier(pnrseg.getAirNo().substring(0, 2));
seg.setFlightno(pnrseg.getAirNo().substring(2));
seg.setDepairport(pnrseg.getOrgCity());
seg.setArrairport(pnrseg.getDesCity());
seg.setDeptime(new Timestamp(format.parse(
pnrseg.getDepartureTime().toLocaleString()).getTime()));
seg.setArrtime(new Timestamp(format.parse(
pnrseg.getArrivalTime().toLocaleString()).getTime()));
seg.setCabin(String.valueOf(pnrseg.getFltClass()));
// 查询机型
FFResult ffr = new FFResult();
try ...{
ffr = new FF().flightTime(pnrseg.getAirNo(), pnrseg
.getDepartureTime());
seg.setPlanetype(ffr.getPlaneModel());
} catch (Exception e) ...{
System.out.println("系统在查询航班 " + pnrseg.getAirNo()
+ " 机型时出错;");
throw new Exception("系统在查询航班 " + pnrseg.getAirNo()
+ " 机型时出错;");
}
seg.setSeatstatus(pnrseg.getActionCode());// 待定
Segmentprice segmentprice = new Segmentprice();
segmentprice.setCarrier(seg.getCarrier());
segmentprice.setFlightno(seg.getFlightno());
segmentprice.setCabin(seg.getCabin());
segmentprice.setDepairport(seg.getDepairport());
segmentprice.setArrairport(seg.getArrairport());
segmentprice.setArrtime(seg.getArrtime());
segmentprice.setFlightdate(seg.getDeptime());
segmentprice.setPlanetype(seg.getPlanetype());
segmentprice.setId(new SegmentpriceId(null, seg.getId()
.getSegorder()));
// 查询价格
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import com.feinar.cbs.delivery.pojo.Deliveryorders;
import com.feinar.cbs.flight.order.pojo.Passenger;
import com.feinar.cbs.flight.order.pojo.Segment;
import com.feinar.cbs.flight.order.pojo.SegmentId;
import com.feinar.cbs.flight.order.pojo.Segmentprice;
import com.feinar.cbs.flight.order.pojo.SegmentpriceId;
import com.travelsky.ibe.client.FD;
import com.travelsky.ibe.client.FDResult;
import com.travelsky.ibe.client.FF;
import com.travelsky.ibe.client.FFResult;
import com.travelsky.ibe.client.pnr.PNRAirSeg;
import com.travelsky.ibe.client.pnr.PNRContact;
import com.travelsky.ibe.client.pnr.PNRInfant;
import com.travelsky.ibe.client.pnr.PNRPassenger;
import com.travelsky.ibe.client.pnr.PNRSSR;
import com.travelsky.ibe.client.pnr.RT;
import com.travelsky.ibe.client.pnr.RTResult;
public class GetPnrInfo implements Runnable ...{
private final String ptype[][] = ...{ ...{ "", "CH", "IN" }, ...{ "成人", "儿童", "婴儿" } };
private String pnr;
private String errormsg;
private List<Passenger> passengerlist[];
private List<Segment> segmentlist;
private Deliveryorders deliveryorders;
private CountDownLatch latch;
public GetPnrInfo(String pnr, CountDownLatch latch) ...{
this.pnr = pnr;
this.latch = latch;
this.errormsg = "";
this.deliveryorders = new Deliveryorders();
this.segmentlist = new ArrayList<Segment>();
this.passengerlist = new ArrayList[3];
for (int i = 0; i < 3; i++) ...{
this.passengerlist[i] = new ArrayList<Passenger>();
}
}
public GetPnrInfo(String pnr, String errormsg,
List<Passenger> passengerlist[], List<Segment> segmentlist,
Deliveryorders deliveryorders, CountDownLatch latch) ...{
this.pnr = pnr;
this.errormsg = errormsg;
this.passengerlist = passengerlist;
this.segmentlist = segmentlist;
this.deliveryorders = deliveryorders;
this.latch = latch;
}
public void run() ...{
try ...{
parsePnr();
} catch (Exception e) ...{
this.setErrormsg(e.getMessage());
}
latch.countDown();
}
public void parsePnr() throws Exception ...{
try ...{
RT rt = new RT();
RTResult rtresult = new RTResult();
rtresult = rt.retrieve(this.getPnr());
// System.out.println("****** "+this.getPnr());
// 获取Pnr中的旅客信息
// 获得证件号组,常旅客号组
String foidcard[] = new String[rtresult.getPassengersCount()];
String fqtvcard[] = new String[rtresult.getPassengersCount()];
for (int j = 0; j < rtresult.getSSRsCount(); j++) ...{
PNRSSR pnrssr = rtresult.getSSRAt(j);
// System.out.println(pnrssr.getPsgrID().substring(1)+" card
// "+pnrssr.getServeInfo().substring(12));
if (pnrssr.getSSRType().equalsIgnoreCase("foid"))
foidcard[Integer.parseInt(pnrssr.getPsgrID().substring(1)) - 1] = pnrssr
.getServeInfo().substring(12);
else if (pnrssr.getSSRType().equalsIgnoreCase("fqtv"))
fqtvcard[Integer.parseInt(pnrssr.getPsgrID().substring(1)) - 1] = pnrssr
.getServeInfo().substring(12);
}
// 获取成人组,儿童组 getPassengers
for (int j = 0; j < rtresult.getPassengersCount(); j++) ...{
Passenger passenger = new Passenger();
PNRPassenger pnrp = rtresult.getPassengerAt(j);
passenger.setPsgname(pnrp.getName());
passenger.setType(String.valueOf(pnrp.getType()));
passenger.setPnrno(rtresult.getPnrcode());
// System.out.println("*** " + j + " **** " + foidcard[j]);
passenger.setIdtype(foidcard[j].substring(0, 2));
passenger.setIdcard(foidcard[j].substring(2, foidcard[j]
.indexOf("/")));
passenger.setMembercardnumber(fqtvcard[j] == null ? null
: fqtvcard[j].substring(2, fqtvcard[j].indexOf("/")));
this.passengerlist[pnrp.getType()].add(passenger);
passenger = null;
}
foidcard = null;
fqtvcard = null;
// 获取婴儿组 getInfants
for (int j = 0; j < rtresult.getInfantsCount(); j++) ...{
Passenger passenger = new Passenger();
passenger.setType("2");
PNRInfant infant = rtresult.getInfantAt(j);
passenger.setPsgname(infant.getName());
passenger.setBirthdate(infant.getBrith());
passenger.setCarriedby(rtresult.getPassengerAt(
Integer.parseInt(infant.getCarrier().substring(1)) - 1)
.getName());
this.passengerlist[2].add(passenger);
passenger = null;
}
// 获取Pnr 中的航班信息
// 提取航段信息
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < rtresult.getAirSegsCount(); i++) ...{
Segment seg = new Segment();
PNRAirSeg pnrseg = rtresult.getAirSegAt(i);
seg.setId(new SegmentId(null, new Long(i)));
seg.setCarrier(pnrseg.getAirNo().substring(0, 2));
seg.setFlightno(pnrseg.getAirNo().substring(2));
seg.setDepairport(pnrseg.getOrgCity());
seg.setArrairport(pnrseg.getDesCity());
seg.setDeptime(new Timestamp(format.parse(
pnrseg.getDepartureTime().toLocaleString()).getTime()));
seg.setArrtime(new Timestamp(format.parse(
pnrseg.getArrivalTime().toLocaleString()).getTime()));
seg.setCabin(String.valueOf(pnrseg.getFltClass()));
// 查询机型
FFResult ffr = new FFResult();
try ...{
ffr = new FF().flightTime(pnrseg.getAirNo(), pnrseg
.getDepartureTime());
seg.setPlanetype(ffr.getPlaneModel());
} catch (Exception e) ...{
System.out.println("系统在查询航班 " + pnrseg.getAirNo()
+ " 机型时出错;");
throw new Exception("系统在查询航班 " + pnrseg.getAirNo()
+ " 机型时出错;");
}
seg.setSeatstatus(pnrseg.getActionCode());// 待定
Segmentprice segmentprice = new Segmentprice();
segmentprice.setCarrier(seg.getCarrier());
segmentprice.setFlightno(seg.getFlightno());
segmentprice.setCabin(seg.getCabin());
segmentprice.setDepairport(seg.getDepairport());
segmentprice.setArrairport(seg.getArrairport());
segmentprice.setArrtime(seg.getArrtime());
segmentprice.setFlightdate(seg.getDeptime());
segmentprice.setPlanetype(seg.getPlanetype());
segmentprice.setId(new SegmentpriceId(null, seg.getId()
.getSegorder()));
// 查询价格