xml config support & multi-step command matcher

This commit is contained in:
Sola
2015-11-26 03:54:13 +08:00
parent ad0c75c12a
commit c2b2f89805
12 changed files with 221 additions and 111 deletions

View File

@@ -0,0 +1,51 @@
package love.sola.netsupport.wechat;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/11/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public enum Command {
REGISTER(0, "Register", "(?i)^Register$"),
;
private static final Map<Integer, Command> ID_MAP = new HashMap<>();
static {
for (Command type : values()) {
if (type.id > 0) {
ID_MAP.put(type.id, type);
}
}
}
@Getter
private final String name;
@Getter
private final String regex;
@Getter
private final int id;
Command(int id, String name, String regex) {
this.name = name;
this.id = id;
this.regex = regex;
}
public static Command fromId(int id) {
return ID_MAP.get(id);
}
@Override
public String toString() {
return name;
}
}

View File

@@ -1,11 +1,11 @@
package love.sola.netsupport.wechat;
import love.sola.netsupport.config.Settings;
import love.sola.netsupport.wechat.handler.RegisterHandler;
import love.sola.netsupport.wechat.intercepter.CheckSpamInterceptor;
import love.sola.netsupport.wechat.matcher.CommandMatcher;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpServiceImpl;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
@@ -29,6 +29,7 @@ public class WxMpServlet extends HttpServlet {
protected WxMpInMemoryConfigStorage config;
protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter;
protected CheckSpamInterceptor checkSpamInterceptor;
public WxMpServlet() {
instance = this;
@@ -46,7 +47,15 @@ public class WxMpServlet extends HttpServlet {
wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(config);
checkSpamInterceptor = new CheckSpamInterceptor();
wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter.rule()
.async(false)
.matcher(new CommandMatcher(Command.REGISTER))
.handler(new RegisterHandler())
.interceptor(checkSpamInterceptor)
.end();
}
@Override
@@ -75,12 +84,12 @@ public class WxMpServlet extends HttpServlet {
String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ? "raw" : request.getParameter("encrypt_type");
if ("raw".equals(encryptType)) {
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
response.getWriter().write(outMessage.toXml());
return;
}
// if ("raw".equals(encryptType)) {
// WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
// WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
// response.getWriter().write(outMessage.toXml());
// return;
// }
if ("aes".equals(encryptType)) {
String msgSignature = request.getParameter("msg_signature");
@@ -98,4 +107,5 @@ public class WxMpServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}

View File

@@ -1,28 +0,0 @@
package love.sola.netsupport.wechat.handler;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import java.util.HashMap;
import java.util.Map;
/**
* ***********************************************
* Created by Sola on 2015/11/5.
* Don't modify this source without my agreement
* ***********************************************
*/
public class HandlerList {
public static Map<String, Class<? extends WxMpMessageHandler>> handlers = new HashMap<>();
static {
handlers.put("Register", RegisterHandler.class);
}
public void init(WxMpMessageRouter router) {
}
}

View File

@@ -1,13 +1,17 @@
package love.sola.netsupport.wechat.handler;
import love.sola.netsupport.pojo.User;
import love.sola.netsupport.wechat.Command;
import love.sola.netsupport.wechat.matcher.CommandMatcher;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.outxmlbuilder.TextBuilder;
import java.util.HashMap;
import java.util.Map;
/**
@@ -18,16 +22,24 @@ import java.util.Map;
*/
public class RegisterHandler implements WxMpMessageHandler {
public RegisterHandler(WxMpMessageRouter router) {
router.rule().async(false).rContent("^").handler(this).end();
}
Map<String, User> pre_confirm = new HashMap<>();
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager)
throws WxErrorException {
return null;
TextBuilder out = WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName());
String in = wxMessage.getContent();
String userName = wxMessage.getFromUserName();
if (in.matches(Command.REGISTER.getRegex())) {
out.content("Welcome, please type your student identification number.");
} else if (pre_confirm.containsKey(userName)) {
//TODO
} else {
out.content("Illegal Operation.");
CommandMatcher.inCmdUsers.remove(userName);
}
return out.build();
}
}

View File

@@ -3,6 +3,7 @@ package love.sola.netsupport.wechat.intercepter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import love.sola.netsupport.config.Settings;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageInterceptor;
@@ -20,26 +21,28 @@ import java.util.concurrent.TimeUnit;
*/
public class CheckSpamInterceptor implements WxMpMessageInterceptor {
private static class ValueLoader extends CacheLoader<String, Long> {
private class ValueLoader extends CacheLoader<String, Long> {
@Override
public Long load(String key) throws Exception {
return System.currentTimeMillis(); //TODO: CONFIGURATION
return System.currentTimeMillis() + Settings.I.Check_Spam_Interval;
}
}
private static LoadingCache<String, Long> cache = CacheBuilder.newBuilder()
private LoadingCache<String, Long> cache = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.weakKeys()
.maximumSize(4096)
.expireAfterWrite(5, TimeUnit.SECONDS)
.expireAfterWrite(Settings.I.Check_Spam_Cache_Expire_Time, TimeUnit.SECONDS)
.build(new ValueLoader());
@Override
public boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
if (cache.getIfPresent(wxMessage.getFromUserName()) != null) {
Long l = cache.getIfPresent(wxMessage.getFromUserName());
if (l != null && l > System.currentTimeMillis()) {
return false;
}
return false;
cache.refresh(wxMessage.getFromUserName());
return true;
}
}

View File

@@ -0,0 +1,36 @@
package love.sola.netsupport.wechat.matcher;
import love.sola.netsupport.wechat.Command;
import me.chanjar.weixin.mp.api.WxMpMessageMatcher;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* ***********************************************
* Created by Sola on 2015/11/26.
* Don't modify this source without my agreement
* ***********************************************
*/
public class CommandMatcher implements WxMpMessageMatcher {
public static Map<String, Command> inCmdUsers = new ConcurrentHashMap<>();
Command command;
public CommandMatcher(Command command) {
this.command = command;
}
@Override
public boolean match(WxMpXmlMessage message) {
String fromUser = message.getFromUserName();
if (inCmdUsers.containsKey(fromUser)) {
return command == inCmdUsers.get(fromUser);
} else {
return message.getContent().matches(command.getRegex());
}
}
}