我们的微信支付,使用的是第三方的支付,某银行的微信支持渠道。所有的接口请求、应答都是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. 转移顺序的艺术 luogu4394 + lougu2966 + luogu3537

    lougu4394: N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好. 对于一个联合内阁,如果某个政党退 ...

  2. Java基础学习总结(11)——重载与重写

    首先我们来讲讲:重载(Overloading) 一.方法的重载 方法名一样,但参数不一样,这就是重载(overload). 所谓的参数不一样,主要有两点:第一是参数的个数不一样,第二是参数的类型不一样 ...

  3. Vs2012在Linux开发中的应用(1):开发环境

    在Linux的开发过程中使用过多个IDE.code::blocks.eclipse.source insight.还有嵌入式厂商提供的各种IDE.如VisualDsp等,感觉总是不如vs强大好用.尽管 ...

  4. atitit.js&#160;与c#&#160;java交互html5化的原理与总结.doc

    atitit.js 与c# java交互html5化的原理与总结.doc 1. 实现html5化界面的要解决的策略 1 1.1. Js交互 1 1.2. 动态參数个数 1 1.3. 事件监听 2 2. ...

  5. Create the Project

    https://docs.microsoft.com/en-us/aspnet/web-forms/overview/getting-started/getting-started-with-aspn ...

  6. 26.angularJS $routeProvider

    转自:https://www.cnblogs.com/best/tag/Angular/ O'Reilly书上的伪代码 var someModule = angular.module('someMod ...

  7. Python(六) Python 函数

    一.认识函数 help(方法名字)  help(round) 1.功能性 2.隐藏细节 3.避免编写重复的代码 4.组织代码 自定义函数 二.函数的定义及运行特点 # 递归 def sum_num(n ...

  8. 1sting

    You will be given a string which only contains ‘1’; You can merge two adjacent ‘1’ to be ‘2’, or lea ...

  9. xcode 条件调试

    添加条件 有时候我们可能会在某个循环中创建断点,但一次又一次地点击 continue 直到我们想要的条件出现,显然是一种非常低效的方式.好在 Xcode 为我们提供了条件断点. 首先在下列代码中插入一 ...

  10. Linux PuTTY 更改字体

    Linux PuTTY默认的字体比较小看着比较不舒服,Linux PuTTY的字体更改与Windows下的设置有所不同 1.Linux PuTTY默认的字体 ,Font used for ordina ...