在系统用户交费后,需要打印发票,可以选择普票或者机打票(票据信息在系统中自定义设置的),也可以打印电子发票,这里对接的是航信的电子发票,请求方式非web服务,而是使用servlet通过HTTP请求的方式获取报文。

整个开票流程如下:

本地组装发票明细信息到报文(内部报文加密)——》将组装好的发票信息发往税控服务器——》成功的话解析返回的信息——》发票打印

报文格式:

实际测试报文如下:

<?xml version="1.0" encoding="utf-8"?>

<SERVICE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HEAD>
<nsrsbh>140115728183815</nsrsbh>
<serviceversion>1.3</serviceversion>
<serviceid>jy.dzptfpkj.hc</serviceid>
<iszip>N</iszip>
<issyn>Y</issyn>
<encryptcode>0</encryptcode>
<RTNINF/>
</HEAD>
<BODY>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KCjxSRVFVRVNUX0ZQS0pYWD4KICA8RlBLSlhYX0ZQVFhYPgogICAgPGRqcnEvPgogICAgPHhzZGgvPgogICAgPGZwbHg+MTA8L2ZwbHg+CiAgICA8Z2ZtYz7otK3kubDmlrk8L2dmbWM+CiAgICA8Z2Zuc3JzYmg+MTIzNDU2Nzg5MTIzNDU2PC9nZm5zcnNiaD4KICAgIDxnZmR6ZGg+6LSt5Lmw5pa55Zyw5Z2A55S16K+dPC9nZmR6ZGg+CiAgICA8Z2Z5aGp6aD7otK3kubDmlrnpk7booYzpk7booYw8L2dmeWhqemg+CiAgICA8Z2Zzai8+CiAgICA8Z2Z5eC8+CiAgICA8Yno+MTIzPC9iej4KICAgIDxrcHk+57O757uf566h55CG5ZGYPC9rcHk+CiAgICA8c2t5PmpjY3M8L3NreT4KICAgIDxmaHI+6KKB57+g6JCNPC9maHI+CiAgICA8aHNiej4xPC9oc2J6PgogICAgPHNsLz4KICAgIDx3Y3R6PjA8L3djdHo+CiAgICA8cnlkbT5hZG1pbjwvcnlkbT4KICAgIDxjaHl5PjEyMzwvY2h5eT4KICAgIDxmcHh6PjA8L2ZweHo+CiAgICA8dHNjaGJ6PjE8L3RzY2hiej4KICAgIDx5ZnBkbT4wMTQwMDEzMDAxMTE8L3lmcGRtPgogICAgPHlmcGhtPjIyMDM0MDk4PC95ZnBobT4KICAgIDxieXpkMS8+CiAgICA8Ynl6ZDIvPgogICAgPGJ5emQzLz4KICAgIDxieXpkNC8+CiAgICA8Ynl6ZDUvPgogIDwvRlBLSlhYX0ZQVFhYPgogIDxGUEtKWFhfWE1YWFM+CiAgICA8RlBLSlhYX1hNWFg+CiAgICAgIDxzcGZsZG0vPgogICAgICA8c3Bsd21jPuWfuuehgOawtOi0uTwvc3Bsd21jPgogICAgICA8Z2d4aD7llYbkuJo8L2dneGg+CiAgICAgIDxkdz4xPC9kdz4KICAgICAgPHNtLz4KICAgICAgPGNvdW50Pi0xPC9jb3VudD4KICAgICAgPHByaWNlPjkuNzA4NzM4PC9wcmljZT4KICAgICAgPGplPi05LjcxPC9qZT4KICAgICAgPHNsPjAuMDM8L3NsPgogICAgICA8c2U+LTAuMjk8L3NlPgogICAgICA8c3NmbGJtPjExMDAzMDEwMTAwMDAwMDAwMDA8L3NzZmxibT4KICAgICAgPGJtYmJoLz4KICAgICAgPGxzbGJzLz4KICAgICAgPHloemNicz4wPC95aHpjYnM+CiAgICAgIDx5aHpjc20vPgogICAgICA8ZnBoeHo+MDwvZnBoeHo+CiAgICAgIDxieXpkMS8+CiAgICAgIDxieXpkMi8+CiAgICAgIDxieXpkMy8+CiAgICAgIDxieXpkNC8+CiAgICAgIDxieXpkNS8+CiAgICA8L0ZQS0pYWF9YTVhYPgogIDwvRlBLSlhYX1hNWFhTPgo8L1JFUVVFU1RfRlBLSlhYPgo=</BODY>
</SERVICE>

