微信公众号 获取 token、用户信息、xml map转换、服务器回调签名校验、自定义消息回复、模板消息

微信公众号工具类

package com.xxx.service.attendance.provider.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xxx.service.attendance.provider.persistence.entity.CheckLog;
import com.xxxx.standard.service.spring.redis.tool.RedisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.PostConstruct;
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.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Component
public class WxUtils {
    private static Logger logger = LoggerFactory.getLogger(WxUtils.class);


    public static final String WX_TOKEN_KEY = "WX_TOKEN_KEY";

    public static final String WX_MESSAGE_PREFIX = "WX_MESSAGE_PREFIX:%s";

    @Value("${wx.miniprogram.appId}")
    private String miniProgramAppId;
    @Value("${wx.miniprogram.path}")
    private String miniProgramPath;

    @Value("${wx.official.account.template}")
    private String officialAccountTemplateId;


    public static String WX_CHECK_NOTIC_TEMPLATEID = null;
    public static String WX_CHECK_NOTIC_MINIPROGRAM_APP_ID = null;
    public static String WX_CHECK_NOTIC_MINIPROGRAM_PATH = null;


    public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm:ss");

    @PostConstruct
    public void init(){
        WX_CHECK_NOTIC_TEMPLATEID = this.officialAccountTemplateId;
        WX_CHECK_NOTIC_MINIPROGRAM_APP_ID = this.miniProgramAppId;
        WX_CHECK_NOTIC_MINIPROGRAM_PATH = this.miniProgramPath;
    }


    /**
     * 获取token
     * @param appId
     * @param secret
     * @return
     */
    public static String getToken(String appId,String secret){
        String token = RedisUtils.get(WX_TOKEN_KEY);
        if(token == null){
            String str = HttpUtils.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret);
            JSONObject jsonObject = JSON.parseObject(str);
            token = jsonObject.get("access_token") == null?null:(String)jsonObject.get("access_token");
            Integer expiresIn = jsonObject.get("expires_in") == null?null:(Integer)jsonObject.get("expires_in");
            if(token != null){
                RedisUtils.set(WX_TOKEN_KEY,token,(expiresIn-100)*1000);
            }
        }
        return token;
    }

    /**
     * 获取用户信息
     * @param accessToken
     * @param openId
     * @return
     */
    public static JSONObject getUserInfo(String accessToken,String openId){
        String str = HttpUtils.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN");
        return JSON.parseObject(str);
    }


    /**
     * xml转map
     * @param strXml
     * @return
     * @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) {
            ex.printStackTrace();
        }
        return data;
    }


    /**
     * map转xml
     * @param data
     * @return
     * @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) {

            ex.printStackTrace();

        }
        return output;
    }


    /**
     * 微信服务器回调  验证签名
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce,String token) {
        String[] arr = new String[] { token, timestamp, nonce };
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        MessageDigest md = null;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        content = null;
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }
    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }
    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        String s = new String(tempArr);
        return s;
    }

    /**
     * 客户账号回复消息
     * @param token
     * @param map
     * @return
     */
    public static boolean customSend(String token,Map map){
        String url  = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+token;
        String param = JSON.toJSONString(map);
        String str = HttpUtils.postJson(url,param);
        JSONObject jsonObject = JSON.parseObject(str);
        int errcode = jsonObject.get("errcode") == null?-1:(int)jsonObject.get("errcode");
        if(errcode != 0){
            System.err.println("param:"+param+"  \nresult:"+str);
        }
        return errcode == 0;
    }


    /**
     * 发送模板消息
     * @param accessToken
     * @param openId
     * @param checkLog
     * @return
     */
    public static boolean sendLogNotic(String accessToken, String openId, CheckLog checkLog){
        Map map = new HashMap<>();
        map.put("touser",openId);
        map.put("template_id",WX_CHECK_NOTIC_TEMPLATEID);
        //map.put("url","http://www.baidu.com");
        map.put("topcolor","#FF0000");


        Map miniprogram = new HashMap<>();
        miniprogram.put("appid",WX_CHECK_NOTIC_MINIPROGRAM_APP_ID);
        miniprogram.put("pagepath",WX_CHECK_NOTIC_MINIPROGRAM_PATH);
        map.put("miniprogram",miniprogram);

        Map data = new HashMap<>();

        Map first = new HashMap<>();
        first.put("value","您好,"+checkLog.getStudentName()+"在学校考勤了");
        first.put("color","#173177");
        data.put("first",first);

        Map keyword1 = new HashMap<>();
        keyword1.put("value",checkLog.getStudentName());
        keyword1.put("color","#173177");
        data.put("keyword1",keyword1);

        Map keyword2 = new HashMap<>();
        keyword2.put("value",sdf.format(checkLog.getDayTime())+" "+sdf1.format(checkLog.getHourTime()));
        keyword2.put("color","#173177");
        data.put("keyword2",keyword2);

        Map remark = new HashMap<>();
        remark.put("value","点击查看详情");
        remark.put("color","#173177");
        data.put("remark",remark);

        map.put("data",data);
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        String paramStr = JSON.toJSONString(map);
        String str = HttpUtils.postJson(url,paramStr);
        JSONObject result = JSON.parseObject(str);
        if(result.get("errcode") != null && (Integer)result.get("errcode")  == 0){
            return true;
        }
        logger.error("sendLogNotic-url:{}",url);
        logger.error("sendLogNotic-paramStr:{}",paramStr);
        logger.error("sendLogNotic-str:{}",str);
        return false;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值