下面是微信公众平台app开发框架sophia部分源代码,对sophia设计、应用的描述请查阅我前面的文章: 《微信公众平台的STRUTS 》和
/** * 消息处理器接口,根据请求返回一个微信响应消息 * @author Peter * */ public interface MessageProcessor { /** * 根据请求返回一个微信响应消息 * @param request * @return */ public ResponseMessage responseMessageObject(RequestMessage request); }
/** * 抽象的微信消息处理器,一个微信公众号需一个处理器 * @author Peter * */ public abstract class AbstractMessageProcessor implements MessageProcessor { private static Log log = LogFactory.getLog(AbstractMessageProcessor.class); /** * 响应消息对象 */ public ResponseMessage responseMessageObject(RequestMessage request) { log.info("into responseMessageObject ->" + request); if(RequestMessage.TEXT_MSG_TYPE.equals(request.getMsgType())) { return responseTextCommand((TextRequestMessage)request, false); } else if (RequestMessage.EVENT_MSG_TYPE.equals(request.getMsgType())) { return responseEvent(request); } else if (RequestMessage.PIC_MSG_TYPE.equals(request.getMsgType())) { return responseImageMessage(request); } else if (RequestMessage.VIDEO_MSG_TYPE.equals(request.getMsgType())) { return responseVideoMessage(request); } else { TextResponseMessage response = new TextResponseMessage(); response.setToUserName(request.getFromUserName()); response.setFromUserName(request.getToUserName()); response.setContent("错误的请求!"); return response; } } /** * 响应视频上传 * @param request * @return */ public ResponseMessage responseVideoMessage(RequestMessage request) { return buildResponseMessage(request, "你的视频已经上传成功!"); } /** * 响应图片上传 * @param request * @return */ public ResponseMessage responseImageMessage(RequestMessage request) { return buildResponseMessage(request, "你的图片已经上传成功!"); } /** * 响应时事件方法 * @param request * @return */ public ResponseMessage responseEvent(RequestMessage request) { EventRequestMessage event = (EventRequestMessage)request; log.info("into responseEvent ->" + request); if(event.getEvent().toUpperCase().equals("CLICK")) { return responseClickEvent(event); } else if (event.getEvent().equals("subscribe")) { return responseSubscribeEvent(request); } else { return responseUnsubscribeEvent(request); } } public ResponseMessage responseSubscribeEvent(RequestMessage request) { return buildResponseMessage(request,"欢迎订阅!..."); } public ResponseMessage responseUnsubscribeEvent(RequestMessage request) { return buildResponseMessage(request,"欢迎再次订阅!..."); } public ResponseMessage responseClickEvent(EventRequestMessage request) { //转换为文本命令 TextRequestMessage trm = new TextRequestMessage(request.getToUserName(), request.getFromUserName(), request.getCreateTime(), RequestMessage.TEXT_MSG_TYPE, request.getCorpId(), request.getMsgId(), request.getEnventKey()); trm.setHandle(request.getHandle()); return responseTextCommand(trm,true); } /** * 模版方法, * 1、通过请求文本获取命令对象 * 2、如果命令对象是查询的,则保存命令信息,以便特殊命令“下一页”可以翻页 * 3、优先处理来自点击的命令 * @param request * @return */ private ResponseMessage responseTextCommand(TextRequestMessage request, boolean fromClick) { CommandParsed parsed = getCommandParsed(); try { Command command = null; if(!fromClick && SessionManager.isEditSession(request)) { TextRequestMessage currentSession = SessionManager.currentEditSession(request); currentSession.setExecuteTimes(currentSession.getExecuteTimes() + 1); command = parsed.getCommand(currentSession.getContent()); request.setExecuteTimes(currentSession.getExecuteTimes()); return command.execute(request); } else { command = parsed.getCommand(request.getContent()); SessionManager.createSession(request,command.commandMode()); return command.execute(request); } } catch (IllegalReplyException e) { log.info("IllegalReplyException :" + e.getMessage()); return buildResponseMessage(request, e.getMessage()); } catch (NotFoundCommandException e) { log.info("NotFoundCommandException :" + e.getMessage()); return buildResponseMessage(request,e.getMessage()); } catch (Exception e) { return buildResponseMessage(request, "此命令不存在,获取帮助回复:BZ"); } } /** * 创建响应消息 * @param request * @param msgText * @return */ public ResponseMessage buildResponseMessage(RequestMessage request, String msgText) { TextResponseMessage message = new TextResponseMessage(); message.setContent(msgText); message.setToUserName(request.getToUserName()); message.setFromUserName(request.getFromUserName()); return message; } /** * 抽象方法,获取命令解析器 * @return */ public abstract CommandParsed getCommandParsed(); }
/** * 抽象命令解析器 * @author Peter * */ public abstract class AbstractCommandParsed implements CommandParsed { protected static Log log = LogFactory.getLog(AbstractCommandParsed.class); /** * 代码-命令映射器 */ private Map<String, Command> commands = new HashMap<String, Command>(); /** * 别名-命令映射器 */ private Map<String, Command> aliasCommands = new HashMap<String, Command>(); public AbstractCommandParsed() { initCommands(); } /** * 初始化基本命令 */ private void initCommands() { List<Command> list = extendCommands(); if(null == list || list.size() == 0) { list = new ArrayList<Command>(); } list.add(new HelpTextCommand(commands)); list.add(new NextTextCommand(this)); list.add(new BackTextCommand(this)); for (Iterator it = list.iterator(); it.hasNext();) { Command comm = (Command) it.next(); commands.put(comm.getCommandCode().toUpperCase(), comm); aliasCommands.put(comm.getAliasName(), comm); } } /** * 子类扩展 */ public abstract List<Command> extendCommands(); private Command text2Command(String text) { String commandCode = getCodeOrAliasOfCommand(text, commands); log.info("text2Command-->" + commandCode); if(null != commandCode && commands.get(commandCode) != null) { return commands.get(commandCode); } else { commandCode = getCodeOrAliasOfCommand(text, aliasCommands); log.info("text2Command-->" + commandCode); return aliasCommands.get(commandCode); } } /** * 根据文本获取命令或者别名,子类可以重写此方法实现特有的解析算法 * @param text * @param comms * @return */ public String getCodeOrAliasOfCommand(String text, Map<String, Command> comms) { for (Iterator it = comms.keySet().iterator(); it.hasNext();) { String commandCode = (String) it.next(); if(text.startsWith(commandCode)) { log.info("getCodeOrAliasOfCommand-->" + commandCode); return commandCode; } } return null; } /** * 根据用户回复的文本,转化成系统命令 */ public Command getCommand(String text) throws NotFoundCommandException { Command command = text2Command(text.toUpperCase()); if (command == null) { command = getDefaultCommand(); if (null == command) { throw new NotFoundCommandException("命令:\n" + text + "\n没有找到,查看帮助请回复:BZ"); } } log.info("getCommand-->" + command.getCommandCode()); return command; } /** * 建立命令和对象的映射关系 * @param name * @param command */ protected void putCommand(String name, Command command) { commands.put(name, command); } /** * 建立别名和对象的映射关系 * @param name * @param command */ protected void putAliasCommand(String name, Command command) { aliasCommands.put(name, command); } /** * 有默认处理器的必须重写这个方法 * @return */ public Command getDefaultCommand() { return null; } }
/** * 用户回复命令处理接口 * @author Peter * */ public interface Command { /** * 命令分隔字符 */ public static final String STRING_DELIM = " ,.!,"; /** * 响应微信公众平台请求 * @param request * @return */ public ResponseMessage execute(RequestMessage request) throws IllegalReplyException; /** * 获取命令模式 * @return */ public CmdMode commandMode(); /** * 命令代码 * @return */ public String getCommandCode(); /** * 命令别名 * @return */ public String getAliasName(); /** * 命令用法 * @return */ public String getHelpInfo(); }
/** * 抽象文本命令,用于帮助子类解析参数,验证等 * @author Peter * */ public abstract class AbstractTextCommand implements Command { protected static Log log = LogFactory.getLog(AbstractTextCommand.class); protected boolean isDefaultCommand = false; /** * 执行命令 */ public ResponseMessage execute(RequestMessage request) throws IllegalReplyException { log.info("-------------->" + request); if (!isAuthorization(request)) { SessionManager.destroySession(request); return buildTextResponseMessage("非法操作", (TextRequestMessage)request); } TextRequestMessage textRequest = (TextRequestMessage) request; String paramsText = getParamText(textRequest); return doExecute(textRequest, verificationReplyContent(paramsText)); } /** * 根据微信用户回复的内容,提取命令的参数 * @param textRequest * @return */ public String getParamText(TextRequestMessage textRequest) { String replyText = textRequest.getContent().toUpperCase(); if(isDefaultCommand) { replyText = getCommandCode() + "," + replyText; } String paramsText = null; if (replyText.startsWith(this.getCommandCode())) { paramsText = replyText.substring(this.getCommandCode().length()); } else { paramsText = replyText.substring(this.getAliasName().length()); } return paramsText; } /** * 真正处理业务的方法 * @param request * @param params 微信用户输入的参数 * @return */ public abstract ResponseMessage doExecute(TextRequestMessage request, String[] params); /** * 验证微信回复的内容 * @param paramsText * @return * @throws IllegalReplyException */ public String[] verificationReplyContent(String paramsText) throws IllegalReplyException { return tokenizer(paramsText); } /** * 从参数文本中进一步解析参数 * @param tokened * @return */ protected String[] tokenizer(String tokened) { StringTokenizer token = new StringTokenizer(tokened,Command.STRING_DELIM); List<String> list = new ArrayList<String>(); while (token.hasMoreTokens()) { list.add(token.nextToken()); } log.info("list------>" + list.toArray()); if(list.size() == 0) { return null; } else { return list.toArray(new String[]{}); } } public static void main(String[] args) { String str = ",3"; StringTokenizer token = new StringTokenizer(str,Command.STRING_DELIM); List<String> list = new ArrayList<String>(); while (token.hasMoreTokens()) { list.add(token.nextToken()); } System.out.println(list); System.out.println(list.toArray(new String[]{})); } public CmdMode commandMode() { return CmdMode.COMMON; } /** * 命令是否可以响应某微信用户的请求,默认授权 * @param request * @return */ public boolean isAuthorization(RequestMessage request) { return true; } /** * 创建文本响应消息对象 * @param content 文本内容 * @param request * @return */ public TextResponseMessage buildTextResponseMessage(String content,TextRequestMessage request) { TextResponseMessage respMsg = new TextResponseMessage(); respMsg.setContent(content); respMsg.setToUserName(request.getToUserName()); respMsg.setFromUserName(request.getFromUserName()); return respMsg; } /** * 创建图文消息响应对象 * @param request * @return */ public NewsResponseMessage buildNewsResponseMessage(RequestMessage request) { NewsResponseMessage news = new NewsResponseMessage(); news.setCreateTime(System.currentTimeMillis()); news.setFromUserName(request.getFromUserName()); news.setToUserName(request.getToUserName()); news.setMsgType("news"); return news; } }