主要代码如下:

1. 页面选打印电子发票后,确定进入下面方法

public Result printElectronic(PrintInvoiceEntity entity) {
// 电子发票不允许进行预览
if (entity.getIsPreview()) {
return new Result(Status.ERROR, null, "电子发票不允许进行预览!");
}
if (PrintCallingTypeEnum.HEATING.getCode().equals(entity.getPrintCallingType())) {
//打印热费的电子发票
return this.printElectronicForHeating(entity);
} else {
return new Result(Status.ERROR, null, "未指定打印票据的调用方式!");
}
}

附:相关实体类

public class PrintInvoiceEntity {

    /* ------------------- 非必填字段 ---------------------*/
private String volumeCode;//票据册号(当票据类型为电子发票时非必填) /* ------------------- 必填字段 ---------------------*/
private String companyCode;//开票公司编码 private String gmf_mc;//购买方名称
private String gmf_nsrsbh;//购买方纳税人识别号
private String gmf_dzdh;//购买方地址电话
private String gmf_yhzh;//购买方银行账户 private String bz;//备注 private String card_no;
private String create_time; private String printCallingType;//打印调用方式
private Boolean isPreview;//是否预览模式
private Boolean isPreprint;//是否预开模式
private String invoiceType;//票据类型 List<PjItemEntity> pjItemEntities;//票据打印明细

2. 打印电子发票方法

    private Result printElectronicForHeating(PrintInvoiceEntity entity) {
// 正常采暖费交费时,获取上年结余
printInvoiceService.initSurplus(entity.getPjItemEntities()); // 根据交易明细组装发票明细信息
List<Invoice> invoices = printInvoiceService.splitInvoice(
SessionUtil.getUser(), entity); // 调用航信税控进行打票
List<Map<String, String>> returnMsg = this.printForHeating(invoices,
entity, null); if (returnMsg.isEmpty()) {
return new Result(Status.ERROR, null, "电子发票开具失败!");
}
return new Result(Status.OK, null, returnMsg);
}

3. 组装发票明细信息

