微信支付 MD5加密 、xml转Map/Json 、 Map转xml

一、MD5加密

public class WxUtils {

    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

//获取MessageDigest.digest(str) 后的字节数组(数组长度16  范围-128~127)
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

//对数组中的每个字节进行计算(返回两个字符,最后组成32位密文)
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

//主方法
    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
            //执行md.digest(byte []bytes)过程中,会先执行 update,将字符串的bytes数组加入进程 md.digest(bytes) 返回长度为16的字节数组
                resultString = 
                byteArrayToHexString(md.digest(resultString
                        .getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString
                        .getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

 public static void main(String args[]){


        WxUtils.MD5Encode("hello","utf-8");

    }

}

注意:编码格式在没有中文情况下得到的结果是一样的,在有中文的情况下编码格式会影响最后结果,微信sign签名方式为 utf-8 编码格式

二、xml 转 Map/Json (json为例)

package com.wxpay.utils;

import net.sf.json.JSONObject;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springSupport.utils.Md5Util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Test {

    public JSONObject xmlToMap(Element node) throws DocumentException {

        JSONObject jsonObject = new JSONObject();
        System.out.println("节点的名称:" + node.getName());
        //首先获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        //遍历属性节点
        for(Attribute attribute : list){
            System.out.println("属性"+attribute.getName() +":" + attribute.getValue());

        }
        //如果当前节点内容不为空,则输出
        if(!(node.getTextTrim().equals(""))){
            System.out.println( node.getName() + ":" + node.getText());
            jsonObject.put(node.getName(),node.getText());
        }
        //同时迭代当前节点下面的所有子节点
        //使用递归
        Iterator<Element> iterator = node.elementIterator();
        while(iterator.hasNext()){
            Element e = iterator.next();
            xmlToMap(e);
        }
        return jsonObject;
    }

    public static void main(String []args) throws DocumentException {


        //创建SAXReader对象
        SAXReader reader = new SAXReader();
        InputStream is = new ByteArrayInputStream("<xml><id>1</id><name>frank</name></xml>".getBytes());
        //读取文件 转换成Document
        Document document = reader.read(is);
        //获取根节点元素对象
        Element root = document.getRootElement();
        Test t = new Test();
        t.xmlToMap(root);


    }

}

输出结果,如图:

这里写图片描述

三、Map 转 xml

package com.wxpay.utils;

import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springSupport.utils.Md5Util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.*;

public class Test {
    /**
     *  map转成xml
     * @param parm
     * @param isAddCDATA
     * @return
     */
    public String mapToXml(Map<String, String> parm, boolean isAddCDATA) {

//首先要对map进行ASCLL码排序
        ArrayList<Map.Entry<String,String>> arrayList = new ArrayList<>(parm.entrySet());
        Collections.sort(arrayList, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        StringBuffer strbuff = new StringBuffer("<xml>");


        if (parm != null && !parm.isEmpty()) {
            for (Map.Entry<String, String> entry : arrayList) {
                strbuff.append("<").append(entry.getKey()).append(">");
                if (isAddCDATA) {
                    strbuff.append("<![CDATA[");
                    if (StringUtils.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                    strbuff.append("]]>");
                } else {
                    if (StringUtils.isNotEmpty(entry.getValue())) {
                        strbuff.append(entry.getValue());
                    }
                }
                strbuff.append("</").append(entry.getKey()).append(">");
            }
        }
        return strbuff.append("</xml>").toString();
    }

    public static void main(String []args) throws DocumentException {

        Map<String,String> map = new HashMap<>();
        map.put("appid","11111111111111");
        map.put("mch_id","222222222222");
        map.put("body","测试");
        map.put("sign_type","MD5");

        Test t = new Test();

//是否添加CDATA标签,false为否
        System.out.println(t.mapToXml(map,false));
    }

}

输出结果,如图

这里写图片描述

### Java实现微信支付H5功能 #### 背景说明 为了实现在Java环境中完成微信H5支付的功能,开发者需要遵循微信支付官方提供的接口规范以及调用逻辑。以下是基于现有资料整理的实现方案和代码示例。 --- #### 接入准备 在正式开发之前,需确保已完成以下准备工作: - 注册成为微信支付商户,并获得相应的商户号(`mch_id`)、API密钥等基础配置信息。 - 下载并引入微信支付V3 SDK到项目中[^1]。 - 配置服务器环境支持HTTPS协议,因微信支付对接口的安全性有严格要求。 --- #### H5支付核心流程 根据参考资料中的描述,微信H5支付的主要流程如下: 1. **发起预支付请求** 商户通过调用微信支付的统一下单接口生成预支付交易会话标识(`prepay_id`)。 2. **跳微信支付页面** 使用返回的`h5_url`引导用户进入微信支付界面完成付款操作。 3. **接收异步通知** 用户支付完成后,微信服务器向商户后台发送支付结果的通知消息。 具体步骤详见参考资料[^4]。 --- #### 示例代码 ##### 1. 统一下单接口调用 此部分用于创建订单并向微信提交必要的参数以获取`prepay_id`。 ```java import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class WeChatPayService { private static final String API_URL = "https://api.mch.weixin.qq.com/v3/pay/transactions/h5"; public static void createOrder(String body, double totalFee, String outTradeNo) throws Exception { OkHttpClient client = new OkHttpClient(); Map<String, Object> params = new HashMap<>(); params.put("appid", "your_appid"); // 替换为实际应用ID params.put("mchid", "your_mchid"); // 替换为商户号 params.put("description", body); params.put("out_trade_no", outTradeNo); params.put("amount", Collections.singletonMap("total", (int)(totalFee * 100))); params.put("scene_info", Collections.singletonMap( "payer_client_ip", "192.168.1.1" )); ObjectMapper mapper = new ObjectMapper(); RequestBody requestBody = RequestBody.create(mapper.writeValueAsString(params), MediaType.get("application/json")); Request request = new Request.Builder() .url(API_URL) .post(requestBody) .addHeader("Authorization", "Bearer your_access_token") // 替换为真实token .build(); try (Response response = client.newCall(request).execute()) { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string()); } } } ``` 上述代码实现了向微信支付服务端发送H5支付请求的过程[^3]。 ##### 2. 处理回调通知 当用户的支付状态发生变化时,微信会主动推送一条XML格式的消息给指定URL地址。因此,在部署阶段还需设置好对应的监听器来解析这些数据包。 ```java @WebServlet("/wxNotify") public class WxPayNotifyServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { BufferedReader reader = req.getReader(); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null){ sb.append(line); } // 解析接收到的数据包内容... processNotification(sb.toString()); // 返回成功响应给微信服务器确认已接受该条目 PrintWriter writer = resp.getWriter(); writer.write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>"); } private void processNotification(String xmlData){ // TODO: Implement logic to handle the notification data. } } ``` 以上片段展示了如何构建一个简单的servlet用来捕获来自微信方面的更新提示[^2]。 --- #### 注意事项 - 所有的网络通信都应当采用加密传输方式保护敏感信息免受窃听攻击威胁。 - 对于生产环境下运行的应用程序而言,请务必妥善保管私钥文件以防泄露风险发生。 - 定期查阅最新版的技术手册以便及时调整不符合当前标准的部分。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值