我们的微信支付,使用的是第三方的支付,某银行的微信支持渠道。所有的接口请求、应答都是xml格式报文,这样就需要用到xml格式报文的拼装和解析,这儿简单讲一下。

拼接xml格式报文。

从页面表单提交和配置文件中读取出参数,或用实体类接收的页面传来的参数。建立map对象,用put()方法把参数添加进去。然后遍历map,将map转换成xml。


  1. StringBuffer soapResultData = new StringBuffer();
  2. //xml声明
  3. soapResultData.append("<?xml version=\"1.0\" encoding=\"GBK\"?><ROOT><MSG_HEAD>");
  4. //请求头
  5. soapResultData.append(requesttoxml(msgHead));
  6. soapResultData.append("</MSG_HEAD><MSG_BODY>");
  7. //请求体
  8. soapResultData.append(requesttoxml(resmap));
  9. soapResultData.append("</MSG_BODY></ROOT>");


  1. /**
  2. * 将map转化为XML格式的字符串
  3. * @param resmap
  4. * @return
  5. */
  6. public static String requesttoxml(Map<String, String> resmap){
  7. StringBuffer soapResultData = new StringBuffer();
  8. for(String key : resmap.keySet()){
  9. soapResultData.append("<");
  10. soapResultData.append(key);
  11. soapResultData.append(">");
  12. soapResultData.append(resmap.get(key));
  13. soapResultData.append("</");
  14. soapResultData.append(key);
  15. soapResultData.append(">");
  16. }
  17. return soapResultData.toString();
  18. }

将接收到的xml格式报文,转换成实体类。


  1. package com.ustcsoft.business.model;
  2. import java.io.Serializable;
  3. import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
  4. import org.apache.commons.digester3.annotations.rules.ObjectCreate;
  5. @ObjectCreate(pattern = "ROOT/MSG_HEAD")
  6. public class ResponseMsgHead implements Serializable {
  7. /**
  8. *
  9. */
  10. private static final long serialVersionUID = -2793215313546940251L;
  11. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/TRAN_CODE")
  12. private String TRAN_CODE;
  13. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/PARTNER_CODE")
  14. private String PARTNER_CODE;
  15. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/REQUEST_SERIAL")
  16. private String REQUEST_SERIAL;
  17. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/RESPONSE_DATE")
  18. private String RESPONSE_DATE;
  19. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/RESPONSE_TIMESTAMP")
  20. private String RESPONSE_TIMESTAMP;
  21. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/RESULT_CODE")
  22. private String RESULT_CODE;
  23. @BeanPropertySetter(pattern = "ROOT/MSG_HEAD/RESULT_MESSAGE")
  24. private String RESULT_MESSAGE;
  25. //get set 省略,不贴在这儿,自己使用时别忘了生成个set和get方法
  26. }


  1. import static org.apache.commons.digester3.binder.DigesterLoader.newLoader;
  2. import java.io.StringReader;
  3. import java.text.SimpleDateFormat;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import java.util.TreeMap;
  7. import org.apache.commons.digester3.Digester;
  8. import org.apache.commons.digester3.annotations.FromAnnotationsRuleModule;
  9. import org.apache.log4j.Logger;
  10. import com.ustcsoft.business.model.CreditPayResponseBody;;
  11. import com.ustcsoft.business.model.ResponseMsgHead;
  12. import com.ustcsoft.framework.util.HTTPUtil;
  13. import com.ustcsoft.framework.util.XMlUtil;
  14. public class PayService {
  15. private final Map<Class<?>, FromAnnotationsRuleModule> xmlAnnotationModule = new HashMap<Class<?>, FromAnnotationsRuleModule>();
  16. private static final Logger logger=Logger.getLogger(PayService.class);
  17. public PayService() {
  18. xmlAnnotationModule.put(ResponseMsgHead.class,
  19. new FromAnnotationsRuleModule() {
  20. @Override
  21. protected void configureRules() {
  22. bindRulesFrom(ResponseMsgHead.class);
  23. }
  24. });
  25. xmlAnnotationModule.put(CreditPayResponseBody.class,
  26. new FromAnnotationsRuleModule() {
  27. @Override
  28. protected void configureRules() {
  29. bindRulesFrom(CreditPayResponseBody.class);
  30. }
  31. });
  32. }
  33. //中间业务代码省略……
  34. public <T> T parseXml(String xml, Class<T> clazz) throws Exception {
  35. StringReader sr = null;
  36. try {
  37. Digester digester = newLoader(xmlAnnotationModule.get(clazz)).newDigester();
  38. sr = new StringReader(xml);
  39. T pi = digester.parse(sr);
  40. digester.clear();
  41. return pi;
  42. } finally {
  43. if (sr != null) {
  44. sr.close();
  45. }
  46. }
  47. }
  48. }

  1. logger.info("统一下单接口请求报文:"+requestxml);
  2. String resultxml = HTTPUtil.postByHttps(url, requestxml,"GBK");
  3. logger.info("统一下单接口返回报文:"+resultxml);
  4. if(resultxml != null){
  5. resultxml = XMlUtil.xmltoUpperCase(resultxml);//将XML报文中的标签,全部转化为大写
  6. ResponseMsgHead head = parseXml(resultxml, ResponseMsgHead.class);
  7. CreditPayResponseBody body = parseXml(resultxml, CreditPayResponseBody.class);
  8. if (null != head) {
  9. if(head.getRESULT_CODE().equals("000000")){
  10. logger.info("下单成功");
  11. logger.info("返回参数:sub_mch_id="+body.getSUB_MCH_ID()+",total_fee="+body.getTOTAL_FEE()+",out_trade_no="+body.getOUT_TRADE_NO());
  12. return body;
  13. }else{
  14. logger.info("下单失败,错误码:"+head.getRESULT_CODE()+",错误信息:"+head.getRESULT_MESSAGE());
  15. }
  16. }
  17. }


  1. /**
  2. * 将XML报文中的标签,全部转化为大写
  3. * @param xmlMessage
  4. * @return
  5. */
  6. public static String xmltoUpperCase(String xmlMessage) {
  7. Pattern pattern = Pattern.compile("<.+?>");
  8. String xml = xmlMessage.split(">")[0];
  9. String xml0 = xmlMessage.substring(0, xml.length()+1);
  10. String xml1 = xmlMessage.substring(xml.length()+1);
  11. StringBuilder res = new StringBuilder();
  12. int lastIdx = 0;
  13. Matcher matchr = pattern.matcher(xml1);
  14. while (matchr.find()) {
  15. String str = matchr.group();
  16. res.append(xml1.substring(lastIdx, matchr.start()));
  17. res.append(str.toUpperCase());
  18. lastIdx = matchr.end();
  19. }
  20. res.append(xml1.substring(lastIdx));
  21. String result = xml0 + res.toString();
  22. return result;
  23. }

