mirror of
https://github.com/ZSCNetSupportDept/WechatTicketSystem.git
synced 2025-10-28 23:55:04 +08:00
xml config support & multi-step command matcher
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package love.sola.netsupport.api;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import love.sola.netsupport.enums.ResponseCode;
|
||||
import love.sola.netsupport.pojo.User;
|
||||
import love.sola.netsupport.sql.TableUser;
|
||||
|
||||
@@ -43,23 +42,23 @@ public class GetUser extends HttpServlet {
|
||||
String id = request.getParameter("id");
|
||||
String name = request.getParameter("name");
|
||||
if ((id == null || id.isEmpty()) && (name == null || name.isEmpty())) {
|
||||
out.println(gson.toJson(new Response(ResponseCode.PARAMETER_REQUIRED)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.PARAMETER_REQUIRED)));
|
||||
} else if (id != null) {
|
||||
try {
|
||||
User u = TableUser.getUserById(Integer.parseInt(id));
|
||||
if (u == null)
|
||||
out.println(gson.toJson(new Response(ResponseCode.USER_NOT_FOUND)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.USER_NOT_FOUND)));
|
||||
else
|
||||
out.println(gson.toJson(new Response(ResponseCode.OK, u)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.OK, u)));
|
||||
} catch (NumberFormatException e) {
|
||||
out.println(gson.toJson(new Response(ResponseCode.ILLEGAL_PARAMETER)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.ILLEGAL_PARAMETER)));
|
||||
}
|
||||
} else {
|
||||
User u = TableUser.getUserByName(name);
|
||||
if (u == null)
|
||||
out.println(gson.toJson(new Response(ResponseCode.USER_NOT_FOUND)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.USER_NOT_FOUND)));
|
||||
else
|
||||
out.println(gson.toJson(new Response(ResponseCode.OK, u)));
|
||||
out.println(gson.toJson(new Response(Response.ResponseCode.OK, u)));
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package love.sola.netsupport.api;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import love.sola.netsupport.enums.ResponseCode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ***********************************************
|
||||
@@ -26,4 +28,42 @@ public class Response {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum ResponseCode {
|
||||
|
||||
OK(0, "OK"),
|
||||
PARAMETER_REQUIRED(-1, "Parameter Required"),
|
||||
ILLEGAL_PARAMETER(-2, "Illegal parameter"),
|
||||
USER_NOT_FOUND(-11, "User not found"),
|
||||
;
|
||||
|
||||
private static final Map<Integer, ResponseCode> ID_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (ResponseCode type : values()) {
|
||||
if (type.id > 0) {
|
||||
ID_MAP.put(type.id, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final String info;
|
||||
public final int id;
|
||||
|
||||
ResponseCode(int id, String info) {
|
||||
this.info = info;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static ResponseCode fromId(int id) {
|
||||
return ID_MAP.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package love.sola.netsupport.config;
|
||||
|
||||
import lombok.ToString;
|
||||
import love.sola.netsupport.sql.TableConfig;
|
||||
|
||||
/**
|
||||
* ***********************************************
|
||||
@@ -13,6 +14,10 @@ public class Settings {
|
||||
|
||||
public static Settings I;
|
||||
|
||||
static {
|
||||
I = TableConfig.getSettings();
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONFIGURATIONS
|
||||
// -------------------------------------------- //
|
||||
@@ -21,10 +26,10 @@ public class Settings {
|
||||
public String Wechat_Token;
|
||||
public String Wechat_AesKey;
|
||||
|
||||
public int Check_Spam_Cache_Expire_Time;
|
||||
public int Check_Spam_Interval;
|
||||
|
||||
//No arg constructor for Yaml.loadAs
|
||||
public Settings() {
|
||||
I = this;
|
||||
}
|
||||
public Settings() { I = this; }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package love.sola.netsupport.config;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import lombok.ToString;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@XStreamAlias("wechat-config")
|
||||
@ToString
|
||||
public class WxMpXmlInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T fromXml(Class<T> clazz, InputStream is) {
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.alias("wechat-config", clazz);
|
||||
xstream.processAnnotations(clazz);
|
||||
return (T) xstream.fromXML(is);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package love.sola.netsupport.enums;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* ***********************************************
|
||||
* Created by Sola on 2015/11/6.
|
||||
* Don't modify this source without my agreement
|
||||
* ***********************************************
|
||||
*/
|
||||
public enum ResponseCode {
|
||||
|
||||
OK(0, "OK"),
|
||||
PARAMETER_REQUIRED(-1, "Parameter Required"),
|
||||
ILLEGAL_PARAMETER(-2, "Illegal parameter"),
|
||||
USER_NOT_FOUND(-11, "User not found"),
|
||||
;
|
||||
|
||||
private static final Map<Integer, ResponseCode> ID_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (ResponseCode type : values()) {
|
||||
if (type.id > 0) {
|
||||
ID_MAP.put(type.id, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final String info;
|
||||
public final int id;
|
||||
|
||||
ResponseCode(int id, String info) {
|
||||
this.info = info;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static ResponseCode fromId(int id) {
|
||||
return ID_MAP.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
51
src/main/java/love/sola/netsupport/wechat/Command.java
Normal file
51
src/main/java/love/sola/netsupport/wechat/Command.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
6
src/main/resources/wechat-config.xml
Normal file
6
src/main/resources/wechat-config.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<wechat-config>
|
||||
<appId>****</appId>
|
||||
<secret>****</secret>
|
||||
<token>****</token>
|
||||
<aesKey>****</aesKey>
|
||||
</wechat-config>
|
||||
Reference in New Issue
Block a user