   // 将交易明细拆分成发票
public List<Invoice> splitInvoice(User operator, PrintInvoiceEntity entity) {
List<Invoice> invoices = new ArrayList<Invoice>(); // 1.初始化字典项数据
Map<String, String> chargeItemDict = initChargeItemDict();// 收费项目
// Map<String, Dict> unitPriceTypeDict = initUnitPriceTypeDict();// 单价类别
Map<String, Dict> areaTypeDict = initAreaTypeDict();// 面积类别
Map<String, XtwhTaxRate> taxRateDict = initTaxRateDict(); // 税率
Map<String, SfOtherCost> otherCostDict = initOtherCostDict(); // 第三方费用 List<PjItemEntity> pjItemEntities = entity.getPjItemEntities();
String customerIds = pjItemEntities.get(0).getSysattachment()
.get(InvoiceInfoConstant.CUSTOMER_COLLECTION_ALIAS);
String[] idArray = customerIds.split(","); String companyCode = this.getCompanyCode(entity, idArray[0]);
String prjName = DeployConfigUtil.getJcDeployConfig().getProjectName();
JcCustomer jccustomer = this.getJccustomer(entity, idArray[0]);
String userKindType =null;
if (jccustomer !=null) {
userKindType= jccustomer.getUserKindCode();
}
// 4.获取公共的发票抬头模板
InvoiceSummary commonSummary = this.createInvoiceSummary(operator,
companyCode); for (int i = 0; i < pjItemEntities.size(); i++) {
// 浅复制发票抬头对象
InvoiceSummary summary = commonSummary.clone();
// 发票请求流水号
summary.setFpqqlsh(SerialNumberUtil.getNextNumber(2));
// 1.同步购买方信息
summary.setGmf_mc(entity.getGmf_mc());// 销售方-名称
summary.setGmf_nsrsbh(entity.getGmf_nsrsbh());// 销售方-纳税人识别号
summary.setGmf_dzdh(entity.getGmf_dzdh());// 销售方-地址电话
summary.setGmf_yhzh(entity.getGmf_yhzh());// 销售方-银行账户
summary.setCard_no (entity.getCard_no());// 销售方-银行账户
summary.setCreate_time (entity.getCreate_time());// 销售方-银行账户
if ("0".equals(prjName)) {
summary.setBz(entity.getBz());
} else if("1".equals(prjName)){
if (jccustomer!=null && "user_type_2".equals(jccustomer.getUserTypeCode())) { // 二部制用户
summary.setBz(entity.getBz()+", 上年结余:"+pjItemEntities.get(i).getSurplus());// 备注
}else{
summary.setBz(entity.getBz());
}
} Invoice invoice = this.splitInvoiceDetail(
entity.getPrintCallingType(), summary,
pjItemEntities.subList(i, i + 1), chargeItemDict,
areaTypeDict, taxRateDict, otherCostDict, userKindType);
invoices.add(invoice);
}
return invoices;
}

将交易明细拆分成发票上的多个明细项

public Invoice splitInvoiceDetail(String printCallingType,
InvoiceSummary summary, List<PjItemEntity> pjItemEntities,
Map<String, String> chargeItemDict, Map<String, Dict> areaTypeDict,
Map<String, XtwhTaxRate> taxRateDict,
Map<String, SfOtherCost> otherCostDict, String userKindType) {
List<InvoiceDetail> invoiceDetails = new ArrayList<InvoiceDetail>();
for (PjItemEntity pjItemEntity : pjItemEntities) {
// 交易明细为热费
List<InvoiceDetail> list = this.createInvoiceDetailsByHeatingCost(
printCallingType, pjItemEntity, chargeItemDict,
areaTypeDict, taxRateDict , userKindType);
invoiceDetails.addAll(list);
} // 2.同步合计金额
BigDecimal hjje = BigDecimal.ZERO;// 合计金额
BigDecimal hjse = BigDecimal.ZERO;// 合金税额
for (InvoiceDetail invoiceDetail : invoiceDetails) {
hjje = BigDecimalUtil.add(hjje,
new BigDecimal(invoiceDetail.getXmje()));
hjse = BigDecimalUtil.add(hjse,
new BigDecimal(invoiceDetail.getSe()));
}
summary.setHjje(hjje.toString());
summary.setHjse(hjse.toString());
BigDecimal jshj = BigDecimalUtil.add(hjje, hjse);// 价税合计
summary.setJshj(jshj.toString()); // 3.组装发票
Invoice invoice = new Invoice();
invoice.setSummary(summary);
invoice.setDetails(invoiceDetails);
return invoice;
}

相关实体:

public class Invoice    {//发票实体
private InvoiceSummary summary; //发票抬头信息
private List<InvoiceDetail> details; //发票项目明细信息
public class InvoiceSummary implements Cloneable{//发票抬头信息实体

