美文网首页
微信工具类

微信工具类

作者: 我我我不是明 | 来源:发表于2019-02-12 16:52 被阅读5次

package com.yupaopao.trade.api.gateway.utils;

import com.yupaopao.trade.api.gateway.code.SignType;

import com.yupaopao.trade.api.gateway.code.WXPayConstants;

import org.jdom2.Document;

import org.jdom2.Element;

import org.jdom2.input.SAXBuilder;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

import java.io.*;

import java.net.ConnectException;

import java.net.HttpURLConnection;

import java.net.InetAddress;

import java.net.URL;

import java.security.MessageDigest;

import java.util.*;

public class WxUtil {

    /**

    * XML格式字符串转换为Map

    *

    * @param strXML XML字符串

    * @return XML数据转换后的Map

    * @throws Exception

    */

    public static Map<String, String> xmlToMap(String strXML) throws Exception {

        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) {

        }

        return data;

    }

    /**

    * 将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;

    }

    /**

    * 生成带有 sign 的 XML 格式字符串

    *

    * @param data Map类型数据

    * @param key API密钥

    * @return 含有sign字段的XML

    */

    public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {

        return generateSignedXml(data, key, SignType.MD5);

    }

    /**

    * 生成带有 sign 的 XML 格式字符串

    *

    * @param data Map类型数据

    * @param key API密钥

    * @param signType 签名类型

    * @return 含有sign字段的XML

    */

    public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {

        String sign = generateSignature(data, key, signType);

        data.put(WXPayConstants.FIELD_SIGN, sign);

        return mapToXml(data);

    }

    /**

    * 判断签名是否正确

    *

    * @param xmlStr XML格式数据

    * @param key API密钥

    * @return 签名是否正确

    * @throws Exception

    */

    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {

        Map<String, String> data = xmlToMap(xmlStr);

        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {

            return false;

        }

        String sign = data.get(WXPayConstants.FIELD_SIGN);

        return generateSignature(data, key).equals(sign);

    }

    /**

    * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。

    *

    * @param data Map类型数据

    * @param key API密钥

    * @return 签名是否正确

    * @throws Exception

    */

    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {

        return isSignatureValid(data, key, SignType.MD5);

    }

    /**

    * 判断签名是否正确,必须包含sign字段,否则返回false。

    *

    * @param data Map类型数据

    * @param key API密钥

    * @param signType 签名方式

    * @return 签名是否正确

    * @throws Exception

    */

    public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {

        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {

            return false;

        }

        String sign = data.get(WXPayConstants.FIELD_SIGN);

        return generateSignature(data, key, signType).equals(sign);

    }

    /**

    * 生成签名

    *

    * @param data 待签名数据

    * @param key API密钥

    * @return 签名

    */

    public static String generateSignature(final Map<String, String> data, String key) throws Exception {

        return generateSignature(data, key, SignType.MD5);

    }

    /**

    * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。

    *

    * @param data 待签名数据

    * @param key API密钥

    * @param signType 签名方式

    * @return 签名

    */

    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {

        Set<String> keySet = data.keySet();

        String[] keyArray = keySet.toArray(new String[keySet.size()]);

        Arrays.sort(keyArray);

        StringBuilder sb = new StringBuilder();

        for (String k : keyArray) {

            if (k.equals(WXPayConstants.FIELD_SIGN)) {

                continue;

            }

            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名

                sb.append(k).append("=").append(data.get(k).trim()).append("&");

        }

        sb.append("key=").append(key);

        if (SignType.MD5.equals(signType)) {

            return MD5(sb.toString()).toUpperCase();

        }

        else if (SignType.HMACSHA256.equals(signType)) {

            return HMACSHA256(sb.toString(), key);

        }

        else {

            throw new Exception(String.format("Invalid sign_type: %s", signType));

        }

    }

    /**

    * 获取随机字符串 Nonce Str

    *

    * @return String 随机字符串

    */

    public static String generateNonceStr() {

        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);

    }

    /**

    * 生成 MD5

    *

    * @param data 待处理数据

    * @return MD5结果

    */

    public static String MD5(String data) throws Exception {

        MessageDigest md = MessageDigest.getInstance("MD5");

        byte[] array = md.digest(data.getBytes("UTF-8"));

        StringBuilder sb = new StringBuilder();

        for (byte item : array) {

            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));

        }

        return sb.toString().toUpperCase();

    }

    /**

    * 生成 HMACSHA256

    * @param data 待处理数据

    * @param key 密钥

    * @return 加密结果

    * @throws Exception

    */

    public static String HMACSHA256(String data, String key) throws Exception {

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");

        sha256_HMAC.init(secret_key);

        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));

        StringBuilder sb = new StringBuilder();

        for (byte item : array) {

            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));

        }

        return sb.toString().toUpperCase();

    }

    /**

    * xml解析

    * @param strxml

    * @return

    * @throws Exception

    */

    public static Map<String, String> doXMLParse(String strxml) throws Exception {

        Map<String,String> m = new HashMap<String,String>();

        try {

            strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

                if(null == strxml || "".equals(strxml)) {

                    return null;

                }

                InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));

                SAXBuilder builder = new SAXBuilder();

                Document doc = builder.build(in);

                Element root = doc.getRootElement();

                List list = root.getChildren();

                Iterator it = list.iterator();

                while(it.hasNext()) {

                    Element e = (Element) it.next();

                    String k = e.getName();

                    String v = "";

                    List children = e.getChildren();

                    if(children.isEmpty()) {

                        v = e.getTextNormalize();

                    } else {

                        v = getChildrenText(children);

                    }

                    m.put(k, v);

                }

                //关闭流

                in.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

        return m;

    }

    /**

    * 获取子节点数据

    * @param children

    * @return

    */

    public static String getChildrenText(List children) {

        StringBuffer sb = new StringBuffer();

        if(!children.isEmpty()) {

            Iterator it = children.iterator();

            while(it.hasNext()) {

                Element e = (Element) it.next();

                String name = e.getName();

                String value = e.getTextNormalize();

                List list = e.getChildren();

                sb.append("<" + name + ">");

                if(!list.isEmpty()) {

                    sb.append(getChildrenText(list));

                }

                sb.append(value);

                sb.append("</" + name + ">");

            }

        }

        return sb.toString();

    }

    //发起微信支付请求

    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {

        try {

            URL url = new URL(requestUrl);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setDoOutput(true);

            conn.setDoInput(true);

            conn.setUseCaches(false);

            // 设置请求方式(GET/POST)

            conn.setRequestMethod(requestMethod);

            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");

            // 当outputStr不为null时向输出流写数据

            if (null != outputStr) {

                OutputStream outputStream = conn.getOutputStream();

                // 注意编码格式

                outputStream.write(outputStr.getBytes("UTF-8"));

                outputStream.close();

            }

            // 从输入流读取返回内容

            InputStream inputStream = conn.getInputStream();

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");

            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;

            StringBuffer buffer = new StringBuffer();

            while ((str = bufferedReader.readLine()) != null) {

                buffer.append(str);

            }

            // 释放资源

            bufferedReader.close();

            inputStreamReader.close();

            inputStream.close();

            inputStream = null;

            conn.disconnect();

            return buffer.toString();

        } catch (ConnectException ce) {

            ce.printStackTrace();

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

    /**

    * 返回给微信服务端的xml

    * @param return_code

    * @return

    */

    public static String returnXML(String return_code) {

        return "<xml><return_code><![CDATA["

                + return_code

                + "]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

    }

    //Map转xml数据

    public static String GetMapToXML(Map<String,String> param){

        StringBuffer sb = new StringBuffer();

        sb.append("<xml>");

        for (Map.Entry<String,String> entry : param.entrySet()) {

            sb.append("<"+ entry.getKey() +">");

            sb.append(entry.getValue());

            sb.append("</"+ entry.getKey() +">");

        }

        sb.append("</xml>");

        return sb.toString();

    }

    /**

    * 获取Ip

    * @return

    */

    public static String GetIp() {

        InetAddress ia=null;

        try {

            ia= InetAddress.getLocalHost();

            String localip=ia.getHostAddress();

            return localip;

        } catch (Exception e) {

            return null;

        }

    }

    public static String getRequestXml(SortedMap<String,String> 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();

    }

}

相关文章

网友评论

      本文标题:微信工具类

      本文链接:https://www.haomeiwen.com/subject/enpkeqtx.html