diff --git a/pom.xml b/pom.xml
index 90c63796..b4cec692 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
weixin4j-mp
weixin4j-qy
weixin4j-server
+ weixin4j-example
UTF-8
diff --git a/weixin4j-example/.gitignore b/weixin4j-example/.gitignore
new file mode 100644
index 00000000..87bd9366
--- /dev/null
+++ b/weixin4j-example/.gitignore
@@ -0,0 +1,32 @@
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+*~
+
+# eclipse ignore
+*.settings/*
+/.project
+/.classpath
+/.tomcatplugin
+
+# idea ignore
+/.idea
+*.iml
+
+# maven ignore
+target/*
+
+# other ignore
+*.log
+*.tmp
+Thumbs.db
+/target/
+.DS_Store
diff --git a/weixin4j-example/pom.xml b/weixin4j-example/pom.xml
new file mode 100644
index 00000000..aa159da8
--- /dev/null
+++ b/weixin4j-example/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ com.foxinmy
+ weixin4j
+ 1.6.8
+
+ weixin4j-example
+ 1.0
+ weixin4j-example
+ https://github.com/foxinmy/weixin4j/tree/master/weixin4j-example
+ weixin4j示例
+
+
+ com.foxinmy
+ weixin4j-mp
+ 1.6.8
+
+
+ com.foxinmy
+ weixin4j-qy
+ 1.6.8
+
+
+ com.foxinmy
+ weixin4j-server
+ 1.1.7
+
+
+ org.springframework
+ spring-context
+ 4.2.1.RELEASE
+ test
+
+
+
\ No newline at end of file
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithThread.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithThread.java
new file mode 100644
index 00000000..a51c9817
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithThread.java
@@ -0,0 +1,90 @@
+package com.foximy.weixin4j.example.server;
+
+import io.netty.util.internal.logging.InternalLoggerFactory;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.spring.SpringBeanFactory;
+import com.foxinmy.weixin4j.startup.WeixinServerBootstrap;
+import com.foxinmy.weixin4j.util.AesToken;
+
+/**
+ * 微信消息服务:需要另外开启一个线程去启动服务,比如在spring mvc中
+ *
+ * @className Weixin4jServerStartupWithThread
+ * @author jy
+ * @date 2015年5月7日
+ * @since JDK 1.7
+ * @see
+ */
+public class Weixin4jServerStartupWithThread implements ApplicationContextAware {
+ /**
+ * 服务监听的端口号,目前微信只支持80端口,可以考虑用nginx做转发到此端口
+ */
+ private final int port;
+ /**
+ * 服务器token信息
+ */
+ /**
+ * 明文模式:String aesToken = ""; 密文模式:AesToken aesToken = new
+ * AesToken("公众号appid", "公众号token","公众号加密/解密消息的密钥");
+ */
+ private final AesToken aesToken;
+ /**
+ * 处理微信消息的全限包名(也可通过addHandler方式一个一个添加)
+ */
+ private final String handlerPackage;
+ /**
+ * 用spring去获取bean
+ */
+ private ApplicationContext applicationContext;
+
+ private Weixin4jServerStartupWithThread(int port, AesToken aesToken,
+ String handlerPackage) {
+ this.port = port;
+ this.aesToken = aesToken;
+ this.handlerPackage = handlerPackage;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = applicationContext;
+ }
+
+ private ExecutorService executor;
+
+ /**
+ * 启动函数
+ *
+ * @throws WeixinException
+ */
+ public void start() {
+ executor = Executors.newCachedThreadPool();
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ new WeixinServerBootstrap(aesToken)
+ .handlerPackagesToScan(handlerPackage)
+ .resolveBeanFactory(
+ new SpringBeanFactory(applicationContext))
+ .openAlwaysResponse().startup(port);
+ } catch (WeixinException e) {
+ InternalLoggerFactory.getInstance(getClass()).error(
+ "weixin4j server startup:FAIL", e);
+ }
+ }
+ });
+ }
+
+ public void stop() {
+ executor.shutdown();
+ }
+}
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithoutThread.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithoutThread.java
new file mode 100644
index 00000000..c46c873e
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/Weixin4jServerStartupWithoutThread.java
@@ -0,0 +1,52 @@
+package com.foximy.weixin4j.example.server;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.spring.SpringBeanFactory;
+import com.foxinmy.weixin4j.startup.WeixinServerBootstrap;
+
+/**
+ * 微信消息服务:单独作为一个服务jar包启动
+ *
+ * @className Weixin4jServerStartupWithoutThread
+ * @author jy
+ * @date 2015年5月7日
+ * @since JDK 1.7
+ * @see
+ */
+public class Weixin4jServerStartupWithoutThread {
+ /**
+ * 服务监听的端口号,目前微信只支持80端口,可以考虑用nginx做转发到此端口
+ */
+ private static int port = 10000;
+ /**
+ * 服务器token信息
+ */
+ /**
+ * 明文模式:String aesToken = ""; 密文模式:AesToken aesToken = new
+ * AesToken("公众号appid", "公众号token","公众号加密/解密消息的密钥");
+ */
+ private static String aesToken = "weixin4j";
+ /**
+ * 处理微信消息的全限包名(也可通过addHandler方式一个一个添加)
+ */
+ private static String handlerPackage = "com.foximy.weixin4j.example.server.handler";
+
+ /**
+ * 入口函数 可使用assembly插件打成可执行zip包:https://github.com/foxinmy/weixin4j/wiki/
+ * assembly%E6%89%93%E5%8C%85
+ *
+ * @param args
+ * @throws WeixinException
+ */
+ public static void main(String[] args) throws WeixinException {
+ ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
+ new String[] { "classpath:/spring-bean.xml" });
+ new WeixinServerBootstrap(aesToken)
+ .handlerPackagesToScan(handlerPackage).openAlwaysResponse()
+ .resolveBeanFactory(new SpringBeanFactory(applicationContext))
+ .startup(port);
+ }
+}
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/HelloMessageHandler.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/HelloMessageHandler.java
new file mode 100644
index 00000000..9a753f67
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/HelloMessageHandler.java
@@ -0,0 +1,42 @@
+package com.foximy.weixin4j.example.server.handler;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
+import com.foxinmy.weixin4j.message.TextMessage;
+import com.foxinmy.weixin4j.request.WeixinRequest;
+import com.foxinmy.weixin4j.response.TextResponse;
+import com.foxinmy.weixin4j.response.WeixinResponse;
+
+/**
+ * 输入 hello 回复 world
+ *
+ * @className HelloMessageHandler
+ * @author jy
+ * @date 2015年12月27日
+ * @since JDK 1.7
+ * @see
+ */
+public class HelloMessageHandler extends MessageHandlerAdapter {
+ @Override
+ public boolean canHandle0(WeixinRequest request, TextMessage message)
+ throws WeixinException {
+ return message.getContent().equalsIgnoreCase("hello");
+ }
+
+ @Override
+ public WeixinResponse doHandle0(WeixinRequest request, TextMessage message)
+ throws WeixinException {
+ /**
+ * 返回用户「world」文本
+ */
+ return new TextResponse("world");
+ }
+
+ /**
+ * 提高权重 > TextMessageHandler
+ */
+ @Override
+ public int weight() {
+ return 2;
+ }
+}
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/SubscribeMessageHandler.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/SubscribeMessageHandler.java
new file mode 100644
index 00000000..e1e5e501
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/SubscribeMessageHandler.java
@@ -0,0 +1,27 @@
+package com.foximy.weixin4j.example.server.handler;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
+import com.foxinmy.weixin4j.mp.event.ScribeEventMessage;
+import com.foxinmy.weixin4j.request.WeixinRequest;
+import com.foxinmy.weixin4j.response.TextResponse;
+import com.foxinmy.weixin4j.response.WeixinResponse;
+
+/**
+ * 处理关注消息
+ *
+ * @className SubscribeMessageHandler
+ * @author jy
+ * @date 2015年12月3日
+ * @since JDK 1.7
+ * @see
+ */
+public class SubscribeMessageHandler extends
+ MessageHandlerAdapter {
+
+ @Override
+ public WeixinResponse doHandle0(WeixinRequest arg0, ScribeEventMessage arg1)
+ throws WeixinException {
+ return new TextResponse("欢迎关注~");
+ }
+}
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/TextMessageHandler.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/TextMessageHandler.java
new file mode 100644
index 00000000..c2479610
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/TextMessageHandler.java
@@ -0,0 +1,26 @@
+package com.foximy.weixin4j.example.server.handler;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
+import com.foxinmy.weixin4j.message.TextMessage;
+import com.foxinmy.weixin4j.request.WeixinRequest;
+import com.foxinmy.weixin4j.response.TextResponse;
+import com.foxinmy.weixin4j.response.WeixinResponse;
+
+/**
+ * 文本消息处理
+ *
+ * @className TextMessageHandler
+ * @author jy
+ * @date 2015年11月18日
+ * @since JDK 1.7
+ * @see
+ */
+public class TextMessageHandler extends MessageHandlerAdapter {
+
+ @Override
+ public WeixinResponse doHandle0(WeixinRequest request, TextMessage message)
+ throws WeixinException {
+ return new TextResponse("收到了文本消息");
+ }
+}
diff --git a/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/VoiceMessageHandler.java b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/VoiceMessageHandler.java
new file mode 100644
index 00000000..b6888a04
--- /dev/null
+++ b/weixin4j-example/src/main/java/com/foximy/weixin4j/example/server/handler/VoiceMessageHandler.java
@@ -0,0 +1,29 @@
+package com.foximy.weixin4j.example.server.handler;
+
+import com.foxinmy.weixin4j.exception.WeixinException;
+import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
+import com.foxinmy.weixin4j.message.VoiceMessage;
+import com.foxinmy.weixin4j.request.WeixinRequest;
+import com.foxinmy.weixin4j.response.TextResponse;
+import com.foxinmy.weixin4j.response.WeixinResponse;
+
+/**
+ * 只处理语音消息
+ *
+ * @className VoiceMessageHandler
+ * @author jy
+ * @date 2015年11月18日
+ * @since JDK 1.7
+ * @see
+ */
+public class VoiceMessageHandler extends MessageHandlerAdapter {
+
+ @Override
+ public WeixinResponse doHandle0(WeixinRequest request, VoiceMessage message)
+ throws WeixinException {
+ /**
+ * 返回一段文字给用户
+ */
+ return new TextResponse("你讲了一句话");
+ }
+}
diff --git a/weixin4j-example/src/main/resources/spring-bean.xml b/weixin4j-example/src/main/resources/spring-bean.xml
new file mode 100644
index 00000000..9a0a5f98
--- /dev/null
+++ b/weixin4j-example/src/main/resources/spring-bean.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/weixin4j-example/src/main/resources/weixin4j.properties b/weixin4j-example/src/main/resources/weixin4j.properties
new file mode 100644
index 00000000..bdc62530
--- /dev/null
+++ b/weixin4j-example/src/main/resources/weixin4j.properties
@@ -0,0 +1,18 @@
+# \u516c\u4f17\u53f7\u4fe1\u606f \u8bf7\u6309\u9700\u586b\u5199
+weixin4j.account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\
+"mchId":"\u5fae\u4fe1\u5546\u6237\u53f7 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\
+"certificateKey":"\u52a0\u8f7d\u652f\u4ed8\u8bc1\u4e66\u6587\u4ef6\u7684\u5bc6\u7801 \u5982\u679c\u4e0d\u586b\u5199\u5219\u9ed8\u8ba4\u83b7\u53d6mchId\u4f5c\u4e3a\u5bc6\u7801",\
+"paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u5fae\u4fe1\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"}
+
+# weixin4j\u7684\u4e34\u65f6\u76ee\u5f55
+# \u53ef\u80fd\u5b58\u653etoken\u6587\u4ef6\u3001\u4e8c\u7ef4\u7801\u6587\u4ef6\u3001\u5a92\u4f53\u6587\u4ef6\u3001\u5bf9\u8d26\u5355\u6587\u4ef6\u7b49
+# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6java.io.tmpdir\u4e34\u65f6\u76ee\u5f55
+weixin4j.tmpdir=
+# \u5fae\u4fe1\u652f\u4ed8\u67d0\u4e9b\u63a5\u53e3\u9700\u8981\u7684ca\u8bc1\u4e66\u5b58\u653e\u7684\u5b8c\u6574\u8def\u5f84
+# classpath\u8def\u5f84\u4e0b\u53ef\u4ee5\u8fd9\u4e48\u5199
+# weixin4j.certificate.file=classpath:xxxxx.p12
+# \u4e3a\u7a7a\u65f6\u5219\u83b7\u53d6classpath\u6839\u76ee\u5f55\u4e0b\u7684ca.p12\u6587\u4ef6
+weixin4j.certificate.file=/tmp/weixin4j/xxxxx.p12
+
+# \u7528\u6237oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url(\u5728\u4f7f\u7528OauthApi\u65f6\u586b\u5199)
+weixin4j.user.oauth.redirect.uri=
\ No newline at end of file
diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java
index be6f0c0b..de8056c1 100644
--- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java
+++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java
@@ -72,7 +72,7 @@ public class WeixinMessageDecoder extends
&& encryptType == EncryptType.AES) {
if (ServerToolkits.isBlank(aesToken.getAesKey())) {
throw new WeixinException(
- "AESEncodingKey not be null in AES mode");
+ "EncodingAESKey not be empty in safety(AES) mode");
}
EncryptMessageHandler encryptHandler = EncryptMessageHandler
.parser(messageContent);
diff --git a/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java b/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java
index 1bd5ec25..f0f65197 100644
--- a/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java
+++ b/weixin4j-server/src/test/java/com/foxinmy/weixin4j/server/test/MessageServerStartup.java
@@ -2,8 +2,11 @@ package com.foxinmy.weixin4j.server.test;
import java.util.Set;
+import org.springframework.context.ApplicationContext;
+
import io.netty.channel.ChannelHandlerContext;
+import com.foxinmy.weixin4j.dispatcher.BeanFactory;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.handler.DebugMessageHandler;
import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
@@ -11,11 +14,13 @@ import com.foxinmy.weixin4j.handler.MultipleMessageHandlerAdapter;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.message.TextMessage;
+import com.foxinmy.weixin4j.message.VoiceMessage;
import com.foxinmy.weixin4j.mp.event.ScanEventMessage;
import com.foxinmy.weixin4j.request.WeixinMessage;
import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse;
+import com.foxinmy.weixin4j.spring.SpringBeanFactory;
import com.foxinmy.weixin4j.startup.WeixinServerBootstrap;
/**
@@ -37,53 +42,88 @@ public class MessageServerStartup {
final String aesKey = "";
/**
- * 明文模式
+ * 调试输出用户发来的消息
*
* @throws WeixinException
*/
public void test1() throws WeixinException {
- // 所有请求都回复调试的文本消息
+ // 明文模式
new WeixinServerBootstrap(token).addHandler(DebugMessageHandler.global)
.startup();
- }
-
- /**
- * 密文模式
- *
- * @throws WeixinException
- */
- public void test2() throws WeixinException {
- // 所有请求都回复调试的文本消息
+ // 密文模式
new WeixinServerBootstrap(weixinId, token, aesKey).addHandler(
DebugMessageHandler.global).startup();
}
/**
- * 针对特定消息回复
+ * 针对特定消息类型
*
* @throws WeixinException
*/
- public void test3() throws WeixinException {
+ public void test2() throws WeixinException {
// 针对文本消息回复
- WeixinMessageHandler messageHandler = new MessageHandlerAdapter() {
+ WeixinMessageHandler textMessageHandler = new MessageHandlerAdapter() {
@Override
public WeixinResponse doHandle0(WeixinRequest request,
TextMessage message) throws WeixinException {
return new TextResponse("HelloWorld!");
}
};
- // 当消息类型为文本(text)时回复「HelloWorld」, 否则回复调试消息
+ // 针对语音消息回复
+ WeixinMessageHandler voiceMessageHandler = new MessageHandlerAdapter() {
+ @Override
+ public WeixinResponse doHandle0(WeixinRequest request,
+ VoiceMessage message) throws WeixinException {
+ return new TextResponse("HelloWorld!");
+ }
+ };
+ // 当消息类型为文本(text)或者语音时回复「HelloWorld」, 否则回复调试消息
new WeixinServerBootstrap(weixinId, token, aesKey).addHandler(
- messageHandler, DebugMessageHandler.global).startup();
+ textMessageHandler, voiceMessageHandler,
+ DebugMessageHandler.global).startup();
}
+ /**
+ * 多种消息类型处理
+ *
+ * @throws WeixinException
+ */
+ public void test3() throws WeixinException {
+ @SuppressWarnings("unchecked")
+ MultipleMessageHandlerAdapter messageHandler = new MultipleMessageHandlerAdapter(
+ ScanEventMessage.class, TextMessage.class) {
+ @Override
+ public WeixinResponse doHandle(WeixinRequest request,
+ WeixinMessage message, Set nodeNames)
+ throws WeixinException {
+ return new TextResponse("处理了扫描和文字消息");
+ }
+ };
+ new WeixinServerBootstrap(token).addHandler(messageHandler,
+ DebugMessageHandler.global).startup();
+ }
+
+ /**
+ * 扫描包添加handler
+ *
+ * @throws WeixinException
+ */
public void test4() throws WeixinException {
- // 扫描包加载消息处理器
+ // handler处理所在的包名(子包也会扫描)
String packageToScan = "com.foxinmy.weixin4j.handler";
+ // handler默认使用 Class.newInstance
+ // 方式实例化,如果handler中含有service等类需要注入,可以声明一个BeanFactory,如SpringBeanFactory
+ ApplicationContext applicationContext = null; // spring容器
+ BeanFactory beanFactory = new SpringBeanFactory(applicationContext);
new WeixinServerBootstrap(token).handlerPackagesToScan(packageToScan)
- .startup();
+ .openAlwaysResponse().resolveBeanFactory(beanFactory).startup();
}
+ /**
+ * 拦截器应用
+ *
+ * @throws WeixinException
+ */
public void test5() throws WeixinException {
// 拦截所有请求
WeixinMessageInterceptor interceptor = new WeixinMessageInterceptor() {
@@ -120,21 +160,12 @@ public class MessageServerStartup {
.openAlwaysResponse().startup();
}
- @SuppressWarnings("unchecked")
- public void test6() throws WeixinException {
- MultipleMessageHandlerAdapter messageHandler = new MultipleMessageHandlerAdapter(
- ScanEventMessage.class, TextMessage.class) {
- @Override
- public WeixinResponse doHandle(WeixinRequest request,
- WeixinMessage message, Set nodeNames)
- throws WeixinException {
- return new TextResponse("处理了扫描和文字消息");
- }
- };
- new WeixinServerBootstrap(token).addHandler(messageHandler,
- DebugMessageHandler.global).startup();
- }
-
+ /**
+ * main方法入口
+ *
+ * @param args
+ * @throws Exception
+ */
public static void main(String[] args) throws Exception {
new MessageServerStartup().test1();
}