| @@ -70,11 +70,6 @@ | |||
| <artifactId>gson</artifactId> | |||
| <version>2.2.2</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>org.apache.commons</groupId> | |||
| <artifactId>commons-lang3</artifactId> | |||
| <version>3.1</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>commons-codec</groupId> | |||
| <artifactId>commons-codec</artifactId> | |||
| @@ -0,0 +1,100 @@ | |||
| package me.chanjar.weixin.common.util; | |||
| /** | |||
| * copy from apache-commons-lang3 | |||
| */ | |||
| public class StringUtils { | |||
| /** | |||
| * <p>Checks if a CharSequence is whitespace, empty ("") or null.</p> | |||
| * | |||
| * <pre> | |||
| * StringUtils.isBlank(null) = true | |||
| * StringUtils.isBlank("") = true | |||
| * StringUtils.isBlank(" ") = true | |||
| * StringUtils.isBlank("bob") = false | |||
| * StringUtils.isBlank(" bob ") = false | |||
| * </pre> | |||
| * | |||
| * @param cs the CharSequence to check, may be null | |||
| * @return {@code true} if the CharSequence is null, empty or whitespace | |||
| * @since 2.0 | |||
| * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence) | |||
| */ | |||
| public static boolean isBlank(CharSequence cs) { | |||
| int strLen; | |||
| if (cs == null || (strLen = cs.length()) == 0) { | |||
| return true; | |||
| } | |||
| for (int i = 0; i < strLen; i++) { | |||
| if (Character.isWhitespace(cs.charAt(i)) == false) { | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| /** | |||
| * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p> | |||
| * | |||
| * <pre> | |||
| * StringUtils.isNotBlank(null) = false | |||
| * StringUtils.isNotBlank("") = false | |||
| * StringUtils.isNotBlank(" ") = false | |||
| * StringUtils.isNotBlank("bob") = true | |||
| * StringUtils.isNotBlank(" bob ") = true | |||
| * </pre> | |||
| * | |||
| * @param cs the CharSequence to check, may be null | |||
| * @return {@code true} if the CharSequence is | |||
| * not empty and not null and not whitespace | |||
| * @since 2.0 | |||
| * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence) | |||
| */ | |||
| public static boolean isNotBlank(CharSequence cs) { | |||
| return !StringUtils.isBlank(cs); | |||
| } | |||
| /** | |||
| * <p>Checks if a CharSequence is empty ("") or null.</p> | |||
| * | |||
| * <pre> | |||
| * StringUtils.isEmpty(null) = true | |||
| * StringUtils.isEmpty("") = true | |||
| * StringUtils.isEmpty(" ") = false | |||
| * StringUtils.isEmpty("bob") = false | |||
| * StringUtils.isEmpty(" bob ") = false | |||
| * </pre> | |||
| * | |||
| * <p>NOTE: This method changed in Lang version 2.0. | |||
| * It no longer trims the CharSequence. | |||
| * That functionality is available in isBlank().</p> | |||
| * | |||
| * @param cs the CharSequence to check, may be null | |||
| * @return {@code true} if the CharSequence is empty or null | |||
| * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) | |||
| */ | |||
| public static boolean isEmpty(CharSequence cs) { | |||
| return cs == null || cs.length() == 0; | |||
| } | |||
| /** | |||
| * <p>Checks if a CharSequence is not empty ("") and not null.</p> | |||
| * | |||
| * <pre> | |||
| * StringUtils.isNotEmpty(null) = false | |||
| * StringUtils.isNotEmpty("") = false | |||
| * StringUtils.isNotEmpty(" ") = true | |||
| * StringUtils.isNotEmpty("bob") = true | |||
| * StringUtils.isNotEmpty(" bob ") = true | |||
| * </pre> | |||
| * | |||
| * @param cs the CharSequence to check, may be null | |||
| * @return {@code true} if the CharSequence is not empty and not null | |||
| * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence) | |||
| */ | |||
| public static boolean isNotEmpty(CharSequence cs) { | |||
| return !StringUtils.isEmpty(cs); | |||
| } | |||
| } | |||
| @@ -1,12 +1,9 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| import me.chanjar.weixin.common.bean.result.WxError; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.util.http.InputStreamResponseHandler; | |||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import org.apache.http.Header; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.client.ClientProtocolException; | |||
| @@ -16,8 +16,9 @@ public interface WxCpMessageHandler { | |||
| * | |||
| * @param wxMessage | |||
| * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 | |||
| * @param wxCpService | |||
| * @return xml格式的消息,如果在异步规则里处理的话,可以返回null | |||
| */ | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context); | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService); | |||
| } | |||
| @@ -15,8 +15,9 @@ public interface WxCpMessageInterceptor { | |||
| * 拦截微信消息 | |||
| * @param wxMessage | |||
| * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 | |||
| * @param wxCpService | |||
| * @return true代表OK,false代表不OK | |||
| */ | |||
| public boolean intercept(WxCpXmlMessage wxMessage, Map<String, Object> context); | |||
| public boolean intercept(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService); | |||
| } | |||
| @@ -45,12 +45,18 @@ public class WxCpMessageRouter { | |||
| private final ExecutorService es = Executors.newCachedThreadPool(); | |||
| private final WxCpService wxCpService; | |||
| public WxCpMessageRouter(WxCpService wxCpService) { | |||
| this.wxCpService = wxCpService; | |||
| } | |||
| /** | |||
| * 开始一个新的Route规则 | |||
| * @return | |||
| */ | |||
| public Rule rule() { | |||
| return new Rule(this); | |||
| return new Rule(this, wxCpService); | |||
| } | |||
| /** | |||
| @@ -101,6 +107,8 @@ public class WxCpMessageRouter { | |||
| private final WxCpMessageRouter routerBuilder; | |||
| private final WxCpService wxCpService; | |||
| private boolean async = true; | |||
| private String msgType; | |||
| @@ -121,8 +129,9 @@ public class WxCpMessageRouter { | |||
| private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>(); | |||
| protected Rule(WxCpMessageRouter routerBuilder) { | |||
| protected Rule(WxCpMessageRouter routerBuilder, WxCpService wxCpService) { | |||
| this.routerBuilder = routerBuilder; | |||
| this.wxCpService = wxCpService; | |||
| } | |||
| /** | |||
| @@ -288,7 +297,7 @@ public class WxCpMessageRouter { | |||
| Map<String, Object> context = new HashMap<String, Object>(); | |||
| // 如果拦截器不通过 | |||
| for (WxCpMessageInterceptor interceptor : this.interceptors) { | |||
| if (!interceptor.intercept(wxMessage, context)) { | |||
| if (!interceptor.intercept(wxMessage, context, wxCpService)) { | |||
| return null; | |||
| } | |||
| } | |||
| @@ -297,7 +306,7 @@ public class WxCpMessageRouter { | |||
| WxCpXmlOutMessage res = null; | |||
| for (WxCpMessageHandler handler : this.handlers) { | |||
| // 返回最后handler的结果 | |||
| res = handler.handle(wxMessage, context); | |||
| res = handler.handle(wxMessage, context, wxCpService); | |||
| } | |||
| return res; | |||
| } | |||
| @@ -1,25 +1,27 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.StringReader; | |||
| import java.util.List; | |||
| import java.util.UUID; | |||
| import java.util.concurrent.atomic.AtomicBoolean; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.JsonObject; | |||
| import com.google.gson.JsonPrimitive; | |||
| import com.google.gson.internal.Streams; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.google.gson.stream.JsonReader; | |||
| import me.chanjar.weixin.common.bean.WxAccessToken; | |||
| import me.chanjar.weixin.common.bean.WxMenu; | |||
| import me.chanjar.weixin.common.bean.result.WxError; | |||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
| import me.chanjar.weixin.common.util.json.GsonHelper; | |||
| import me.chanjar.weixin.cp.bean.*; | |||
| import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.common.util.crypto.SHA1; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import me.chanjar.weixin.common.util.http.*; | |||
| import me.chanjar.weixin.common.util.json.GsonHelper; | |||
| import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpTag; | |||
| import me.chanjar.weixin.cp.bean.WxCpUser; | |||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.auth.AuthScope; | |||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||
| @@ -33,20 +35,13 @@ import org.apache.http.impl.client.BasicResponseHandler; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import org.apache.http.impl.client.HttpClients; | |||
| import me.chanjar.weixin.cp.bean.WxCpDepart; | |||
| import me.chanjar.weixin.common.bean.result.WxError; | |||
| import me.chanjar.weixin.cp.bean.WxCpUser; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
| import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.internal.Streams; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.google.gson.stream.JsonReader; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.StringReader; | |||
| import java.util.List; | |||
| import java.util.UUID; | |||
| import java.util.concurrent.atomic.AtomicBoolean; | |||
| public class WxCpServiceImpl implements WxCpService { | |||
| @@ -8,17 +8,12 @@ | |||
| */ | |||
| package me.chanjar.weixin.cp.util.json; | |||
| import java.lang.reflect.Type; | |||
| import com.google.gson.*; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.JsonObject; | |||
| import com.google.gson.JsonSerializationContext; | |||
| import com.google.gson.JsonSerializer; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import java.lang.reflect.Type; | |||
| /** | |||
| * | |||
| @@ -1,6 +1,6 @@ | |||
| package me.chanjar.weixin.cp.api; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| @@ -47,7 +47,7 @@ public class WxCpMessageRouterTest { | |||
| @Test(dataProvider="messages-1") | |||
| public void testSync(WxCpXmlMessage message, String expected) { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| prepare(false, sb, router); | |||
| router.route(message); | |||
| Assert.assertEquals(sb.toString(), expected); | |||
| @@ -56,7 +56,7 @@ public class WxCpMessageRouterTest { | |||
| @Test(dataProvider="messages-1") | |||
| public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(); | |||
| WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| prepare(true, sb, router); | |||
| router.route(message); | |||
| Thread.sleep(500l); | |||
| @@ -64,10 +64,10 @@ public class WxCpMessageRouterTest { | |||
| } | |||
| public void testConcurrency() throws InterruptedException { | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(); | |||
| final WxCpMessageRouter router = new WxCpMessageRouter(null); | |||
| router.rule().handler(new WxCpMessageHandler() { | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context) { | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService) { | |||
| return null; | |||
| } | |||
| }).end(); | |||
| @@ -149,7 +149,7 @@ public class WxCpMessageRouterTest { | |||
| } | |||
| @Override | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context) { | |||
| public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService) { | |||
| sb.append(this.echoStr).append(','); | |||
| return null; | |||
| } | |||
| @@ -1,11 +1,11 @@ | |||
| package me.chanjar.weixin.cp.demo; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.cp.api.*; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | |||
| import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import javax.servlet.ServletException; | |||
| import javax.servlet.http.HttpServlet; | |||
| @@ -21,8 +21,8 @@ import java.util.Map; | |||
| */ | |||
| public class WxCpDemoServlet extends HttpServlet { | |||
| protected WxCpService wxCpService; | |||
| protected WxCpConfigStorage wxCpConfigStorage; | |||
| protected WxCpService wxCpService; | |||
| protected WxCpMessageRouter wxCpMessageRouter; | |||
| @Override public void init() throws ServletException { | |||
| @@ -37,7 +37,7 @@ public class WxCpDemoServlet extends HttpServlet { | |||
| wxCpService.setWxCpConfigStorage(config); | |||
| WxCpMessageHandler handler = new WxCpMessageHandler() { | |||
| @Override public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context) { | |||
| @Override public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService) { | |||
| WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||
| .TEXT() | |||
| .content("测试加密消息") | |||
| @@ -48,7 +48,7 @@ public class WxCpDemoServlet extends HttpServlet { | |||
| } | |||
| }; | |||
| wxCpMessageRouter = new WxCpMessageRouter(); | |||
| wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||
| wxCpMessageRouter | |||
| .rule() | |||
| .async(false) | |||
| @@ -64,13 +64,14 @@ public class WxCpDemoServlet extends HttpServlet { | |||
| @Override protected void service(HttpServletRequest request, HttpServletResponse response) | |||
| throws ServletException, IOException { | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||
| String msgSignature = request.getParameter("msg_signature"); | |||
| String nonce = request.getParameter("nonce"); | |||
| String timestamp = request.getParameter("timestamp"); | |||
| String echostr = request.getParameter("echostr"); | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||
| if (StringUtils.isNotBlank(echostr)) { | |||
| if (!wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) { | |||
| // 消息签名不正确,说明不是公众平台发过来的消息 | |||
| @@ -84,11 +85,8 @@ public class WxCpDemoServlet extends HttpServlet { | |||
| return; | |||
| } | |||
| WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||
| WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); | |||
| if (outMessage != null) { | |||
| response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); | |||
| } | |||
| @@ -16,8 +16,9 @@ public interface WxMpMessageHandler { | |||
| * | |||
| * @param wxMessage | |||
| * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 | |||
| * @param wxMpService | |||
| * @return xml格式的消息,如果在异步规则里处理的话,可以返回null | |||
| */ | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context); | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService); | |||
| } | |||
| @@ -15,8 +15,9 @@ public interface WxMpMessageInterceptor { | |||
| * 拦截微信消息 | |||
| * @param wxMessage | |||
| * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 | |||
| * @param wxMpService | |||
| * @return true代表OK,false代表不OK | |||
| */ | |||
| public boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context); | |||
| public boolean intercept(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService); | |||
| } | |||
| @@ -43,14 +43,20 @@ public class WxMpMessageRouter { | |||
| private final List<Rule> rules = new ArrayList<Rule>(); | |||
| private final ExecutorService es = Executors.newCachedThreadPool(); | |||
| private final ExecutorService executorService = Executors.newCachedThreadPool(); | |||
| private final WxMpService wxMpService; | |||
| public WxMpMessageRouter(WxMpService wxMpService) { | |||
| this.wxMpService = wxMpService; | |||
| } | |||
| /** | |||
| * 开始一个新的Route规则 | |||
| * @return | |||
| */ | |||
| public Rule rule() { | |||
| return new Rule(this); | |||
| return new Rule(this, wxMpService); | |||
| } | |||
| /** | |||
| @@ -73,7 +79,7 @@ public class WxMpMessageRouter { | |||
| if (matchRules.get(0).async) { | |||
| // 只要第一个是异步的,那就异步执行 | |||
| // 在另一个线程里执行 | |||
| es.submit(new Runnable() { | |||
| executorService.submit(new Runnable() { | |||
| public void run() { | |||
| for (final Rule rule : matchRules) { | |||
| rule.service(wxMessage); | |||
| @@ -101,6 +107,8 @@ public class WxMpMessageRouter { | |||
| private final WxMpMessageRouter routerBuilder; | |||
| private final WxMpService wxMpService; | |||
| private boolean async = true; | |||
| private String msgType; | |||
| @@ -119,8 +127,9 @@ public class WxMpMessageRouter { | |||
| private List<WxMpMessageInterceptor> interceptors = new ArrayList<WxMpMessageInterceptor>(); | |||
| protected Rule(WxMpMessageRouter routerBuilder) { | |||
| protected Rule(WxMpMessageRouter routerBuilder, WxMpService wxMpService) { | |||
| this.routerBuilder = routerBuilder; | |||
| this.wxMpService = wxMpService; | |||
| } | |||
| /** | |||
| @@ -274,7 +283,7 @@ public class WxMpMessageRouter { | |||
| Map<String, Object> context = new HashMap<String, Object>(); | |||
| // 如果拦截器不通过 | |||
| for (WxMpMessageInterceptor interceptor : this.interceptors) { | |||
| if (!interceptor.intercept(wxMessage, context)) { | |||
| if (!interceptor.intercept(wxMessage, context, wxMpService)) { | |||
| return null; | |||
| } | |||
| } | |||
| @@ -283,7 +292,7 @@ public class WxMpMessageRouter { | |||
| WxMpXmlOutMessage res = null; | |||
| for (WxMpMessageHandler handler : this.handlers) { | |||
| // 返回最后handler的结果 | |||
| res = handler.handle(wxMessage, context); | |||
| res = handler.handle(wxMessage, context, wxMpService); | |||
| } | |||
| return res; | |||
| } | |||
| @@ -10,6 +10,7 @@ import me.chanjar.weixin.common.bean.WxMenu; | |||
| import me.chanjar.weixin.common.bean.result.WxError; | |||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.common.util.crypto.SHA1; | |||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||
| import me.chanjar.weixin.common.util.http.*; | |||
| @@ -18,7 +19,6 @@ import me.chanjar.weixin.mp.bean.*; | |||
| import me.chanjar.weixin.mp.bean.result.*; | |||
| import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; | |||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.auth.AuthScope; | |||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||
| @@ -27,7 +27,6 @@ import org.apache.http.client.CredentialsProvider; | |||
| import org.apache.http.client.config.RequestConfig; | |||
| import org.apache.http.client.methods.CloseableHttpResponse; | |||
| import org.apache.http.client.methods.HttpGet; | |||
| import org.apache.http.client.methods.HttpPost; | |||
| import org.apache.http.impl.client.BasicCredentialsProvider; | |||
| import org.apache.http.impl.client.BasicResponseHandler; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| @@ -38,7 +37,6 @@ import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.io.StringReader; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.UUID; | |||
| import java.util.concurrent.atomic.AtomicBoolean; | |||
| @@ -1,6 +1,6 @@ | |||
| package me.chanjar.weixin.mp.api; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| @@ -47,7 +47,7 @@ public class WxMpMessageRouterTest { | |||
| @Test(dataProvider="messages-1") | |||
| public void testSync(WxMpXmlMessage message, String expected) { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxMpMessageRouter router = new WxMpMessageRouter(); | |||
| WxMpMessageRouter router = new WxMpMessageRouter(null); | |||
| prepare(false, sb, router); | |||
| router.route(message); | |||
| Assert.assertEquals(sb.toString(), expected); | |||
| @@ -56,7 +56,7 @@ public class WxMpMessageRouterTest { | |||
| @Test(dataProvider="messages-1") | |||
| public void testAsync(WxMpXmlMessage message, String expected) throws InterruptedException { | |||
| StringBuffer sb = new StringBuffer(); | |||
| WxMpMessageRouter router = new WxMpMessageRouter(); | |||
| WxMpMessageRouter router = new WxMpMessageRouter(null); | |||
| prepare(true, sb, router); | |||
| router.route(message); | |||
| Thread.sleep(500l); | |||
| @@ -64,10 +64,10 @@ public class WxMpMessageRouterTest { | |||
| } | |||
| public void testConcurrency() throws InterruptedException { | |||
| final WxMpMessageRouter router = new WxMpMessageRouter(); | |||
| final WxMpMessageRouter router = new WxMpMessageRouter(null); | |||
| router.rule().handler(new WxMpMessageHandler() { | |||
| @Override | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context) { | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService) { | |||
| return null; | |||
| } | |||
| }).end(); | |||
| @@ -149,7 +149,7 @@ public class WxMpMessageRouterTest { | |||
| } | |||
| @Override | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context) { | |||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService) { | |||
| sb.append(this.echoStr).append(','); | |||
| return null; | |||
| } | |||
| @@ -1,10 +1,10 @@ | |||
| package me.chanjar.weixin.mp.demo; | |||
| import me.chanjar.weixin.common.util.StringUtils; | |||
| import me.chanjar.weixin.mp.api.*; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import javax.servlet.ServletException; | |||
| import javax.servlet.http.HttpServlet; | |||
| @@ -20,8 +20,8 @@ import java.util.Map; | |||
| */ | |||
| public class WxMpDemoServlet extends HttpServlet { | |||
| protected WxMpService wxMpService; | |||
| protected WxMpConfigStorage wxMpConfigStorage; | |||
| protected WxMpService wxMpService; | |||
| protected WxMpMessageRouter wxMpMessageRouter; | |||
| @Override public void init() throws ServletException { | |||
| @@ -36,7 +36,7 @@ public class WxMpDemoServlet extends HttpServlet { | |||
| wxMpService.setWxMpConfigStorage(config); | |||
| WxMpMessageHandler handler = new WxMpMessageHandler() { | |||
| @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context) { | |||
| @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService) { | |||
| WxMpXmlOutTextMessage m | |||
| = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName()) | |||
| .toUser(wxMessage.getFromUserName()).build(); | |||
| @@ -44,7 +44,7 @@ public class WxMpDemoServlet extends HttpServlet { | |||
| } | |||
| }; | |||
| wxMpMessageRouter = new WxMpMessageRouter(); | |||
| wxMpMessageRouter = new WxMpMessageRouter(wxMpService); | |||
| wxMpMessageRouter | |||
| .rule() | |||
| .async(false) | |||
| @@ -60,13 +60,13 @@ public class WxMpDemoServlet extends HttpServlet { | |||
| @Override protected void service(HttpServletRequest request, HttpServletResponse response) | |||
| throws ServletException, IOException { | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||
| String signature = request.getParameter("signature"); | |||
| String nonce = request.getParameter("nonce"); | |||
| String timestamp = request.getParameter("timestamp"); | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| response.setStatus(HttpServletResponse.SC_OK); | |||
| if (!wxMpService.checkSignature(timestamp, nonce, signature)) { | |||
| // 消息签名不正确,说明不是公众平台发过来的消息 | |||
| response.getWriter().println("非法请求"); | |||
| @@ -84,31 +84,25 @@ public class WxMpDemoServlet extends HttpServlet { | |||
| "raw" : | |||
| request.getParameter("encrypt_type"); | |||
| WxMpXmlMessage inMessage = null; | |||
| if ("raw".equals(encryptType)) { | |||
| // 明文传输的消息 | |||
| inMessage = WxMpXmlMessage.fromXml(request.getInputStream()); | |||
| } else if ("aes".equals(encryptType)) { | |||
| // 是aes加密的消息 | |||
| String msgSignature = request.getParameter("msg_signature"); | |||
| inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature); | |||
| } else { | |||
| response.getWriter().println("不可识别的加密类型"); | |||
| WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream()); | |||
| WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); | |||
| response.getWriter().write(outMessage.toXml()); | |||
| return; | |||
| } | |||
| WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); | |||
| if (outMessage != null) { | |||
| if ("raw".equals(encryptType)) { | |||
| response.getWriter().write(outMessage.toXml()); | |||
| } else if ("aes".equals(encryptType)) { | |||
| response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage)); | |||
| } | |||
| if ("aes".equals(encryptType)) { | |||
| // 是aes加密的消息 | |||
| String msgSignature = request.getParameter("msg_signature"); | |||
| WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature); | |||
| WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage); | |||
| response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage)); | |||
| return; | |||
| } | |||
| response.getWriter().println("不可识别的加密类型"); | |||
| return; | |||
| } | |||
| } | |||