Browse Source

refactor

master
Daniel Qian 10 years ago
parent
commit
89aefa45d0
18 changed files with 201 additions and 107 deletions
  1. +0
    -5
      pom.xml
  2. +100
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/StringUtils.java
  3. +2
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java
  4. +2
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java
  5. +2
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java
  6. +13
    -4
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
  7. +21
    -26
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
  8. +3
    -8
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java
  9. +1
    -1
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
  10. +5
    -5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
  11. +7
    -9
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServlet.java
  12. +2
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
  13. +2
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
  14. +16
    -7
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
  15. +1
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
  16. +1
    -1
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java
  17. +5
    -5
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java
  18. +18
    -24
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java

+ 0
- 5
pom.xml View File

@@ -70,11 +70,6 @@
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.2.2</version> <version>2.2.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency> <dependency>
<groupId>commons-codec</groupId> <groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>


+ 100
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/StringUtils.java View File

@@ -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);
}

}

+ 2
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java View File

@@ -1,12 +1,9 @@
package me.chanjar.weixin.common.util.http; package me.chanjar.weixin.common.util.http;


import me.chanjar.weixin.common.bean.result.WxError; 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.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.Header;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ClientProtocolException;


+ 2
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java View File

@@ -16,8 +16,9 @@ public interface WxCpMessageHandler {
* *
* @param wxMessage * @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxCpService
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null * @return xml格式的消息,如果在异步规则里处理的话,可以返回null
*/ */
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context);
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService);
} }

+ 2
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java View File

@@ -15,8 +15,9 @@ public interface WxCpMessageInterceptor {
* 拦截微信消息 * 拦截微信消息
* @param wxMessage * @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxCpService
* @return true代表OK,false代表不OK * @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);
} }

+ 13
- 4
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java View File

