All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.weixinmp.BaseWeinxinmpController Maven / Gradle / Ivy

The newest version!
package net.sf.weixinmp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import net.sf.weixinmp.inbound.InboundEventMessage;
import net.sf.weixinmp.inbound.menu.InboundLocationSelectMessage;
import net.sf.weixinmp.inbound.menu.InboundPicPhoteOrAlbumMessage;
import net.sf.weixinmp.inbound.menu.InboundPicSysphotoMessage;
import net.sf.weixinmp.inbound.menu.InboundPicWeixinMessage;
import net.sf.weixinmp.inbound.menu.InboundScancodePushEventMessage;
import net.sf.weixinmp.inbound.menu.InboundScancodeWaitmsgMessage;
import net.sf.weixinmp.inbound.plain.InboundImageMessage;
import net.sf.weixinmp.inbound.plain.InboundLinkMessage;
import net.sf.weixinmp.inbound.plain.InboundMapLocationMessage;
import net.sf.weixinmp.inbound.plain.InboundSmallVideoMessage;
import net.sf.weixinmp.inbound.plain.InboundTextMessage;
import net.sf.weixinmp.inbound.plain.InboundVideoMessage;
import net.sf.weixinmp.inbound.plain.InboundVoiceMessage;
import net.sf.weixinmp.inbound.push.InboundQRScanSubscribeMessage;
import net.sf.weixinmp.inbound.push.InboundSubscribeMessage;
import net.sf.weixinmp.inbound.user.InboundLocationMessage;
import net.sf.weixinmp.outbound.passive.PassiveMessage;
import net.sf.weixinmp.util.HttpParam;
import net.sf.weixinmp.util.SHA1;
import net.sf.weixinmp.util.XMLUtil;
/**
 * 可继承服用processCallback
 * @author Alex
 *
 */