以上就是拼接xml格式报文和解析xml格式报文。需要注意的是,在解析xml格式报文时,由于对方返回的报文的标签有小写的,结果解析出错,所以在里面做了个处理,将标签全部转化为大写。

xml格式报文的拼装,和解析成实体类的更多相关文章

  1. 自动将String类型的XML解析成实体类

    package com.mooc.freemarker2dto; public class BaseDto { } package com.mooc.freemarker2dto; public cl ...

  2. IntelliJ IDEA 通过GsonFormat插件将JSONObject格式的String 解析成实体

    GsonFormat插件主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高. 插件地址:https://plugins.jetbr ...

  3. GsonFormat插件主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高。

    GsonFormat插件主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高. 插件地址:https://plugins.jetbr ...

  4. IDEAL葵花宝典:java代码开发规范插件:GsonFormat插件将JSONObject格式的String 解析成实体

    前言: GsonFormat插件主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高. 这个教程主要是学习IntelliJ IDEA ...

  5. Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)

    上一篇文章我们已经将SQL发送到了数据库,并返回了ResultSet,接下来就是将结果集 ResultSet 自动映射成实体类对象.这样使用者就无需再手动操作结果集,并将数据填充到实体类对象中.这可大 ...

  6. WebApi系列~FromUri参数自动解析成实体的要求

    回到目录 关于webapi我之前写了一些文章,大家可以根据目录去浏览,今天要说的是个怪问题,也是被我忽略的一个问题,当你的Url参数需要被Api自动解析成实体的属性,实事上是要有条件的,不是所以属性都 ...

  7. 复杂xml格式报文和实体类之间的转化

    pom.xml中引入如下依赖: <dependency> <groupId>org.eclipse.persistence</groupId> <artifa ...

  8. ajax交互数据简单拼装,数组成字符串

    json2Form:function(json) { var str = ""; for(var p in json){ // 判断对象是否为数组 if(typeof json[p ...

  9. SpringCloud中接收application/json格式的post请求参数并转化为实体类

    @CrossOrigin(allowCredentials="true", allowedHeaders="*", methods={RequestMethod ...

随机推荐

  1. bzoj 3408 热浪 最短路

    一道最短路的模板题,就当练习一下SPFA和dijkstra了 SPFA #include<bits/stdc++.h> using namespace std; struct edge{ ...

  2. Android设计模式(十二)--抽象工厂模式

    问题: 抽象工厂模式,是一个,狠恶心的模式,那么这个模式在Android有没实用到过呢? 1.定义: 抽象工厂模式:为创建一组相关或者是相互依赖的对象提供一个接口,而不须要指定他们的详细类. 2.使用 ...

  3. OpenCV【2】---读取png图片显示到QT label上的问题

    问题一:   操作图片test.png是一个365x365的PNG图片   通过OpenCV自带的GUI显示出来图像是没问题的,例如以下操作代码所看到的: QStringfileName=QFileD ...

  4. FSM的几种策略

    FSM是什么?FSM就是Finite(有限) State(状态) 机(Machine)的缩写.(之所以中英文混写,是为了强调学懂FSM的原理是根本,刻意去采用“几段式”的写法并不重要) riple F ...

  5. WITH common_table_expression (Transact-SQL)

    https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql Specifi ...

  6. LSTM入门学习——本质上就是比RNN的隐藏层公式稍微复杂了一点点而已

    LSTM入门学习 摘自:http://blog.csdn.net/hjimce/article/details/51234311 下面先给出LSTM的网络结构图: 看到网络结构图好像很复杂的样子,其实 ...

  7. NetFlow是一种数据交换方式,提供网络流量的会话级视图,记录下每个TCP/IP事务的信息

    NetFlow是一种数据交换方式,提供网络流量的会话级视图,记录下每个TCP/IP事务的信息.也许它不能象tcpdump那样提供网络流量的完整记录,但是当汇集起来时,它更加易于管理和易读.Netflo ...

  8. [ Java ][ Eclipse ] 停止讓 Eclipse 跳出 Password Required

    stackoverflow 上,問題的解決方式: http://stackoverflow.com/questions/4713890/how-to-disable-programmatically- ...

  9. AIX 压缩与归档

    .tar.Z 格式 压缩:  compress filename.tar 解压:  zcat filename.tar.Z           tar -xvf -   .tar.gz 格式 压缩:t ...

  10. 在navicat中如何新建连接数据库

    前几天给大家分享了如何安装Navicat,没有来得及上车的小伙伴可以戳这篇文章:手把手教你安装Navicat——靠谱的Navicat安装教程.今天给大家分享一下Navicat的简单使用教程,具体的教程 ...