    private Long pjInfoId; //票据表ID
private String fp_dm; // 发票代码
private String fp_hm; // 发票号码
private String fp_ch; // 发票册号 private String fpqqlsh; // <FPQQLSH>发票请求流水号</FPQQLSH>
private String kplx; // <KPLX>开票类型</KPLX>
private String xsf_nsrsbh; // <XSF_NSRSBH>销售方纳税人识别号</XSF_NSRSBH>
private String xsf_mc; // <XSF_MC>销售方名称</XSF_MC>
private String xsf_dzdh; // <XSF_DZDH>销售方地址、电话</XSF_DZDH>
private String xsf_yhzh; // <XSF_YHZH>销售方银行账号</XSF_YHZH> 否
private String gmf_nsrsbh; // <GMF_NSRSBH>购买方纳税人识别号</GMF_NSRSBH> 否
private String gmf_mc; // <GMF_MC>购买方名称</GMF_MC>
private String gmf_dzdh; // <GMF_DZDH>购买方地址、电话</GMF_DZDH> 否
private String gmf_yhzh; // <GMF_YHZH>购买方银行账号</GMF_YHZH> 否
private String kpr; // <KPR>开票人</KPR>
private String skr; // <SKR>收款人</SKR> 否
private String fhr; // <FHR>复核人</FHR> 否
private String yfp_dm; // <YFP_DM>原发票代码</YFP_DM>红字发票时必须填写
private String yfp_hm; // <YFP_HM>原发票号码</YFP_HM> 红字发票时必须填写
private String jshj; // <JSHJ>价税合计</JSHJ>单位:元(2位小数)
private String hjje; // <HJJE>合计金额</HJJE>不含税,单位:元(2位小数)
private String hjse; // <HJSE>合计税额</HJSE>单位:元(2位小数)
private String bmb_bbh;// <BMB_BBH>编码表版本号</BMB_BBH>目前为1.0
private String qd_bz;// <QD_BZ>清单标志</QD_BZ>0:根据项目名称字数,自动产生清单,保持目前逻辑不变1:取清单对应票面内容字段打印到发票票面上,将项目信息 XMXX 打印到清单上。默认为 0。 1 暂不支持
private String qdxmmc;// <QDXMMC>清单项目名称</QDXMMC>否 需要打印清单时对应发票票面项目名称清单标识( QD_BZ)为 1 时必填。为 0不进行处理。
private String ghf_sj; // <GHF_SJ>购货方手机</GHF_SJ> 否
private String ghf_email; // <GHF_EMAIL>购货方邮箱</GHF_EMAIL> 否
private String bz; // <BZ>备注</BZ> 否
private String card_no; // <BZ>用户卡号</BZ> 否
private String create_time; // <BZ>交易时间</BZ> 否

4. 调用航信税控进行打票

public List<Map<String, String>> printForHeating(List<Invoice> invoices,
PrintInvoiceEntity entity, PjInfo bluePjinfo) {
List<Map<String, String>> returnMsg = new ArrayList<Map<String, String>>();
String prjName = DeployConfigUtil.getJcDeployConfig().getProjectName();// 0:项目A 1:项目B
// 将组装好的发票信息发往税控服务器进行电子发票打印
String requestXml = null; // 请求报文
String returnXml = null; // 请求报文对应的返回报文
InvoiceReturnEntity invoiceReturnEntity = null; // 开票返回报文对应的实体
PjItemEntity pjItemEntity = null; // 票据打印原始数据
Invoice invoice = null; // 票据实体
PjInfo pjInfo = null;
for (int i = 0; i < invoices.size(); i++) { invoice = invoices.get(i);
pjItemEntity = entity.getPjItemEntities().get(i);
JcCustomer jcCustomer = printInvoiceService.getJccustomer(entity,pjItemEntity.getCustomerId().toString());
String userKindType=null;
if (jcCustomer != null) {
userKindType = jcCustomer.getUserKindCode();
}
// 将开具的电子发票信息保存到收费系统票据信息表中
pjInfo = ElnvoiceEntityUtil.createPjInfo(
entity.getPrintCallingType(), entity.getIsPreprint(),
invoice, bluePjinfo);
pjInfoService.insert(pjInfo);
//蓝票冲红
if(bluePjinfo != null){
invoice.getSummary().setPjInfoId(bluePjinfo.getId());
}else{
invoice.getSummary().setPjInfoId(pjInfo.getId());
} if ("0".equals(prjName)) {
if (StringUtils.defaultString(invoice.getSummary().getYfp_dm()).length() > 0
&& StringUtils.defaultString(invoice.getSummary().getYfp_hm()).length() > 0) {
// 封装航信电子发票所需报文--红冲
requestXml = LFEInvoiceXmlUtil.createHCEInvoiceXml(invoice,userKindType);
} else {
// 封装航信电子发票所需报文
requestXml = LFEInvoiceXmlUtil.createEInvoiceXml(invoice, userKindType);
} // 请求航信开票接口开具报文
returnXml = EInvoiceWsUtil.eInvoice(requestXml);
// 解析返回报文
invoiceReturnEntity = LFElnvoiceEntityUtil.createInvoiceReturnEntity(returnXml);
} else { if (StringUtils.defaultString(invoice.getSummary().getYfp_dm()).length() > 0
&& StringUtils.defaultString(invoice.getSummary().getYfp_hm()).length() > 0) {
// 封装航信电子发票所需报文--红冲
requestXml = EInvoiceXmlUtil.createHCEInvoiceXml(invoice);
} else {// 封装航信电子发票所需报文
requestXml = EInvoiceXmlUtil.createEInvoiceXml(invoice);
} // 请求航信开票接口开具报文
returnXml = EInvoiceWsUtil.eInvoice(requestXml);
// 解析返回报文
invoiceReturnEntity = ElnvoiceEntityUtil.createInvoiceReturnEntity(returnXml);
}
if (!RETURN_CODE_SUCCESS
.equals(invoiceReturnEntity.getReturnCode())) { continue;
}
// 将开具的电子发票信息保存到收费系统票据信息表中
pjInfo = ElnvoiceEntityUtil.updatePjInfo(pjInfo, invoiceReturnEntity);
pjInfoService.updateById(pjInfo);
// 记录开票明细
printInvoiceService.savepjItem(pjInfo.getId(), pjItemEntity);
// 挂上电子发票与热用户的关联关系
printInvoiceService.savePjCustomerRelation(pjInfo.getId(),pjItemEntity);
// 更新交易明细为已开票状态
printInvoiceService.updateInvoiceStatusForHeating(entity.getPrintCallingType(), pjItemEntity);
// 推送到财务,此处正常开票、补打、冲红、集体交费逐户打印、全部打印都调用
printInvoiceService.insertRfglFinance(pjItemEntity, pjInfo, invoice);
// 根据票据号请求电子发票下载地址
/* invoiceQueryEntity = ElnvoiceEntityUtil.createQueryInvoiceEntity(pjInfo);
requestXml = EInvoiceXmlUtil.createQueryInvoiceXml(invoiceQueryEntity);
returnXml = EInvoiceWsUtil.queryInvoice(requestXml);
queryReturnEntity = ElnvoiceEntityUtil.createQueryReturnEntity(returnXml);*/
// 封装前台返回信息
Map<String, String> map = new HashMap<String, String>();
map.put("fpdm", invoiceReturnEntity.getFp_dm());
map.put("fphm", invoiceReturnEntity.getFp_hm());
map.put("downloadUrl", invoiceReturnEntity.getPdfUrl());
returnMsg.add(map); //下载pdf到本地
if(StringUtils.isNotEmpty(invoiceReturnEntity.getPdfUrl())){
try {
downLoadByUrl(invoiceReturnEntity.getPdfUrl());
} catch (IOException e) {
System.err.println("电子发票- PDF下载失败!");
e.printStackTrace();
}
}
}
return returnMsg;
}

相关实体:

public class InvoiceReturnEntity { //电子发票-请求开具发票返回报文对应的实体

