【fastweixin框架教程2】weblogic javax.xml 解析xml问题

一般国内的攻城狮喜欢用tomcat进行调试自己的程序,但往往发布到生产环境就会 出现各种各样问题。

比如 上一篇文章我们谈了fastweixin最基本的使用,也许你在tomcat里面使用没有任何问题,但发布到weblogic上就会出现各种各样问题:

ExceptionPrecondition for readText is nextEvent().getTypeEventType() ==START_ELEMENT 


查看fastweixin原始代码

可以看到其使用Javax里面xml解析器 而在Weblogic中,默认使用weblogic自己实现javax类,用这个处理xml 会出问题。

大家需要注意的是,javax开头的类,一般第三方容器很多都有自己实现,相同API的Class,默认一般都是自己实现Class,而不是使用JDK里面的。

我个人解决方法就是使用第三方jar,比如xmlpull替代。

下面是修改后的代码:

package com.fastwixinextend;

import com.github.sd4324530.fastweixin.util.CollectionUtil;
import com.github.sd4324530.fastweixin.util.StrUtil;

import com.github.sd4324530.fastweixin.util.StreamUtil;

import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

/**luozhuang
 * ExceptionPrecondition for readText is nextEvent().getTypeEventType() ==
 * START_ELEMENT 原始代码使用Javax里面xml解析器 在Weblogic中,默认使用weblogic自己实现的xml 会出问题
 */
public class MyMessageUtil {

    public MyMessageUtil() {
        super();
    }

    private static final Logger LOG
            = LoggerFactory.getLogger(MyMessageUtil.class);

    private static final String FORMAT
            = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";

