微信公众号开发(二)


参考文章:Java微信公众号扫描带参数二维码事件

事件监听及自动回复消息

扫码回复、订阅回复、文本回复等

重新编写/verifyWxToken接口

    @ResponseBody
    @RequestMapping(value = "/verifyWxToken")
    @RequestNoneAuthentication
    public String verifyWxToken(HttpServletRequest request) throws IOException {
        // 获得微信端返回的xml数据
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingaeskey, appId);

            is = request.getInputStream();
            isr = new InputStreamReader(is, "utf-8");
            br = new BufferedReader(isr);
            String str = null;
            StringBuffer returnXml = new StringBuffer();
            while ((str = br.readLine()) != null) {
                //返回的是xml数据
                returnXml.append(str);
            }
            logger.error("==========returnXml="+returnXml);
            Map<String, String> encryptMap = WeiXinUtils.xmlToMap(returnXml.toString(),pc);
            logger.error("==========encryptMap="+new Gson().toJson(encryptMap));
            // 得到公众号传来的加密信息并解密,得到的是明文xml数据
            String encrypt=encryptMap.get("Encrypt");
            String decryptXml =null;
            if(StringUtils.isNotBlank(encrypt)){
                decryptXml = pc.decrypt(encrypt);//pc.decrypt(encryptMap.get("Encrypt"));encryptMsg
            }
            logger.error("==========decryptXml="+decryptXml);
            // 将xml数据转换为map
            Map<String, String> decryptMap = new HashMap<>();
            if(StringUtils.isNotBlank(decryptXml)){
                decryptMap=WeiXinUtils.xmlToMap(decryptXml,pc);
            }
            logger.error("==========decryptMap="+new Gson().toJson(decryptMap));

            // 区分消息类型
            String msgType = encryptMap.get("MsgType");
            logger.error("==========msgType="+msgType);
            // 普通消息
            if ("text".equals(msgType)) { // 文本消息
                return MyEventHandler.subscribe(encryptMap);
            } else if ("image".equals(msgType)) { // 图片消息
                // todo 处理图片消息
            } else if ("voice".equals(msgType)) { //语音消息
                // todo 处理语音消息
            }
            // 事件推送
            else if ("event".equals(msgType)) { // 事件消息
                // 区分事件推送
                String event = encryptMap.get("Event");
                if ("subscribe".equals(event)) { // 订阅事件 或 未关注扫描二维码事件
                    // 返回消息时ToUserName的值与FromUserName的互换
                    return MyEventHandler.subscribe(encryptMap);
                }  else if ("unsubscribe".equals(event)) { // 取消订阅事件
                    // todo 处理取消订阅事件
                } else if ("SCAN".equals(event)) { // 已关注扫描二维码事件
                    // 返回消息时ToUserName的值与FromUserName的互换
                    return MyEventHandler.subscribe(encryptMap);
                }
            }
        } catch (Exception e) {
            logger.error("===verifyWxToken===处理异常,e:", e);
        }finally {
            if (null != is) {
                is.close();
            }
            if (null != isr) {
                isr.close();
            }
            if (null != br) {
                br.close();
            }
        }
        return "Success";
    }

WeiXinUtils

public class WeiXinUtils{
	/**
     * XML格式字符串转换为Map
     * 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
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML, WXBizMsgCrypt pc) throws Exception {
        try {
            Map<String, String> data = new HashMap<>();

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
            dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            dbf.setXIncludeAware(false);
            dbf.setExpandEntityReferences(false);

            int startIndex=strXML.indexOf("<xml>");
            String content=strXML.substring(startIndex);
            int endIndex=content.indexOf("</xml>");
            content=content.substring(0,endIndex+6);
            System.out.println("centent:"+content);

            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(content);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);

            Element root = document.getDocumentElement();
            NodeList nodeList =  root.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 {
                sr.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            logger.warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }
    }
    /**
     * 将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;
    }
}

MyEventHandler

public class MyEventHandler {

    public static String subscribe(Map<String, String> decryptMap) throws Exception {
        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("ToUserName", decryptMap.get("FromUserName"));
        returnMap.put("FromUserName", decryptMap.get("ToUserName"));
        returnMap.put("CreateTime", new Date().getTime()+"");
        returnMap.put("MsgType", "text");
        returnMap.put("Content", "https://www.baidu.com");
        String encryptMsg = WeiXinUtils.mapToXml(returnMap);
        return encryptMsg;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信公众号开发源码Java是用Java语言编写的用于开发微信公众号的源代码。微信公众号开发是指通过开发者账号申请成为微信公众号开发者,利用微信提供的开发接口和SDK来开发和管理公众号。 Java作为一种广泛应用于企业级开发的编程语言,在微信公众号开发中也得到了广泛应用。通过使用Java开发微信公众号,可以实现公众号的业务逻辑,包括用户管理、消息推送、菜单设置、素材管理等功能,以及与其他系统的对接、数据的处理和存储等。 对于开发微信公众号的源码来说,Java源码通常包括了处理微信服务器与开发者服务器之间的消息通信和交互的代码,以及各类功能模块的实现代码。开发者可以根据自己的需求和业务逻辑,使用Java语言编写各种业务逻辑代码,并通过开发工具集成微信提供的SDK库来实现与微信服务器之间的交互。 在Java源码的基础上,开发者还可以根据需要进行定制和扩展,以满足更具体的业务需求。可以添加自定义的功能模块或者对现有功能进行修改和优化,以适应不同的应用场景和业务要求。 总之,微信公众号开发源码Java是用于开发微信公众号的源代码,通过使用Java语言和相应的开发工具,开发者可以自定义和实现具体的业务功能,满足不同用户的需求,并与微信服务器进行消息交互,为用户提供更好的微信公众号服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值