• [转]IBE傻瓜教程


    一、IBE介绍
    IBE(Internet Booking Engine),即互联网订座引擎,是基于因特网的开放平台技术,它为各种用户应用系统提供访问中国航信传统订座业务系统的途径,是采用API(Application Programming interface)方式的接口。
    二、IBE分类
    IBE接口分为Internal-and-Parser和Client两种,但它们之间没有太大的区别。Internal-and-Parser包中指令类中具有的方法大多为静态方法,所以在每一次执行指令方法时会跟上主机配置。对于Client包中的指令类,只需在新建对象后设置主机配置就行了。
    三、IBE的使用
    3.1主机配置
    主机配置可以采取两种配置方式。
    1、配置文件ibeclient.properties,这里以山航为例,内容如下:
    ibe.client.app=scairetd1
    ibe.client.customn=0
    ibe.client.office=SDH888
    ibe.client.validationno=0
    ibe.server.ip=202.106.139.75
    ibe.server.port=6891
    在调用IBE类时,它会自动查找该配置文件,各航空公司主机配置不同,且设有IP权限,如果不能连接主机,请先确认是否开通IP权限。
    2、写公共方法
    public static void connectHost(IBEClient ibe){
    ibe.setAgentInfo("SDH888", "0", "20");
    ibe.setConnectionInfo("202.106.139.75", 6891);
    ibe.setAppName("scairetd1");
    }
    3.1查询航班
    1、在这里我们还是按照E-TERM的操作流程来为旅客订票,首先是查询航班信息:
    为了方便调用,这里采用的是client包中的方法类。类名:AV 
    方法:getAvailability
    说明:注释中为Internal包中相关API的用法;主机配置各航空公司不同
    public static AvResult av() throws ParseException {// 查询航班
    AV avExample = new AV();// AV指令接口
     //第一步、连接主机,AV实现了IBEClient接口,所以可以使用写的静态方法完成主机配置
    connectHost(avExample);
     //处理查询指令参数,需注意多数方法要求的时间参数格式不同
    Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2012-10-28");
    //第二步、查询航班
    AvResult ar = null;
    try {
    ar = avExample.getAvailability("tao", "pek", date, "sc");
    } catch (Exception e) {
    e.printStackTrace();
    }
    System.out.println(ar);
            //返回查询结果
    return ar;
    }
    3.2、建立PNR
    我们可以根据上一步骤返回的结果生成航段信息,再添加其他信息组,就可以完成PNR的创建。这里采用字符串的方式传递参数,格式和E-TERM中一样。类名:SellSeat
    public static String createPNR() throws Exception {// 新建PNR
    SellSeat ss = new SellSeat();
    //第一步、连接主机
    connectHost(ss);
    //第二步、添加旅客姓名
    String name = "TEST/ADULT";
    ss.addAdult(name);
    //第三步、添加旅客乘坐航段信息
    String airNo = "SC4651";
    char fltClass = 'Y';
    String orgCity = "TAO";
    String dstCity = "PEK";
    String actionCode = "NN";
    int tktNum = 1;
    String departureTime = "2012-10-26";
    ss.addAirSeg(airNo, fltClass, orgCity, dstCity, actionCode, tktNum, departureTime);
    //第四步、添加旅客身份证信息
    String airline = "SC";
    String idtype = "NI";
    String id = "123456789";
    ss.addSSR_FOID(airline, idtype, id, name);
    //第五步、添加旅客联系组信息
    String contactinfo = "15123339999";
    ss.addContact(contactinfo);
    //第六步、添加旅客出票时限
    String dateLimit = "2012-10-25 12:00:00";
    ss.setTimelimit(dateLimit);
    //第七步、添加FC票价计算组
    //字符串参数、格式为FC:出发城市(TAO) 承运航空(SC) 目的城市(PEK) 票面价(600.00) 运价基础(Y)总价(CNY)结束(END)
    String fcStr = "FC:TAO SC PEK 600.00Y CNY600.00END";
    ss.addFC(fcStr);
    /*BookFC对象参数
    BookFC fc= new BookFC();
    fc.addFC("pek", "tao", "sc", "y", 600.00);//多航段多次添加,价格-1
    时表示把该航段价格加到下一航段(最后一个航段),可用于多航段只了解票面总价的情况下使用,在后面的升舱过程由于无数据库保存FC项时可以用到
    ss.addFC(fc);*/
    //第八步、添加FN票价组
    //字符串参数、格式为FN:票面总价(FCNY)/实收价格(SCNY)/代理费率(C3.00)/机建税(TCNY50.00CN)/燃油税(TCNY70.00YQ)
    String fnStr = "FN:FCNY600.00/SCNY600.00/C3.00/TCNY50.00CN/TCNY70.00YQ";
    ss.addFN(fnStr);
             /* //BookFN对象参数
    BookFN fn= new BookFN();
    fn.setAmount(BookFN.F, "CNY", 600.00);//FCNY
    fn.setAmount(BookFN.S, "CNY", 600.00);//SCNY
    fn.setC(3.00);//代理费率
    fn.addTax(BookFN.T, "CNY", 50.00, "CN");//机建
    fn.addTax(BookFN.T, "CNY", 70.00, "YQ");//燃油
    ss.addFN(fn);*/
    //第九步、完成PNR必需信息输入,递交主机,生成PNR
    SSResult ssr = ss.commit1();
    // 返回PNR结果
    System.out.println(ssr.getPnrno());
    return ssr.getPnrno();
    }
    3.2、出票
    类名:ETDZ
    方法: issueTicket
    public static void etdz(String pnr) throws Exception {// 出票
    ETDZ etdz = new ETDZ();
    connectHost(etdz); System.out.println(etdz.issueTicket(pnr, 2));//返回OK
    }
    3.3、改期升舱
    以下只针对单程和往返客票,即旅客只有一张客票的情况下。
    1、首先确认是否需要分离PNR,多旅客(成人、儿童)PNR中部分旅客改期升舱情况下使用。
    类名:Pnrmanage、
    方法:splitPNR 
    public static String split(String pnr) throws Exception {//分离PNR
    PnrManage pm=new PnrManage();
    connectHost(pm);
    String name="test/adult";
    //第一步、创建要分离的旅客集合
    Vectorpassengers=new Vector();
    BookPassenger passenger=new BookPassenger(name);//默认成人
    //对于含儿童的PNR,一般用RT的返回结果设置旅客类型
    //RTResult rs=new RTResult();
    //rs=new RT().retrieve(pnr);
    //passenger.setType(rs.getPassengerAt(n).getType());
    passengers.add(passenger);
    //第二步、分离旅客,返回新PNR号
    String pnrnew=pm.splitPNR("NKHD2P", passengers, 0);//在散客中count参数无意义
    return pnrnew;//新生成的PNR
    }
    2、改期:这里指不需要换开票面的改升操作。
    类名:Pnrmanage
    方法:changeETktAirSeg
    public static void changeDate(String pnr) throws Exception {//改期
    PnrManage pm = new PnrManage();
        connectHost(pm);
    //用旧的航段信息替换新的航段信息
    String str = pm.changeETktAirSeg(pnr, "sc4651", "21sep", "sc4651","23sep", "nn");
    System.out.println("PM:" + str);
    }
    3、升舱:换开票面的改升操作,生产上采用占位PNR的方式实现升舱,且大多原票面信息可以从数据库中提取,所以这里的升舱主要是为了加强对IBE的API学习,了解PNR中各类信息的提取
    类名:Pnrmanage
    方法:updatePnr,传入的参数为要改升的PNR,新添加信息bookinformation,删除所有index[]。
    说明:这里以成人、儿童、带婴儿、往返航段、修改第一个航段为F舱为例,采用部分参数写死的方式,可以学习PNR信息提取相关API的用法。
    注意事项:a、index[]中存放的该条记录在PNR中的行号
    b、改升的时候不要把第一航段的出发日期改到第二航段之前
    c、索引从0开始,行号从1开始。
    d、OI项票联号,往返客票为1200
    e、TKNE项要删除干净,因为要生成新票面,原TKNE中的票号已不能使用
    f、出过票的PNR才能改升
    public static void change(String pnr) throws Exception{
    PnrManage pm=new PnrManage();
    RT rt = new RT();
    // 第一步、连接主机
    connectHost(pm);
    connectHost(rt);
    //第二步、提取PNR
    RTResult rtResult =rt.retrieve(pnr);
    //第三步、创建要删除的信息pnr序号集合
    List indextemp = new ArrayList();
    //第四步、 创建要更新的信息组
    BookInfomation bookInfomation = new BookInfomation();
    //这里以成人、儿童、带婴儿、往返航段、修改第一个航段为F舱为例
    //第五步、添加新的航段组。
    PNRAirSeg oldPNRAirSeg=rtResult.getAirSegAt(0);//航段索引从0开始
    BookAirSeg newBookAirSeg = new BookAirSeg();
    newBookAirSeg.setActionCode("NN");
    newBookAirSeg.setAirNo(oldPNRAirSeg.getAirNo());
    newBookAirSeg.setDepartureTime(oldPNRAirSeg.getDepartureTime());//可以改期
    newBookAirSeg.setOrgCity(oldPNRAirSeg.getOrgCity());
    newBookAirSeg.setDesCity(oldPNRAirSeg.getDesCity());
    newBookAirSeg.setFltClass('F');
    newBookAirSeg.setTktNum(oldPNRAirSeg.getTktNum());
    bookInfomation.addAirSeg(newBookAirSeg);
    indextemp.add(oldPNRAirSeg.getIndex());//添加该pnr序号以待删除
    /*
     *第六步、添加OI项
     */
    //首先获取原PNR票号
    Map infTktNo = new HashMap();// 婴儿原票号
    Map tktNo = new HashMap();// 成人和儿童原票号
    for (int i = 0; i < rtResult.getTktnosCount(); i++) {
    PNRTktNo pnrTktNo =rtResult.getTktnoAt(i) ;
    if (null != pnrTktNo&&"".equals(pnrTktNo.getRemark())) {//成人和儿童的remark为空字符串
    tktNo.put(pnrTktNo.getPsgrID(), pnrTktNo.getTktNo());
    }
    if (null != pnrTktNo&&"IN".equals(pnrTktNo.getRemark())){//婴儿的remark为IN
    infTktNo.put(pnrTktNo.getPsgrID(), pnrTktNo.getTktNo());
    }
    }
    //添加OI项
    Set psgrids = tktNo.keySet();
    Set infPsgrids = infTktNo.keySet();
    String psgrid = "";
    String ticketNo = "";
    //成人和儿童OI
    for (Iterator iterator = psgrids.iterator(); iterator.hasNext();) {
    psgrid = (String) iterator.next();
    ticketNo = tktNo.get(psgrid);
    BookOI oi = new BookOI();
    oi.setCoupon("1200");//单航段客票为1000,指同一张票面上的航段都需要OI
    oi.setPsgrid(psgrid);
    oi.setTktno(ticketNo);
    bookInfomation.addOI(oi);
    }
    //婴儿OI
    for (Iterator iterator = infPsgrids.iterator(); iterator.hasNext();) {
    psgrid = (String) iterator.next();
    ticketNo = infTktNo.get(psgrid);
    BookOI oi = new BookOI();
    oi.setCoupon("1200");
    oi.setPsgrid(psgrid);
    oi.setTktno(ticketNo);
    oi.setInfant(true);//区别
    bookInfomation.addOI(oi);
    }
    /*
     *第七步、添加FC、FN
     */
    /*
     * 因为出过票,FC项已丢失,航段价无法获取,所以采用把新票面总价加到最后一个航段的方式创建FC
     * 对于包含成人、儿童、婴儿的PNR,FC项不同,所以在添加FC项时需添加旅客标识
     */
    /*
     * 确认旅客信息类型
     */
    int adultCnt = 0;// 成人旅客计数
    int infantCnt = 0;// 婴儿旅客计数
    int childCnt = 0;// 儿童旅客计数
    List childNames = new ArrayList();// 儿童姓名集合
    List adultNames = new ArrayList();// 成人姓名集合
    Vector psgrs = rtResult.getPassengers();
    for (int i = 0; i < psgrs.size(); i++) {
    if (PNRPassenger.ADULT == psgrs.get(i).getPassengerType()) {// 判断是否含有成人旅客,确认成人旅客数量
    adultCnt++;
    adultNames.add(psgrs.get(i).getName());
    }
    if (3 == psgrs.get(i).getPassengerType()) {// 判断是否含有儿童旅客,确认儿童旅客数量,因为PNRPassenger.CHILD在API和实际值不同,所以采用数值
    childCnt++;
    childNames.add(psgrs.get(i).getName());
    }
    }
    infantCnt = rtResult.getInfantsCount();// 判断是否含有婴儿旅客,确认婴儿数量
    //成人FC、FN、FP
    if(0!=adultCnt){
    BookFC adultFc = new BookFC();
    adultFc.addFC(rtResult.getAirSegAt(0).getOrgCity(),rtResult.getAirSegAt(0).getDesCity(),
    "SC","F",-1, -1, -1, null, null, false, true,
    null, -1, null, -1, null, null, null);//第四个参数为-1表示此处不填写价格
    adultFc.addFC(rtResult.getAirSegAt(1).getOrgCity(),rtResult.getAirSegAt(1).getDesCity(),
    "SC",String.valueOf(rtResult.getAirSegAt(1).getFltClass()),1200.00, -1, -1, null, null, false, true,
    null, -1, null, -1, null, null, null);//在最后一个航段填写价格1200.00
    for (int k = 0; k < adultNames.size(); k++) {//添加旅客标识
    adultFc.addPsgrname(adultNames.get(k));
    }
    bookInfomation.addFC(adultFc);
    BookFN adultFn = new BookFN();// 成人 FN
    adultFn.setAmount(BookFN.R, "CNY", 1200.00);//新票面价
    adultFn.setAmount(BookFN.S, "CNY", 200.00);//票面差价
    adultFn.setAmount(BookFN.A, "CNY", 200.00);//总差价
    adultFn.setC(0);
    adultFn.addTax(BookFN.T, "CNY", 100.00, "CN");
    adultFn.addTax(BookFN.T, "CNY", 140.00, "YQ");
    for (int k = 0; k < adultNames.size(); k++) {
    adultFn.addPsgrname(adultNames.get(k));
    }
    bookInfomation.addFN(adultFn);
    BookFP fp = new BookFP();// FP不可省掉
    fp.setFp("cc/23");
    bookInfomation.addFP(fp);
    }
    //儿童FC、FN,票价不同
    if(0!=childCnt){
    BookFC childFc = new BookFC();
    childFc.addFC(rtResult.getAirSegAt(0).getOrgCity(),rtResult.getAirSegAt(0).getDesCity(),
    "SC","F",-1, -1, -1, null, null, false, true,
    null, -1, null, -1, null, null, null);//第四个参数为-1表示此处不填写价格
    childFc.addFC(rtResult.getAirSegAt(1).getOrgCity(),rtResult.getAirSegAt(1).getDesCity(),
    "SC",String.valueOf(rtResult.getAirSegAt(1).getFltClass()),600.00, -1, -1, null, null, false, true,
    null, -1, null, -1, null, null, null);//在最后一个航段填写价格
    for (int k = 0; k < childNames.size(); k++) {//添加旅客标识
    childFc.addPsgrname(childNames.get(k));
    }
    bookInfomation.addFC(childFc);
    BookFN childFn = new BookFN();// 儿童FN
    childFn.setAmount(BookFN.R, "CNY", 600.00);//RCNY
    childFn.setAmount(BookFN.S, "CNY", 100.00);//SCNY
    childFn.setAmount(BookFN.A, "CNY", 100.00);//ACNY
    childFn.setC(0);
    childFn.addTax(BookFN.T, "CNY", 140.00, "YQ");
    childFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "CN");
    for (int k = 0; k < childNames.size(); k++) {
    childFn.addPsgrname(childNames.get(k));
    }
    bookInfomation.addFN(childFn);
    if (0 == adultCnt) {//如果没有成人才追加FP
    BookFP fp = new BookFP();// FP
    fp.setFp("cc/23");
    bookInfomation.addFP(fp);
    }
    }
    //婴儿FC、FN、FP,票价不同,特殊标识infant
    if (0 != infantCnt) {
    BookFC infantFc = new BookFC();
    infantFc.addFC(rtResult.getAirSegAt(0).getOrgCity(), rtResult.getAirSegAt(0).getDesCity(), "SC", "F", -1, -1, -1, null,
    null, false, true, null, -1, null, -1, null, null, null);// 第四个参数为-1表示此处不填写价格
    infantFc.addFC(rtResult.getAirSegAt(1).getOrgCity(), rtResult.getAirSegAt(1).getDesCity(), "SC", String.valueOf(rtResult
    .getAirSegAt(1).getFltClass()), 120.00, -1, -1, null, null,
    false, true, null, -1, null, -1, null, null, null);// 在最后一个航段填写价格
    // 婴儿有特殊的标识项,所以可以不添加旅客标识
    infantFc.setInfant(true);
    bookInfomation.addFC(infantFc);
    BookFN infantFn = new BookFN();// 婴儿FN
    infantFn.setAmount(BookFN.F, "CNY", 60.00);
    infantFn.setAmount(BookFN.S, "CNY", 60.00);
    infantFn.setAmount(BookFN.A, "CNY", 60.00);
    infantFn.setC(0);
    infantFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "YQ");
    infantFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "CN");
    infantFn.setInfant(true);//区别标识
    bookInfomation.addFN(infantFn);
    BookFP fp = new BookFP();// FP
    fp.setFp("cc/23");
    fp.setInfant(true);// 区别
    bookInfomation.addFP(fp);
    }
    bookInfomation.setTimelimit("2012-10-23 12:00:00");// TK:TL
    /*
     *第八步、获取要删除T、FN、TN、FP、剩下要修改航段的TKNE的PNR序号
     */
    if (0 != rtResult.getTktsCount()) {// 出票组T
    for (int i = 0; i < rtResult.getTktsCount(); i++) {
    if (null != rtResult.getTktAt(i)) {
    indextemp.add(rtResult.getTktAt(i).getIndex());
    }
    }
    }
    if (0 != rtResult.getFNsCount()) {// FN
    for (int i = 0; i < rtResult.getFNsCount(); i++) {
    if (null != rtResult.getFNAt(i)) {
    indextemp.add(rtResult.getFNAt(i).getIndex());
    }
    }
    }
    if (0 != rtResult.getTktnosCount()) {// TN
    for (int i = 0; i < rtResult.getTktnosCount(); i++) {
    if (null != rtResult.getTktnoAt(i)) {
    indextemp.add(rtResult.getTktnoAt(i).getIndex());
    }
    }
    }
    if (null != rtResult.getFps() && 0 != rtResult.getFps().size()) {// FP
    for (int i = 0; i < rtResult.getFps().size(); i++) {
    if (null != rtResult.getFpAt(i)) {
    indextemp.add(rtResult.getFpAt(i).getIndex());
    }
    }
    }
    if (null != rtResult.getSsrs() && 0 != rtResult.getSSRsCount()) {// TKNE
    for (int i = 0; i < rtResult.getSSRsCount(); i++) {
    if (null != rtResult.getSSRAt(i)) {
    if ("TKNE".equals(rtResult.getSSRAt(i).getSSRType())) {
    indextemp.add(rtResult.getSSRAt(i).getIndex());
    }
    }
    }
    }
    Integer[] indexsTemp=(Integer[])indextemp.toArray(new Integer[0]);
    int[]index=new int[indexsTemp.length];
    for(int i=0;ilength;i++){
    index[i]=indexsTemp[i].intValue();
    }
    //第九步、升舱
    String status=pm.updatePnr(pnr, bookInfomation, index);
    //第十步、打印出票
    if("OK".equals(status)){
    etdz(pnr);
    }
    3.4退票
    1、在E-TERM中填写退票单后票面上该航段会自动refunded,但使用IBE接口需要自己手动去refunded票面。
    2、对于往返航段,已经退过一个航段的客票,需要提取该退票单并修改,以保留上次退票信息。
    public static void trfd(String tktNo) throws Exception {// 退票
    //第一步、 REFUNDED票面上的航段状态
    ETRF etrf = new ETRF();
    connectHost(etrf);
    etrf.refundETkt(tktNo, 1, "CNY", 1200.00, "1", "");
    //第二步、 填写退票单,连接主机
    TRFD trfd = new TRFD();
    connectHost(trfd);
    TRFDResult result = null;
    //第三步、 生成退票单。先尝试获取退票单,如果没有则新生成一个新退票单。
    try {
    result = trfd.genRefundForm("tm", 2, "D", tktNo);
    } catch (IBEException e) {
    if (!e.getMessage().contains("CAN NOT PRINT NEW REFUND")) {// 判断是否已经生成过退票单
    throw e;
    }
    //第四步、 生成新的退票单
    result = trfd.genRefundForm("AM", 2, "D", null);
    result.setTktNo(tktNo.split("-")[1]);
    result.setRefund("N");
    result.setPassName("SC");
    result.setAirlineCode(tktNo.split("-")[0]);
    result.setCommissionRate(0);
    }
    //第五步、填写/修改退票单信息
    result.setTax(0, 100.00, "CN");
    result.setTax(1, 140.00, "YQ");
    result.setDeduction(22);// 手续费
    result.setGrossRefund(1000.00);
    result.setCouponNo(0, "1200"); // 新票联号
    String s = trfd.changeRefundForm_new(result, false);
    System.out.println(s);
    }

  • 相关阅读:
    mybatis 梳理9--别名
    mybatis 梳理8--多个参数 @Param
    mybatis 梳理7--map的使用 (很好用)
    mybatis 梳理6--模糊查询
    mybatis 梳理5-- 增删改查 基于注解 (少)
    mybatis 梳理4--增删改查 基于配置文件(多)
    mybatis 梳理3--搭建环境 小栗子 结合 梳理10 复习
    mybatis 梳理2--代理设计模式 静态代理、动态代理(Proxy) (懵)
    mybatis 梳理1--文档官网、简介、持久化、持久层、持久层框架
    梳理5--核心配置文件pom 基础配置、构建配置、插件(记得!)、区别dependencies 和 dependencyManagement
  • 原文地址:https://www.cnblogs.com/achengmu/p/14019257.html
Copyright © 2020-2023  润新知