    /**
     * 解析从微信服务器来的请求,将消息或者事件返回出去
     *
     * @param request http请求对象
     * @param token 用户设置的taken
     * @param appId 公众号的APPID
     * @param aesKey 用户设置的加密密钥
     * @return 微信消息或者事件Map
     */
    public static Map<String, Object> parseXml(HttpServletRequest request,
            String token, String appId,
            String aesKey) {
        Map<String, Object> map = new HashMap<String, Object>();

        InputStream inputStream = null;
        String message = null;
        try {
            inputStream = request.getInputStream();
            if (StrUtil.isNotBlank(aesKey)) {
                ByteArrayOutputStream outputStream
                        = new ByteArrayOutputStream();
                StreamUtil.copy(inputStream, outputStream);
                String body = outputStream.toString("UTF-8");
                LOG.debug("收到的消息密文:{}", body);

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

                Element root = document.getDocumentElement();
                NodeList nodelist1 = root.getElementsByTagName("Encrypt");

                WXBizMsgCrypt pc = new WXBizMsgCrypt(token, aesKey, appId);
                String msgSignature = request.getParameter("msg_signature");
                String timeStamp = request.getParameter("timestamp");
                String nonce = request.getParameter("nonce");
                LOG.debug("msgSignature:{}", msgSignature);
                LOG.debug("timeStamp:{}", timeStamp);
                LOG.debug("nonce:{}", nonce);
                String encrypt = nodelist1.item(0).getTextContent();
                String fromXML = String.format(FORMAT, encrypt);
                message
                        = pc.DecryptMsg(msgSignature, timeStamp, nonce, fromXML);
                LOG.debug("收到的消息:{}", message);
            }
            inputStream = new ByteArrayInputStream(message.getBytes("UTF-8"));

            XmlPullParserFactory pullFactory
                    = XmlPullParserFactory.newInstance();
            XmlPullParser reader = pullFactory.newPullParser();
            // 设置输入流 并指明编码方式
            reader.setInput(inputStream, "UTF-8");
            // 产生第一个事件
            int eventType = reader.getEventType();
            // 只要不是文档结束事件,就一直循环
            while (eventType != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {
                    String tagName = reader.getName();
                    if ("SendPicsInfo".equals(tagName)) {
                        map.put(tagName, eventSendPicsInfo(reader));
                    } else if ("SendLocationInfo".equals(tagName)) {
                        map.put(tagName, eventSendLocationInfo(reader));
                    } else if ("ScanCodeInfo".equals(tagName)) {
                        map.put(tagName, eventScanCodePush(reader));
                    } else if ("xml".equals(tagName)) {
                    } else {
                        eventType = reader.next();
                        map.put(tagName, reader.getText());
                    }
                }
                eventType = reader.next();
            }

        } catch (IOException e) {
            LOG.error("IO出现异常", e);
        } catch (ParserConfigurationException e) {
            LOG.error("XML解析出现异常", e);
        } catch (SAXException e) {
            LOG.error("XML解析出现异常", e);
        } catch (AesException e) {
            LOG.error("Aes异常", e);
        } catch (XmlPullParserException e) {
            LOG.error("XML解析出现异常", e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {

            }
        }
        return map;
    }

    /**
     * Event为pic_sysphoto, pic_photo_or_album, pic_weixin时触发
     *
     * @param reader reader
     * @return 读取结果
     * @throws XMLStreamException XML解析异常
     */
    protected static Map<String, Object> eventSendPicsInfo(XmlPullParser reader) throws XmlPullParserException,
            IOException {
        Map<String, Object> sendPicsInfoMap = new HashMap<String, Object>();
        int eventType = reader.next();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = reader.next();
            if (eventType == XmlPullParser.START_TAG) {
                String tagName = reader.getName();
                if ("Count".equals(tagName)) {
                    eventType = reader.next();
                    sendPicsInfoMap.put(tagName, reader.getText());
                } else if ("PicList".equals(tagName)) {
                    //                    StringBuilder sb = new StringBuilder();
                    List<Map<String, String>> picList
                            = CollectionUtil.newArrayList();
                    while (eventType != XmlPullParser.END_DOCUMENT) {
                        int event1 = reader.next();
                        if (event1 == XmlPullParser.START_TAG
                                && "PicMd5Sum".equals(reader.getName())) {
                            Map<String, String> picMap
                                    = new HashMap<String, String>();
                            eventType = reader.next();
                            picMap.put("PicMd5Sum", reader.getText());
                            //                            sb.append(reader.getText()());
                            //                            sb.append(",");
                            picList.add(picMap);
                        } else if (event1 == XmlPullParser.END_TAG
                                && "PicList".equals(reader.getName())) {
                            break;
                        }
                    }
                    //                    sendPicsInfoMap.put(tagName, sb.substring(0, sb.length()));
                    sendPicsInfoMap.put(tagName, picList);
                }
            }
        }

        return sendPicsInfoMap;
    }

    /**
     * Event为location_select时触发
     *
     * @param reader reader
     * @return 读取结果
     * @throws XMLStreamException XML解析异常
     */
    protected static Map<String, Object> eventSendLocationInfo(XmlPullParser reader) throws XmlPullParserException,
            IOException {
        Map<String, Object> sendLocationInfo = new HashMap<String, Object>();
        int eventType = reader.next();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = reader.next();
            if (eventType == XmlPullParser.START_TAG) {
                String tagName = reader.getName().toString();
                eventType = reader.next();
                sendLocationInfo.put(tagName, reader.getText());
            }
        }
        return sendLocationInfo;
    }

    /**
     * Event为scancode_push, scancode_waitmsg时触发
     *
     * @param reader reader
     * @return 读取结果
     * @throws XMLStreamException XML解析异常
     */
    protected static Map<String, Object> eventScanCodePush(XmlPullParser reader) throws XmlPullParserException,
            IOException {
        Map<String, Object> scanCodePush = new HashMap<String, Object>();
        int eventType = reader.next();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = reader.next();
            if (eventType == XmlPullParser.START_TAG) {
                String tagName = reader.getName();
                eventType = reader.next();
                scanCodePush.put(tagName, reader.getText());
            }
        }
        return scanCodePush;
    }

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值