ITPub博客

首页 > 数据库 > 国内数据库 > 微信开发用到的常见的方法~~xmlToMap、MapToXml、签名等等

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

原创 国内数据库 作者:duisong5766 时间:2018-08-22 14:50:23 0 删除 编辑

近日,皇冠体育出租  dsluntan.com 企娥339 3756 370 在开发微信支付、微信退款、微信付款到零钱、微信订单查询、微信付款到银行卡的功能。以及其他微信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;
    }
}12345678910111213141516171819202122232425262728293031323334353637383940

这里写图片描述

二、将当前的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;
    }12345678910111213141516171819202122232425262728293031323334353637383940
 /*
     * 将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();
    }123456789101112131415161718192021

这里写图片描述

这里写图片描述
三、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;
        }
    }12345678910111213141516171819202122232425262728293031323334353637
//不通用的、返回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; 
        } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198

四、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(); 
        } 
    } 
} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293

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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31551548/viewspace-2212559/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2018-08-22

  • 博文量
    1
  • 访问量
    565