    private String fpqqlsh; //<FPQQLSH>发票请求流水号</FPQQLSH>
private String jqbh;//<JQBH>税控设备编号</JQBH>
private String fp_dm;//<FP_DM>发票代码</FP_DM>
private String fp_hm;//<FP_HM>发票号码</FP_HM>
private String kprq;//<KPRQ>开票日期</KPRQ>
private String fp_mw;//<FP_MW>发票密文</FP_MW>
private String jym;//<JYM>校验码</JYM>
private String ewm;//<EWM>二维码</EWM>
private String returnCode;//<RETURNCODE>返回代码</RETURNCODE>
private String returnMsg;//<RETURNMSG>返回信息</RETURNMSG> private String ssyf;// 所属月份
private String kplx;// 开票类型1-正票 2-红票
private String hjbhsje;// 合计不含税金额
private String kphjse;// 开票合计税额
private String czdm;// 10-正常开具 20-红票
private String pdfFile;// PDF文件
private String pdfUrl;// PDF下载路径

5. 封装航信电子发票所需报文——》发送到航信接口开具报文——》解析包含开票信息的返回报文

5.1 生成电子发票开具报文

public static String createEInvoiceXml(Invoice invoice, String userKindType){
Document document = DocumentHelper.createDocument();
document.setXMLEncoding("utf-8"); // 默认utf-8
Element rootElement = getRoolElement(document, "");
String cdataXml =createEInvoiceCDATA(invoice, userKindType); //内部报文加密
Base64Encoder encoder = new Base64Encoder();
String comment = encoder.encode(cdataXml.getBytes());
Element dataElement = rootElement.element("Data");
dataElement.element("content").addText(comment);
//xml文件"< >"禁止转义,保留<>样式的方法
String xml = StringEscapeUtils.unescapeXml(document.asXML()); return xml ;
}

5.2 调用税控开具发票接口

public static String eInvoice(String wsXml){
String methodName = "eInvoiceCodes";
return EInvoiceWsUtil.invoke(methodName, wsXml);
}
//调用远程服务接口的公共方法,获得包含开票信息的返回报文
public static String invoke(String methodName, String wsXml){ CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(webServiceUrl);// 创建httpPost
httpPost.setHeader("Accept", "text/xml");
httpPost.setHeader("Content-Type", "text/xml");
String charSet = "UTF-8";
StringEntity entity = new StringEntity(wsXml, charSet);
httpPost.setEntity(entity);
CloseableHttpResponse response = null; try {
response = httpclient.execute(httpPost); StatusLine status = response.getStatusLine();
int state = status.getStatusCode();
if (state == 200) {
HttpEntity responseEntity = response.getEntity();
String jsonString = EntityUtils.toString(responseEntity);
System.out.println("---response----"+jsonString);
return jsonString;
}
else{
System.err.print("请求返回:"+state+"("+webServiceUrl+")");
}
} catch(IOException e){
e.printStackTrace();
}
finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}

5.3 解析返回报文,将信息保存进返回报文实体类

public static InvoiceReturnEntity createInvoiceReturnEntity(String returnXml){

        InvoiceReturnEntity entity = new InvoiceReturnEntity();
try {
Document document = DocumentHelper.parseText(returnXml);
Element rootElement = document.getRootElement(); //business标签
Element element = null;
Element headElement = rootElement.element("interface");
Element rtnElement = headElement.element("returnStateInfo");
String rtnCode = rtnElement.element("returnCode").getTextTrim();
Element dataElement = rootElement.element("Data");
//开票成功返回code
if("0000".equals(rtnCode)){
// base64解码
String cdataXml = dataElement.element("content").getTextTrim();
String bodyXml = base64Decoder(cdataXml);
Document bodyDoc = DocumentHelper.parseText(bodyXml);
Element bodyElement = bodyDoc.getRootElement(); element = bodyElement.element("FPQQLSH");
entity.setFpqqlsh(element.getTextTrim()); element = bodyElement.element("FP_DM");
entity.setFp_dm(element.getTextTrim()); element = bodyElement.element("FP_HM");
entity.setFp_hm(element.getTextTrim()); element = bodyElement.element("KPRQ");
entity.setKprq(element.getTextTrim()); element = bodyElement.element("PDF_URL");
entity.setPdfUrl(element.getTextTrim());
} entity.setReturnCode(rtnCode); element = rtnElement.element("RETURNMESSAGE");
entity.setReturnMsg(element.getTextTrim()); } catch (DocumentException e) {
System.err.println("电子发票-开具发票请求的返回报文解析失败!");
e.printStackTrace();
} return entity;
}

6. 从网络Url中下载发票信息的pdf文件