public abstract class BaseWeinxinmpController {
	private final static Logger LOGGER=Logger.getLogger(BaseWeinxinmpController.class);
	public final static String MESSAGE_LISTENER="net.sf.weixinmp.MessageListener.attributeKey";
	/**
	 * 此接口涵盖的是对话服务->接收消息.发送消息 。他们是 自动回复,接收语音识别结果 ,接收事件推送,接收普通消息和验证消息真实性
	 * 获取用户地理位置(已关闭)如果打开,一旦用户进入公众号聊天窗口,并且用户同意了获取位置,那么地理位置信息将被XML推送到这里
	 * 微信所有的自动推送消息和用户行为产生的消息都推推送到接口上来。
	 * 数据是XML
	 * @param req
	 * @param res
	 * @param forIntegrationTest
	 * @param token
	 */
	@SuppressWarnings("rawtypes")
	protected final void processCallback(HttpServletRequest req, HttpServletResponse res, boolean forIntegrationTest, String token) {
		LOGGER.debug("isIntegeration: "+forIntegrationTest);
		LOGGER.debug("token: "+token);
		
		MessageListener messageListener=new MessageListenerAdapter();
		Object obj=req.getAttribute(MESSAGE_LISTENER);
		LOGGER.debug(obj);
		if(obj==null){
			LOGGER.error("Can not find MessageListener for processing message");
		}
		else {
			messageListener = (MessageListener)obj;
		}
		
		String signature = req.getParameter("signature")+"";
        String timestamp = req.getParameter("timestamp")+"";
        String nonce = req.getParameter("nonce")+"";
        String echostr = req.getParameter("echostr")+"";
        
        Map map= req.getParameterMap();
        HttpParam reqParams =new HttpParam(); 
        Iterator it = map.entrySet().iterator();
        while(it.hasNext()){
        	Entry entry=(Entry)it.next();
        	String[] values=(String[])entry.getValue();
        	reqParams.put(entry.getKey().toString(), values);
        	
        }
        LOGGER.debug(reqParams);
        
        HttpParam headerParams =new HttpParam(); 
        Enumeration enumeration = req.getHeaderNames();
        while(enumeration.hasMoreElements()){
        	String name=(String)enumeration.nextElement();
        	Enumeration values=req.getHeaders(name);
        	List valueList=new ArrayList();
        	while(values.hasMoreElements()){
        		valueList.add(values.nextElement().toString());
        	}
        	String[] array=new String[valueList.size()];
        	int i=0;
        	for(String s:valueList){
        		array[i]=s;
        		i++;
        	}
        	headerParams.put(name, array);
        	
        }
        LOGGER.debug(headerParams);
        
        if(!authenticate(signature, timestamp, nonce, token)) {
    		try {
				res.getWriter().write("You are not supposed to be here.");
				LOGGER.debug("You are not supposed to be here.");
			} catch (IOException e) {
				LOGGER.error("error on authenticate");
				e.printStackTrace();
			}
			return ;
		}
        
		if(forIntegrationTest){
            try {
				if(authenticate(signature, timestamp, nonce, token)) {
					res.getWriter().write(echostr);
					LOGGER.debug("OK");
					this.onIntegrationSuccess(reqParams, headerParams);
				}
				else {
					this.onIntegrationFail(reqParams, headerParams, "validation error");
				}
			} catch (IOException e) {
				LOGGER.error("error on authenticate");
				e.printStackTrace();
				this.onIntegrationFail(reqParams, headerParams, e.getLocalizedMessage());
			}
        }
        else {
        	PassiveMessage result = null;
            try {
				Document doc=XMLUtil.createDocument(req.getReader());
				Element root=doc.getDocumentElement();
				
				Element e=XMLUtil.readFirstChild(root, "ToUserName");
				String to=(e==null?null:e.getTextContent());
				
				e=XMLUtil.readFirstChild(root, "FromUserName");
				String from=(e==null?null:e.getTextContent());
				
				String createTime=XMLUtil.readFirstChild(root, "CreateTime").getTextContent();
				String type=XMLUtil.readFirstChild(root, "MsgType").getTextContent();
				
				e=XMLUtil.readFirstChild(root, "MsgId");
				String msgId=(e==null?"-1":e.getTextContent());
				
				if ("text".equals(type)) {
					InboundTextMessage message=new InboundTextMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					
					message.setContent(XMLUtil.readFirstChild(root, "Content").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result = messageListener.onTextMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("image".equals(type)) {
					InboundImageMessage message=new InboundImageMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					
					message.setPicUrl(XMLUtil.readFirstChild(root, "PicUrl").getTextContent());
					message.setMediaId(XMLUtil.readFirstChild(root, "MediaId").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result = messageListener.onImageMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("voice".equals(type)) {
					InboundVoiceMessage message=new InboundVoiceMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));

					message.setMediaId(XMLUtil.readFirstChild(root, "MediaId").getTextContent());
					message.setFormat(XMLUtil.readFirstChild(root, "Format").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result = messageListener.onVoiceMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("video".equals(type)) {
					InboundVideoMessage message=new InboundVideoMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					message.setMediaId(XMLUtil.readFirstChild(root, "MediaId").getTextContent());
					message.setThumbMediaId(XMLUtil.readFirstChild(root, "ThumbMediaId").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result = messageListener.onVideoMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("shortvideo".equals(type)) {
					InboundSmallVideoMessage message=new InboundSmallVideoMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					message.setMediaId(XMLUtil.readFirstChild(root, "MediaId").getTextContent());
					message.setThumbMediaId(XMLUtil.readFirstChild(root, "ThumbMediaId").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result= messageListener.onSmallVideoMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("location".equals(type)) {
					InboundMapLocationMessage message=new InboundMapLocationMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					
					message.setLocationX(Float.parseFloat(XMLUtil.readFirstChild(root, "Location_X").getTextContent()));
					message.setLocationY(Float.parseFloat(XMLUtil.readFirstChild(root, "Location_Y").getTextContent()));
					message.setLabel(XMLUtil.readFirstChild(root, "Label").getTextContent());
					message.setScale(Integer.parseInt(XMLUtil.readFirstChild(root, "Scale").getTextContent()));
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result= messageListener.onLocationMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				} 
				else if ("link".equals(type)) {
					InboundLinkMessage message=new InboundLinkMessage();
					message.setToUserName(to);
					message.setFromUserName(from);
					message.setCreateTime(Long.parseLong(createTime));
					message.setMsgId(Long.parseLong(msgId));
					
					message.setTitle(XMLUtil.readFirstChild(root, "Title").getTextContent());
					message.setDescription(XMLUtil.readFirstChild(root, "Description").getTextContent());
					message.setUrl(XMLUtil.readFirstChild(root, "Url").getTextContent());
					
					messageListener.preProcessMessage(message, headerParams, reqParams, doc);
					result=messageListener.onLinkMessage(message, headerParams, reqParams, doc);
					messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
					
					LOGGER.debug(message);
				}
				else if ("event".equals(type)) {
					String event = XMLUtil.readFirstChild(root, "Event").getTextContent();
					e=XMLUtil.readFirstChild(root, "EventKey");
					String eventKey=(e==null?null:e.getTextContent());
					
					if("subscribe".equalsIgnoreCase(event)){
						if(eventKey==null){
							InboundSubscribeMessage message=new InboundSubscribeMessage();
							
							message.setFromUserName(from);
							message.setToUserName(to);
							message.setFromUserName(from);
							message.setCreateTime(Long.parseLong(createTime));
							message.setMsgId(Long.parseLong(msgId));
							message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
							message.setEventKey(eventKey);
							
							messageListener.preProcessMessage(message, headerParams, reqParams, doc);
							result=messageListener.onSubscribeMessage(message, headerParams, reqParams, doc);
							messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
							
							LOGGER.debug(message);
						}
						else {//通过扫二维码关注的公众号 1. 用户未关注时,进行关注后的事件推送
							InboundQRScanSubscribeMessage message=new InboundQRScanSubscribeMessage();
							
							message.setFromUserName(from);
							message.setToUserName(to);
							message.setFromUserName(from);
							message.setCreateTime(Long.parseLong(createTime));
							message.setMsgId(Long.parseLong(msgId));
							message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
							message.setEventKey(eventKey);
							Element elTicket=XMLUtil.readFirstChild(root, "Ticket");
							if(elTicket!=null)message.setTicket(elTicket.getTextContent());
							
							messageListener.preProcessMessage(message, headerParams, reqParams, doc);
							result=messageListener.onQRScanSubscribeMessage(message, headerParams, reqParams, doc);
							messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
							
							LOGGER.debug(message);
						}
					}
					//通过扫二维码关注的公众号 2. 用户已关注时的事件推送
					if("SCAN".equalsIgnoreCase(event)){
						InboundQRScanSubscribeMessage message=new InboundQRScanSubscribeMessage();
						
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						Element elTicket=XMLUtil.readFirstChild(root, "Ticket");
						if(elTicket!=null)message.setTicket(elTicket.getTextContent());
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onQRScanReSubscribeMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					else if("unsubscribe".equalsIgnoreCase(event)){
						InboundQRScanSubscribeMessage message=new InboundQRScanSubscribeMessage();
						
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onUnsubscribeMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					else if("CLICK".equalsIgnoreCase(event)){
						InboundEventMessage message=new InboundEventMessage();
						
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onMenuClickMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					else if("VIEW".equalsIgnoreCase(event)){
						InboundEventMessage message=new InboundEventMessage();
						
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onViewMenuMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					//请注意,第3个到第8个的所有事件,仅支持微信iPhone5.4.1以上版本,
					//和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。
					else if("scancode_push".equalsIgnoreCase(event)){
						InboundScancodePushEventMessage message=new InboundScancodePushEventMessage();
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						message.setScanType(XMLUtil.readFirstChild(XMLUtil.readFirstChild(root, "ScanCodeInfo"), "ScanType").getTextContent());
						message.setScanResult(XMLUtil.readFirstChild(XMLUtil.readFirstChild(root, "ScanCodeInfo"), "ScanResult").getTextContent());
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onScancodePushMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					else if("scancode_waitmsg".equalsIgnoreCase(event)){
						InboundScancodeWaitmsgMessage message=new InboundScancodeWaitmsgMessage();
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						message.setScanType(XMLUtil.readFirstChild(XMLUtil.readFirstChild(root, "ScanCodeInfo"), "ScanType").getTextContent());
						message.setScanResult(XMLUtil.readFirstChild(XMLUtil.readFirstChild(root, "ScanCodeInfo"), "ScanResult").getTextContent());
						
						messageListener.preProcessMessage(message, headerParams, reqParams, doc);
						result=messageListener.onScancodeWaitmsgMessage(message, headerParams, reqParams, doc);
						messageListener.postProcessMessage(result, message, headerParams, reqParams, doc);
						
						LOGGER.debug(message);
					}
					else if("pic_sysphoto".equalsIgnoreCase(event)){
						InboundPicSysphotoMessage message=new InboundPicSysphotoMessage();
						message.setFromUserName(from);
						message.setToUserName(to);
						message.setFromUserName(from);
						message.setCreateTime(Long.parseLong(createTime));
						message.setMsgId(Long.parseLong(msgId));
						message.setEvent(XMLUtil.readFirstChild(root, "Event").getTextContent());
						message.setEventKey(eventKey);
						
						NodeList list=root.getElementsByTagName("item");
						if(list!=null){
							for(int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy