微信开发用到的常见的方法~~xmlToMap、MapToXml、签名等等

原创 2018年01月22日 11:42:40

       近日,在开发微信支付、微信退款、微信付款到零钱、微信订单查询、微信付款到银行卡的功能。以及其他微信API的使用。发现微信API的开发都是同样的套路~~封装参数–》包装成Xml—》提交到Api—》获取返回的内容就行了。因为会有多个API都设计到这些操作,特地抽取出来封装成工具类单独讲,学习完以下这5~8个放法、那么你的开发就很简便了 ~ ~ 一个支付方法简单的十五行代码立马搞定。希望对你们有帮助。个人浅薄的见解
资料下载:没积分找我拿~ ~这边分享资料一定要设个积分值,没办法
http://download.csdn.net/download/xiaozhegaa/10226929
这里写图片描述
一、微信签名的工具类
【温馨提示:】数字签名是一般开发人员容易遇到的错误,记住“你没遇到数字签名错误,都不好意思说自己做过微信开发”。
耐心解决就行

【Description】简单来解释,就是对自己要发送的数据进行加密处理、换句话说假如说你要传递A/B/C,就对这三者进行加密。初开发者的误区:例如看到别人代码拿D和E等去数字签名、然后在自己的开发中就拿D和E去签名,这是错误的做法,会出现数字签名错误。你要看一下你的开发需要传递D和F去后台,那么你应该拿D和F去签名就对了

package com.fh.util.weixin;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import com.fh.controller.app.nrb.bargain.wxconfig;
/**
 * 签名工具类
 * @author 小郑
 * @date 2018年02月22日
 * @Notice:wxconfig.apikey。这句代码是获取商务号设置的api秘钥。这里不方便贴出来,
 * 复制签名代码的人,需要把该常量改成自己商务号的key值。原因是Api规定了签名必须加上自己的key值哦 
 * */
public class SignUtils {

    /**
     * @param characterEncoding 编码格式 utf-8
     * */
    public static String creatSign(String characterEncoding,
            SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v) 
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        //wxconfig.apikey。这句代码是获取商务号设置的api秘钥。这里不方便贴出来,
        //复制签名代码的人,需要把该常量改成自己商务号的key值。原因是Api规定了签名必须加上自己的key值哦 
        sb.append("key=" + wxconfig.apikey);
        String sign = MD5Utils.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        System.out.println(sign);
        return sign;
    }
}

这里写图片描述

二、将当前的map结合转化成xml格式 ~~ 微信请求参数是必须要封装成Xml格式的,在java中写xml很不方便,但是写Map集合很方便。故需要提供map转化xml的方法


    /**
     * 将Map转换为XML格式的字符串
     *
     * @param data Map类型数据
     * @return XML格式的字符串
     * @throws Exception
     */
    public static String mapToXml(Map<String, String> data) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = documentBuilder.newDocument();
        org.w3c.dom.Element root = document.createElement("xml");
        document.appendChild(root);
        for (String key: data.keySet()) {
            String value = data.get(key);
            if (value == null) {
                value = "";
            }
            value = value.trim();
            org.w3c.dom.Element filed = document.createElement(key);
            filed.appendChild(document.createTextNode(value));
            root.appendChild(filed);
        }
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);
        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
        try {
            writer.close();
        }
        catch (Exception ex) {
        }
        return output;
    }
 /*
     * 将SortedMap<Object,Object> 集合转化成 xml格式
     */
    public static String getRequestXml(SortedMap<Object,Object> parameters){
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
                sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
            }else {
                sb.append("<"+k+">"+v+"</"+k+">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

这里写图片描述

这里写图片描述
三、xml转化成map或者Bean
微信返回的信息是Xml格式、需要一个工具类把它解析成Map集合或者是一个Bean。方便我们去获取里面返回值。这里会介绍两种方式,一种是转化成Map集合,通过get出来使用,这个方法是通用的,第二种是转化成Bean、这种的话不通用。每个bean基本都不大一样,需要定制

 //通用的。返回map格式
 /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. 
            Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }

    }
//不通用的、返回Bean格式

//以企业付款到零钱为例子~~根据Api会返回的参数,书写一个Bean类型
package com.fh.entity.nrb.xiaozheng;
/**
 * 
 * 企业 付款到 客户  的 实体类
 * @author xiaozheng
 * @version 1.0 
 * @description: 收集企业 支付给客户成功后的返回信息
 * @time : 2018-01-16 16:00:00
 */
public class EnterpriceToCustomer {
    /*  <xml>
        <return_code><![CDATA[SUCCESS]]></return_code>
        <return_msg><![CDATA[]]></return_msg>
        <mchid><![CDATA[1488323162]]></mchid>
        <nonce_str><![CDATA[o9fcpfvqow1aks48a2omvayu1ne7c709]]></nonce_str>
        <result_code><![CDATA[SUCCESS]]></result_code>
        <partner_trade_no><![CDATA[xvuct0087w4t1dpr87iqj98w5f71ljae]]></partner_trade_no>
        <payment_no><![CDATA[1000018301201801163213961289]]></payment_no>
        <payment_time><![CDATA[2018-01-16 14:52:16]]></payment_time>
        </xml>
    */

    private String return_code;
    private String return_msg;
    private String mchid;
    private String nonce_str;
    private String result_code;
    private String partner_trade_no;
    private String payment_no;
    private String payment_time;

    /*
     * 支付错误时,返回的代码
     *  key是:return_code,值是:SUCCESS
        key是:return_msg,值是:支付失败
        key是:mch_appid,值是:wx49c22ad731b679c3
        key是:mchid,值是:1488323162
        key是:result_code,值是:FAIL
        key是:err_code,值是:AMOUNT_LIMIT
        key是:err_code_des,值是:付款金额超出限制。低于最小金额1.00元或累计超过20000.00元。
     * 
     */
    private String err_code;
    private String err_code_des;

    public String getErr_code() {
        return err_code;
    }
    public void setErr_code(String errCode) {
        err_code = errCode;
    }
    public String getErr_code_des() {
        return err_code_des;
    }
    public void setErr_code_des(String errCodeDes) {
        err_code_des = errCodeDes;
    }
    public String getReturn_code() {
        return return_code;
    }
    public void setReturn_code(String returnCode) {
        return_code = returnCode;
    }
    public String getReturn_msg() {
        return return_msg;
    }
    public void setReturn_msg(String returnMsg) {
        return_msg = returnMsg;
    }
    public String getMchid() {
        return mchid;
    }
    public void setMchid(String mchid) {
        this.mchid = mchid;
    }
    public String getNonce_str() {
        return nonce_str;
    }
    public void setNonce_str(String nonceStr) {
        nonce_str = nonceStr;
    }
    public String getResult_code() {
        return result_code;
    }
    public void setResult_code(String resultCode) {
        result_code = resultCode;
    }
    public String getPartner_trade_no() {
        return partner_trade_no;
    }
    public void setPartner_trade_no(String partnerTradeNo) {
        partner_trade_no = partnerTradeNo;
    }
    public String getPayment_no() {
        return payment_no;
    }
    public void setPayment_no(String paymentNo) {
        payment_no = paymentNo;
    }
    public String getPayment_time() {
        return payment_time;
    }
    public void setPayment_time(String paymentTime) {
        payment_time = paymentTime;
    }
    @Override
    public String toString() {
        return "EnterpriceToCustomer [err_code=" + err_code + ", err_code_des="
                + err_code_des + ", mchid=" + mchid + ", nonce_str="
                + nonce_str + ", partner_trade_no=" + partner_trade_no
                + ", payment_no=" + payment_no + ", payment_time="
                + payment_time + ", result_code=" + result_code
                + ", return_code=" + return_code + ", return_msg=" + return_msg
                + "]";
    }
}

/** 
    下面是需要通过跟节点,找找到对应的类属性,手动把它set进去。因此API返回的参数不一样。需要写每个返回的Bean。看个人的习惯呗~~我喜欢用bean存储数据的方式
    * 解析企业支付申请 
    * 解析的时候自动去掉CDMA 
    * @param xml 
    */ 
    @SuppressWarnings("unchecked") 
    public static EnterpriceToCustomer parseXmlToMapEnterpriceToCustomer(String xml){ 
            EnterpriceToCustomer enterpriceToCustomer = new EnterpriceToCustomer(); 
            try { 
                    StringReader read = new StringReader(xml); 
                    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入 
                    InputSource source = new InputSource(read); 
                    // 创建一个新的SAXBuilder 
                    SAXBuilder sb = new SAXBuilder(); 
                    // 通过输入源构造一个Document 
                    Document doc; 
                    doc = (Document) sb.build(source); 

                    Element root = doc.getRootElement();// 指向根节点 
                    List<Element> list = root.getChildren(); 

                    if(list!=null&&list.size()>0){ 
                    for (Element element : list) { 
                        System.out.println("key是:"+element.getName()+",值是:"+element.getText()); 
                        if("return_code".equals(element.getName())){ 
                                enterpriceToCustomer.setReturn_code(element.getText()); 
                            } 

                        if("return_msg".equals(element.getName())){ 
                                enterpriceToCustomer.setReturn_msg(element.getText()); 
                            } 

                        if("mchid".equals(element.getName())){ 
                            enterpriceToCustomer.setMchid(element.getText()); 
                        }

                        if("nonce_str".equals(element.getName())){ 
                            enterpriceToCustomer.setNonce_str(element.getText()); 
                        }
                        if("result_code".equals(element.getName())){ 
                            enterpriceToCustomer.setResult_code(element.getText()); 
                        }
                        if("partner_trade_no".equals(element.getName())){ 
                            enterpriceToCustomer.setPartner_trade_no(element.getText()); 
                        }
                        if("payment_no".equals(element.getName())){ 
                            enterpriceToCustomer.setPayment_no(element.getText()); 
                        }
                        if("payment_time".equals(element.getName())){ 
                            enterpriceToCustomer.setPayment_time(element.getText()); 
                        }   
                        //错误的编码
                        /*
                           private String err_code;
                           private String err_code_des;
                         * */
                        if("err_code".equals(element.getName())){ 
                            enterpriceToCustomer.setErr_code(element.getText()); 
                        }
                        if("err_code_des".equals(element.getName())){ 
                            enterpriceToCustomer.setErr_code_des(element.getText()); 
                        }   

                    }
                }


            } catch (JDOMException e) { 
            e.printStackTrace(); 
            } catch (IOException e) { 
            e.printStackTrace(); 
            }catch (Exception e) { 
            e.printStackTrace(); 
            } 

            return enterpriceToCustomer; 
        } 

四、Post请求+证书~~亲测可以的

package com.fh.entity.nrb.weixinResult;
import java.io.File; 
import java.io.FileInputStream; 
import java.security.KeyStore; 

import javax.net.ssl.SSLContext; 

import org.apache.http.HttpEntity; 
import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
import org.apache.http.conn.ssl.SSLContexts; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClients; 
import org.apache.http.util.EntityUtils; 

import com.fh.controller.app.nrb.bargain.wxconfig;