  public  void  downLoadByUrl(String urlStr) throws IOException{
URL url = new URL(urlStr);
String[] str= urlStr.split("/");
String fileName= str[str.length-1]+".pdf";
String savePath = "C://upload";
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置超时间为3秒
conn.setConnectTimeout(2*1000);
//防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//得到输入流
InputStream inputStream = conn.getInputStream();
//获取自己数组
byte[] getData = readInputStream(inputStream);
//文件保存位置
File saveDir = new File(savePath);
if(!saveDir.exists()){
saveDir.mkdir();
}
File file = new File(saveDir+File.separator+fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(getData);
if(fos!=null){
fos.close();
}
if(inputStream!=null){
inputStream.close();
} } // 从输入流中获取字节数组
public byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}

接口规范说明文档下载地址

航信电子发票开发(servlet请求方式)的更多相关文章

  1. servlet三种实现方式之三通过继承HttpServlet开发servlet

    servlet有三种实现方式: 1.实现servlet接口 2.继承GenericServlet 3.通过继承HttpServlet开发servlet 第三种: import java.io.*; i ...

  2. 开发servlet三种方式

    第一种:实现Servlet接口 ServletDemo类 实现Servlet接口 public class ServletDemo implements Servlet { //初始化该servlet ...

  3. Servlet请求参数的方式

    今天整理了以下几种常用的Servlet请求参数的方式,下面简单地介绍 1)getParameter(String key)返回一个字符串,获得name和key 一样的表单控件的数据,如果有重复的nam ...