@@ -45,12 +45,18 @@ public class WxCpMessageRouter {


private final ExecutorService es = Executors.newCachedThreadPool(); private final ExecutorService es = Executors.newCachedThreadPool();


private final WxCpService wxCpService;

public WxCpMessageRouter(WxCpService wxCpService) {
this.wxCpService = wxCpService;
}

/** /**
* 开始一个新的Route规则 * 开始一个新的Route规则
* @return * @return
*/ */
public Rule rule() { 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 WxCpMessageRouter routerBuilder;


private final WxCpService wxCpService;

private boolean async = true; private boolean async = true;


private String msgType; private String msgType;
@@ -121,8 +129,9 @@ public class WxCpMessageRouter {


private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>(); private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>();


protected Rule(WxCpMessageRouter routerBuilder) {
protected Rule(WxCpMessageRouter routerBuilder, WxCpService wxCpService) {
this.routerBuilder = routerBuilder; this.routerBuilder = routerBuilder;
this.wxCpService = wxCpService;
} }


/** /**
@@ -288,7 +297,7 @@ public class WxCpMessageRouter {
Map<String, Object> context = new HashMap<String, Object>(); Map<String, Object> context = new HashMap<String, Object>();
// 如果拦截器不通过 // 如果拦截器不通过
for (WxCpMessageInterceptor interceptor : this.interceptors) { for (WxCpMessageInterceptor interceptor : this.interceptors) {
if (!interceptor.intercept(wxMessage, context)) {
if (!interceptor.intercept(wxMessage, context, wxCpService)) {
return null; return null;
} }
} }
@@ -297,7 +306,7 @@ public class WxCpMessageRouter {
WxCpXmlOutMessage res = null; WxCpXmlOutMessage res = null;
for (WxCpMessageHandler handler : this.handlers) { for (WxCpMessageHandler handler : this.handlers) {
// 返回最后handler的结果 // 返回最后handler的结果
res = handler.handle(wxMessage, context);
res = handler.handle(wxMessage, context, wxCpService);
} }
return res; return res;
} }


+ 21
- 26
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java View File

@@ -1,25 +1,27 @@
package me.chanjar.weixin.cp.api; 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.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; 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.WxAccessToken;
import me.chanjar.weixin.common.bean.WxMenu; 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.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.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 me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; 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.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; 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 { public class WxCpServiceImpl implements WxCpService {




+ 3
- 8
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java View File

@@ -8,17 +8,12 @@
*/ */
package me.chanjar.weixin.cp.util.json; 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.api.WxConsts;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.cp.bean.WxCpMessage; 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
- 1
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java View File

@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.api; 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.Assert;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;


+ 5
- 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java View File

@@ -47,7 +47,7 @@ public class WxCpMessageRouterTest {
@Test(dataProvider="messages-1") @Test(dataProvider="messages-1")
public void testSync(WxCpXmlMessage message, String expected) { public void testSync(WxCpXmlMessage message, String expected) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter();
WxCpMessageRouter router = new WxCpMessageRouter(null);
prepare(false, sb, router); prepare(false, sb, router);
router.route(message); router.route(message);
Assert.assertEquals(sb.toString(), expected); Assert.assertEquals(sb.toString(), expected);
@@ -56,7 +56,7 @@ public class WxCpMessageRouterTest {
@Test(dataProvider="messages-1") @Test(dataProvider="messages-1")
public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException { public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter();
WxCpMessageRouter router = new WxCpMessageRouter(null);
prepare(true, sb, router); prepare(true, sb, router);
router.route(message); router.route(message);
Thread.sleep(500l); Thread.sleep(500l);
@@ -64,10 +64,10 @@ public class WxCpMessageRouterTest {
} }
public void testConcurrency() throws InterruptedException { public void testConcurrency() throws InterruptedException {
final WxCpMessageRouter router = new WxCpMessageRouter();
final WxCpMessageRouter router = new WxCpMessageRouter(null);
router.rule().handler(new WxCpMessageHandler() { router.rule().handler(new WxCpMessageHandler() {
@Override @Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context) {
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService) {
return null; return null;
} }
}).end(); }).end();
@@ -149,7 +149,7 @@ public class WxCpMessageRouterTest {
} }


@Override @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(','); sb.append(this.echoStr).append(',');
return null; return null;
} }


+ 7
- 9
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServlet.java View File

@@ -1,11 +1,11 @@
package me.chanjar.weixin.cp.demo; package me.chanjar.weixin.cp.demo;


import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.cp.api.*; import me.chanjar.weixin.cp.api.*;
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
import org.apache.commons.lang3.StringUtils;


import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
@@ -21,8 +21,8 @@ import java.util.Map;
*/ */
public class WxCpDemoServlet extends HttpServlet { public class WxCpDemoServlet extends HttpServlet {


protected WxCpService wxCpService;
protected WxCpConfigStorage wxCpConfigStorage; protected WxCpConfigStorage wxCpConfigStorage;
protected WxCpService wxCpService;
protected WxCpMessageRouter wxCpMessageRouter; protected WxCpMessageRouter wxCpMessageRouter;


@Override public void init() throws ServletException { @Override public void init() throws ServletException {
@@ -37,7 +37,7 @@ public class WxCpDemoServlet extends HttpServlet {
wxCpService.setWxCpConfigStorage(config); wxCpService.setWxCpConfigStorage(config);


WxCpMessageHandler handler = new WxCpMessageHandler() { 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 WxCpXmlOutTextMessage m = WxCpXmlOutMessage
.TEXT() .TEXT()
.content("测试加密消息") .content("测试加密消息")
@@ -48,7 +48,7 @@ public class WxCpDemoServlet extends HttpServlet {
} }
}; };


wxCpMessageRouter = new WxCpMessageRouter();
wxCpMessageRouter = new WxCpMessageRouter(wxCpService);
wxCpMessageRouter wxCpMessageRouter
.rule() .rule()
.async(false) .async(false)
@@ -64,13 +64,14 @@ public class WxCpDemoServlet extends HttpServlet {
@Override protected void service(HttpServletRequest request, HttpServletResponse response) @Override protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { throws ServletException, IOException {


response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);

String msgSignature = request.getParameter("msg_signature"); String msgSignature = request.getParameter("msg_signature");
String nonce = request.getParameter("nonce"); String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp"); String timestamp = request.getParameter("timestamp");
String echostr = request.getParameter("echostr"); String echostr = request.getParameter("echostr");


response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
if (StringUtils.isNotBlank(echostr)) { if (StringUtils.isNotBlank(echostr)) {
if (!wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) { if (!wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) {
// 消息签名不正确,说明不是公众平台发过来的消息 // 消息签名不正确,说明不是公众平台发过来的消息
@@ -84,11 +85,8 @@ public class WxCpDemoServlet extends HttpServlet {
return; return;
} }



WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature);

WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage);

if (outMessage != null) { if (outMessage != null) {
response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage));
} }


+ 2
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java View File

@@ -16,8 +16,9 @@ public interface WxMpMessageHandler {
* *
* @param wxMessage * @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxMpService
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null * @return xml格式的消息,如果在异步规则里处理的话,可以返回null
*/ */
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context);
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService);
} }

+ 2
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java View File

@@ -15,8 +15,9 @@ public interface WxMpMessageInterceptor {
* 拦截微信消息 * 拦截微信消息
* @param wxMessage * @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param wxMpService
* @return true代表OK,false代表不OK * @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);
} }

+ 16
- 7
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java View File

@@ -43,14 +43,20 @@ public class WxMpMessageRouter {
private final List<Rule> rules = new ArrayList<Rule>(); 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规则 * 开始一个新的Route规则
* @return * @return
*/ */
public Rule rule() { public Rule rule() {
return new Rule(this);
return new Rule(this, wxMpService);
} }


/** /**
@@ -73,7 +79,7 @@ public class WxMpMessageRouter {
if (matchRules.get(0).async) { if (matchRules.get(0).async) {
// 只要第一个是异步的,那就异步执行 // 只要第一个是异步的,那就异步执行
// 在另一个线程里执行 // 在另一个线程里执行
es.submit(new Runnable() {
executorService.submit(new Runnable() {
public void run() { public void run() {
for (final Rule rule : matchRules) { for (final Rule rule : matchRules) {
rule.service(wxMessage); rule.service(wxMessage);
@@ -101,6 +107,8 @@ public class WxMpMessageRouter {
private final WxMpMessageRouter routerBuilder; private final WxMpMessageRouter routerBuilder;


private final WxMpService wxMpService;

private boolean async = true; private boolean async = true;
private String msgType; private String msgType;
@@ -119,8 +127,9 @@ public class WxMpMessageRouter {
private List<WxMpMessageInterceptor> interceptors = new ArrayList<WxMpMessageInterceptor>(); private List<WxMpMessageInterceptor> interceptors = new ArrayList<WxMpMessageInterceptor>();
protected Rule(WxMpMessageRouter routerBuilder) {
protected Rule(WxMpMessageRouter routerBuilder, WxMpService wxMpService) {
this.routerBuilder = routerBuilder; this.routerBuilder = routerBuilder;
this.wxMpService = wxMpService;
} }
/** /**
@@ -274,7 +283,7 @@ public class WxMpMessageRouter {
Map<String, Object> context = new HashMap<String, Object>(); Map<String, Object> context = new HashMap<String, Object>();
// 如果拦截器不通过 // 如果拦截器不通过
for (WxMpMessageInterceptor interceptor : this.interceptors) { for (WxMpMessageInterceptor interceptor : this.interceptors) {
if (!interceptor.intercept(wxMessage, context)) {
if (!interceptor.intercept(wxMessage, context, wxMpService)) {
return null; return null;
} }
} }
@@ -283,7 +292,7 @@ public class WxMpMessageRouter {
WxMpXmlOutMessage res = null; WxMpXmlOutMessage res = null;
for (WxMpMessageHandler handler : this.handlers) { for (WxMpMessageHandler handler : this.handlers) {
// 返回最后handler的结果 // 返回最后handler的结果
res = handler.handle(wxMessage, context);
res = handler.handle(wxMessage, context, wxMpService);
} }
return res; return res;
} }


+ 1
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java View File

@@ -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.WxError;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException; 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.crypto.SHA1;
import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.*; 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.bean.result.*;
import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; 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.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; 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.BasicCredentialsProvider;
import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
@@ -38,7 +37,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;




+ 1
- 1
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java View File

@@ -1,6 +1,6 @@
package me.chanjar.weixin.mp.api; 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.Assert;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;


+ 5
- 5
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java View File

@@ -47,7 +47,7 @@ public class WxMpMessageRouterTest {
@Test(dataProvider="messages-1") @Test(dataProvider="messages-1")
public void testSync(WxMpXmlMessage message, String expected) { public void testSync(WxMpXmlMessage message, String expected) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
WxMpMessageRouter router = new WxMpMessageRouter();
WxMpMessageRouter router = new WxMpMessageRouter(null);
prepare(false, sb, router); prepare(false, sb, router);
router.route(message); router.route(message);
Assert.assertEquals(sb.toString(), expected); Assert.assertEquals(sb.toString(), expected);
@@ -56,7 +56,7 @@ public class WxMpMessageRouterTest {
@Test(dataProvider="messages-1") @Test(dataProvider="messages-1")
public void testAsync(WxMpXmlMessage message, String expected) throws InterruptedException { public void testAsync(WxMpXmlMessage message, String expected) throws InterruptedException {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
WxMpMessageRouter router = new WxMpMessageRouter();
WxMpMessageRouter router = new WxMpMessageRouter(null);
prepare(true, sb, router); prepare(true, sb, router);
router.route(message); router.route(message);
Thread.sleep(500l); Thread.sleep(500l);
@@ -64,10 +64,10 @@ public class WxMpMessageRouterTest {
} }
public void testConcurrency() throws InterruptedException { public void testConcurrency() throws InterruptedException {
final WxMpMessageRouter router = new WxMpMessageRouter();
final WxMpMessageRouter router = new WxMpMessageRouter(null);
router.rule().handler(new WxMpMessageHandler() { router.rule().handler(new WxMpMessageHandler() {
@Override @Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context) {
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService) {
return null; return null;
} }
}).end(); }).end();
@@ -149,7 +149,7 @@ public class WxMpMessageRouterTest {
} }


@Override @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(','); sb.append(this.echoStr).append(',');
return null; return null;
} }


+ 18
- 24
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java View File

@@ -1,10 +1,10 @@
package me.chanjar.weixin.mp.demo; package me.chanjar.weixin.mp.demo;


import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
import org.apache.commons.lang3.StringUtils;


import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
@@ -20,8 +20,8 @@ import java.util.Map;
*/ */
public class WxMpDemoServlet extends HttpServlet { public class WxMpDemoServlet extends HttpServlet {


protected WxMpService wxMpService;
protected WxMpConfigStorage wxMpConfigStorage; protected WxMpConfigStorage wxMpConfigStorage;
protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter; protected WxMpMessageRouter wxMpMessageRouter;


@Override public void init() throws ServletException { @Override public void init() throws ServletException {
@@ -36,7 +36,7 @@ public class WxMpDemoServlet extends HttpServlet {
wxMpService.setWxMpConfigStorage(config); wxMpService.setWxMpConfigStorage(config);


WxMpMessageHandler handler = new WxMpMessageHandler() { 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 WxMpXmlOutTextMessage m
= WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName()) = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName()).build(); .toUser(wxMessage.getFromUserName()).build();
@@ -44,7 +44,7 @@ public class WxMpDemoServlet extends HttpServlet {
} }
}; };


wxMpMessageRouter = new WxMpMessageRouter();
wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
wxMpMessageRouter wxMpMessageRouter
.rule() .rule()
.async(false) .async(false)
@@ -60,13 +60,13 @@ public class WxMpDemoServlet extends HttpServlet {
@Override protected void service(HttpServletRequest request, HttpServletResponse response) @Override protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { throws ServletException, IOException {


response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);

String signature = request.getParameter("signature"); String signature = request.getParameter("signature");
String nonce = request.getParameter("nonce"); String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp"); String timestamp = request.getParameter("timestamp");


response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);

if (!wxMpService.checkSignature(timestamp, nonce, signature)) { if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
// 消息签名不正确,说明不是公众平台发过来的消息 // 消息签名不正确,说明不是公众平台发过来的消息
response.getWriter().println("非法请求"); response.getWriter().println("非法请求");
@@ -84,31 +84,25 @@ public class WxMpDemoServlet extends HttpServlet {
"raw" : "raw" :
request.getParameter("encrypt_type"); request.getParameter("encrypt_type");


WxMpXmlMessage inMessage = null;

if ("raw".equals(encryptType)) { 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; 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; return;
} }


response.getWriter().println("不可识别的加密类型");
return;
} }


} }

Loading…
Cancel
Save