/** 
* This example demonstrates how to create secure connections with a custom SSL 
* context. 
*/ 
public class ClientCustomSSL { 

@SuppressWarnings("deprecation")
public static String doRefund(String url,String data) throws Exception { 
        /** 
        * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 
        */ 

        KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
        /**
        *此处要改
        *wxconfig.SSLCERT_PATH : 指向你的证书的绝对路径,带着证书去访问
        */

        FileInputStream instream = new FileInputStream(new File(wxconfig.SSLCERT_PATH));//P12文件目录 
        try { 
        /** 
        * 此处要改 
        * 
        * 下载证书时的密码、默认密码是你的MCHID mch_id
        * */ 
        keyStore.load(instream, wxconfig.SSLCERT_PASSWORD.toCharArray());//这里写密码
        } finally { 
            instream.close(); 
        } 

        // Trust own CA and all self-signed certs 
        /** 
        * 此处要改 
        * 下载证书时的密码、默认密码是你的MCHID mch_id
        * */ 
        SSLContext sslcontext = SSLContexts.custom() 
        .loadKeyMaterial(keyStore, wxconfig.SSLCERT_PASSWORD.toCharArray())//这里也是写密码的 
        .build(); 
        // Allow TLSv1 protocol only 
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( 
        sslcontext, 
        new String[] { "TLSv1" }, 
        null, 
        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 
        CloseableHttpClient httpclient = HttpClients.custom() 
        .setSSLSocketFactory(sslsf) 
        .build(); 
        try { 
        HttpPost httpost = new HttpPost(url); // 设置响应头信息 
        httpost.addHeader("Connection", "keep-alive"); 
        httpost.addHeader("Accept", "*/*"); 
        httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); 
        httpost.addHeader("Host", "api.mch.weixin.qq.com"); 
        httpost.addHeader("X-Requested-With", "XMLHttpRequest"); 
        httpost.addHeader("Cache-Control", "max-age=0"); 
        httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); 
        httpost.setEntity(new StringEntity(data, "UTF-8")); 
        CloseableHttpResponse response = httpclient.execute(httpost); 
        try { 
        HttpEntity entity = response.getEntity(); 

        String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); 
        EntityUtils.consume(entity); 
        return jsonStr; 
        } finally { 
        response.close(); 
        } 
        } finally { 
        httpclient.close(); 
        } 
    } 
} 

其他的。遇到了会补充上来。还有一个get方式,不需要证书的提交,稍后补充呗

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaozhegaa/article/details/79127283

将map自动转化为xml报文

public static byte[] callMapToXML(Map map) { logger.info("将Map转成Xml, Map:" + map.toString()); St...
  • lisheng19870305
  • lisheng19870305
  • 2015年05月19日 18:15
  • 18936

dom4j Map XML互转

package com.wop.util; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterat...
  • qq_29246225
  • qq_29246225
  • 2016年10月21日 14:45
  • 3460

XML和Map集合之间的相互转换

通过XStream和DOM4J实现Map集合和XML文本格式的转化
  • qq_16071145
  • qq_16071145
  • 2016年05月09日 20:54
  • 8266

微信支付中xml和map互转

现在用java做微信公众号的支付,支付过程将参数发给微信是以xml格式发送,接受过来的也是xml格式字符串。感觉网上的xml和map转化复杂就手写了一个,具体代码如下:package com.ciji...
  • zl544434558
  • zl544434558
  • 2015年11月13日 17:22
  • 5613

微信开发源码讲解

微信开发源码讲解
  • zhangdaiscott
  • zhangdaiscott
  • 2014年03月24日 13:19
  • 6288

一个xml和map相互转换的工具类

一个xml和map相互转换的工具类,依赖dom4j import java.io.File; import java.io.IOException; import java.io.Str...
  • zhouxuke
  • zhouxuke
  • 2017年01月23日 14:37
  • 2405

微信支付api返回的xml转换为Map的方法

举例如下:                                                   Java代码  /**     ...
  • xu3508620
  • xu3508620
  • 2015年06月19日 10:21
  • 2652

微信开发用到的常见的方法~~xmlToMap、MapToXml、签名等等

近日,在开发微信支付、微信退款、微信付款到零钱、微信订单查询、微信付款到银行卡的功能。以及其他微信API的使用。发现微信API的开发都是同样的套路~~封装参数–》包装成Xml—》提交到Api—》获取返...
  • xiaozhegaa
  • xiaozhegaa
  • 2018年01月22日 11:42
  • 685

用XStream把Map转化成xml的例子

原文:http://deepakmodi2006.blogspot.com/2012/06/conversion-of-map-into-xml-and-vice.html
  • u012319317
  • u012319317
  • 2014年11月15日 16:33
  • 3105

笔试题:求一个数的开方,如根号2

题目: 求一个数的开方,如根号2,要求保留到小数点位后10位。 解法一: 也就相当于求一个数n的开方,我们用二分法进行计算,不断缩小范围,但是double、float不能直接等,最后如果...
  • sinat_24520925
  • sinat_24520925
  • 2015年09月11日 16:14
  • 457
收藏助手
不良信息举报
您举报文章:微信开发用到的常见的方法~~xmlToMap、MapToXml、签名等等
举报原因:
原因补充:

(最多只允许输入30个字)