  4. JAVAEE 和项目开发(第三课:HTTP的请求头和请求方式)

    HTTP 协议之请求格式   请求格式的结构:请求行:请求方式.请求的地址和 HTTP 协议版本 请求头:消息报头,一般用来说明客户端要使用的一些附加信息 空行: 位于请求行和请求数据之间,空行是必须 ...

  5. <<海闻电子发票接口 ESB 封装 代码指示 文档>>

    <<海闻电子发票接口 ESB 封装 代码指示 文档>> isValid 是否有效标志 代码 中文 说明 true 成功 false 失败   code 海闻错误说明 代码 中文 ...

  6. <<海闻电子发票接口 ESB 封装文档>>

    <<海闻电子发票接口 ESB 封装文档>> 章节目录结构: 发票验证接口 发票开具接口 ESB请求地址: 发票验证接口: http://10.15.22.120:8866/42 ...

  7. Servlet程序开发--Servlet 与 表单

    servlet程序: doPost方法时为了防止表单提交时post方式的问题.否则只能处理get请求 package org.lxh.servletdemo ; import java.io.* ; ...

  8. Servlet底层原理、Servlet实现方式、Servlet生命周期

    Servlet简介 Servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. Servlet的特点 (1)Servlet对像,由Servlet容器 ...

  9. Web地图服务、WMS 请求方式、网络地图服务(WMS)的三大操作

    转自奔跑的熊猫原文 Web地图服务.WMS 请求方式.网络地图服务(WMS)的三大操作 1.GeoServer(地理信息系统服务器) GeoServer是OpenGIS Web 服务器规范的 J2EE ...

随机推荐

  1. CListCtrl 之右键菜单

    在使用CListCtrl时要为它添加一个右键菜单,步骤如下: 1. 响应CListCtrl的NM_RCLICK消息. 2. 添加一个菜单资源,在菜单资源中插入要添加到菜单内容.   一般存在两种方法: ...

  2. grunt-cmd-transport提取deps[]的BUG

    该BUG已经在GitHub上提了issue,详见:#56 文件 // employee/static/adder.js define(function (require, exports) { exp ...

  3. 【转】TensorFlow四种Cross Entropy算法实现和应用

    http://www.jianshu.com/p/75f7e60dae95 作者:陈迪豪 来源:CSDNhttp://dataunion.org/26447.html 交叉熵介绍 交叉熵(Cross ...

  4. RAMPS1.4 3d打印控制板接线与测试3

    RAMPS1.4作为mega2560的拓展板插在mega板子上面.从而让mega板子可以控制3d打印机的工作.ramps上的接线至关重要,接错不仅不能打印,甚至还会烧坏器件和板子.请一定注意. 我的淘 ...

  5. 如何屏蔽ctrl + v 粘贴事件,鼠标右键粘贴事件

    通常在自己的APP里的密码框,验证码框需要屏蔽复制,粘贴,怎么办呢? 有三种方法: 1 hook 此方法是最完全的,但由于hook是全局的,容易影响到其它代码. 2 子类化文本框, 重写OnPaste ...

  6. [Spring Boot] @Component, @AutoWired and @Primary

    Spring boot is really good for Dependencies injection by using Autowiring. Each class instancse in s ...

  7. 杂谈:大容量(T级容量)的网盘的意义

    这两天,大容量的网盘的消息不断的推出.有百度的网盘推1T容量的:有腾讯的推10T容量的:有的还推不限容量的等等不一而足. 先看看大容量网盘的历史 早先是没有网盘这个概念的.能提供免费空间是电子邮箱 早 ...

  8. template.helper 多参数

    <script type="text/html" id="text4"> {{detail name classInfo schoolInfo}} ...

  9. pycharm+python+Django之web开发环境的搭建(windows)

    转载:https://blog.csdn.net/yjx2323999451/article/details/53200243/ pycharm+python+Django之web开发环境的搭建(wi ...

  10. 编译安装openssl报错:POD document had syntax errors at /usr/bin/pod2man line 69. make: *** [install_docs]

    错误如下: cms.pod around line 457: Expected text after =item, not a number cms.pod around line 461: Expe ...