一般国内的攻城狮喜欢用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; } }