commons-codec
commons-codec
diff --git a/pom.xml.versionsBackup b/pom.xml.versionsBackup
new file mode 100644
index 00000000..3e038387
--- /dev/null
+++ b/pom.xml.versionsBackup
@@ -0,0 +1,229 @@
+
+
+ 4.0.0
+ me.chanjar
+ weixin-java-parent
+ 1.0.5-SNAPSHOT
+ pom
+ WeiXin Java Tools - Parent
+ 微信公众号、企业号上级POM
+ https://github.com/chanjarster/weixin-java-tools
+
+
+
+ The Apache License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+
+
+
+
+
+ Daniel Qian
+ chanjarster@gmail.com
+
+
+
+
+ scm:git:https://github.com/chanjarster/weixin-java-tools.git
+ scm:git:git@github.com:chanjarster/weixin-java-tools.git
+ https://github.com/chanjarster/weixin-java-tools
+
+
+
+ weixin-java-common
+ weixin-java-cp
+ weixin-java-mp
+
+
+
+ UTF-8
+ true
+ true
+ 4.3.5
+
+
+
+
+ org.apache.httpcomponents
+ fluent-hc
+ ${httpclient.version}
+
+
+ org.apache.httpcomponents
+ httpmime
+ ${httpclient.version}
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.2.7
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ 2.2.7
+
+
+ com.google.code.gson
+ gson
+ 2.2.2
+
+
+ commons-codec
+ commons-codec
+ 1.9
+
+
+ commons-io
+ commons-io
+ 2.4
+
+
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ com.google.inject
+ guice
+ 3.0
+ test
+
+
+ org.testng
+ testng
+ 6.8.7
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ 9.3.0.M0
+ test
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 9.3.0.M0
+ test
+
+
+
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9.1
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+ UTF-8
+ zh_CN
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.5
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.17
+
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.3
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 2.5
+
+ true
+ false
+ release
+ deploy
+
+
+
+
+
+
+
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 1d9c3ebc..a1365add 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
me.chanjar
weixin-java-parent
- 1.0.4
+ 1.0.5
weixin-java-common
diff --git a/weixin-java-common/pom.xml.versionsBackup b/weixin-java-common/pom.xml.versionsBackup
new file mode 100644
index 00000000..47e4ec22
--- /dev/null
+++ b/weixin-java-common/pom.xml.versionsBackup
@@ -0,0 +1,68 @@
+
+
+ 4.0.0
+
+ me.chanjar
+ weixin-java-parent
+ 1.0.5-SNAPSHOT
+
+
+ weixin-java-common
+ WeiXin Java Tools - Common
+ 微信公众号、企业号Java SDK Common
+
+
+
+ junit
+ junit
+ test
+
+
+ org.testng
+ testng
+ 6.8.7
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+
+
+ com.google.inject
+ guice
+ 3.0
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ 9.3.0.M0
+ test
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 9.3.0.M0
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/testng.xml
+
+
+
+
+
+
+
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
index 8a843e94..18260295 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
@@ -128,4 +128,12 @@ public class WxConsts {
/** 弹出地理位置选择器 */
public static final String LOCATION_SELECT = "location_select";
+ ///////////////////////
+ // oauth2网页授权的scope
+ ///////////////////////
+ /** 不弹出授权页面,直接跳转,只能获取用户openid */
+ public static final String OAUTH2_SCOPE_BASE = "snsapi_base";
+ /** 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 */
+ public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo";
+
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/StringUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/StringUtils.java
new file mode 100644
index 00000000..4234a8c8
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/StringUtils.java
@@ -0,0 +1,100 @@
+package me.chanjar.weixin.common.util;
+
+/**
+ * copy from apache-commons-lang3
+ */
+public class StringUtils {
+
+ /**
+ * Checks if a CharSequence is whitespace, empty ("") or null.
+ *
+ *
+ * StringUtils.isBlank(null) = true
+ * StringUtils.isBlank("") = true
+ * StringUtils.isBlank(" ") = true
+ * StringUtils.isBlank("bob") = false
+ * StringUtils.isBlank(" bob ") = false
+ *
+ *
+ * @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;
+ }
+
+ /**
+ * Checks if a CharSequence is not empty (""), not null and not whitespace only.
+ *
+ *
+ * StringUtils.isNotBlank(null) = false
+ * StringUtils.isNotBlank("") = false
+ * StringUtils.isNotBlank(" ") = false
+ * StringUtils.isNotBlank("bob") = true
+ * StringUtils.isNotBlank(" bob ") = true
+ *
+ *
+ * @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);
+ }
+
+ /**
+ * Checks if a CharSequence is empty ("") or null.
+ *
+ *
+ * StringUtils.isEmpty(null) = true
+ * StringUtils.isEmpty("") = true
+ * StringUtils.isEmpty(" ") = false
+ * StringUtils.isEmpty("bob") = false
+ * StringUtils.isEmpty(" bob ") = false
+ *
+ *
+ * NOTE: This method changed in Lang version 2.0.
+ * It no longer trims the CharSequence.
+ * That functionality is available in isBlank().
+ *
+ * @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;
+ }
+
+ /**
+ * Checks if a CharSequence is not empty ("") and not null.
+ *
+ *
+ * StringUtils.isNotEmpty(null) = false
+ * StringUtils.isNotEmpty("") = false
+ * StringUtils.isNotEmpty(" ") = true
+ * StringUtils.isNotEmpty("bob") = true
+ * StringUtils.isNotEmpty(" bob ") = true
+ *
+ *
+ * @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);
+ }
+
+}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java
index 7fc05d94..dc7f28b4 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java
@@ -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;
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java
new file mode 100644
index 00000000..bb671eb1
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.common.util.http;
+
+import me.chanjar.weixin.common.util.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+
+public class URIUtil {
+
+ private static final String ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()";
+
+ public static String encodeURIComponent(String input) {
+ if (StringUtils.isEmpty(input)) {
+ return input;
+ }
+
+ int l = input.length();
+ StringBuilder o = new StringBuilder(l * 3);
+ try {
+ for (int i = 0; i < l; i++) {
+ String e = input.substring(i, i + 1);
+ if (ALLOWED_CHARS.indexOf(e) == -1) {
+ byte[] b = e.getBytes("utf-8");
+ o.append(getHex(b));
+ continue;
+ }
+ o.append(e);
+ }
+ return o.toString();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return input;
+ }
+
+ private static String getHex(byte buf[]) {
+ StringBuilder o = new StringBuilder(buf.length * 3);
+ for (int i = 0; i < buf.length; i++) {
+ int n = (int) buf[i] & 0xff;
+ o.append("%");
+ if (n < 0x10) {
+ o.append("0");
+ }
+ o.append(Long.toString(n, 16).toUpperCase());
+ }
+ return o.toString();
+ }
+}
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 7f96ee7a..e0f1d49a 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -6,7 +6,7 @@
me.chanjar
weixin-java-parent
- 1.0.4
+ 1.0.5
weixin-java-cp
diff --git a/weixin-java-cp/pom.xml.versionsBackup b/weixin-java-cp/pom.xml.versionsBackup
new file mode 100644
index 00000000..fe491f91
--- /dev/null
+++ b/weixin-java-cp/pom.xml.versionsBackup
@@ -0,0 +1,73 @@
+
+
+ 4.0.0
+
+ me.chanjar
+ weixin-java-parent
+ 1.0.5-SNAPSHOT
+
+
+ weixin-java-cp
+ WeiXin Java Tools - CP
+ 微信企业号Java SDK
+
+
+
+ me.chanjar
+ weixin-java-common
+ ${project.version}
+
+
+ junit
+ junit
+ test
+
+
+ org.testng
+ testng
+ 6.8.7
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+
+
+ com.google.inject
+ guice
+ 3.0
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ 9.3.0.M0
+ test
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 9.3.0.M0
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/testng.xml
+
+
+
+
+
+
+
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
index 7837a6f4..36c9cfba 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
@@ -27,6 +27,8 @@ public interface WxCpConfigStorage {
public int getExpiresIn();
+ public String getOauth2redirectUri();
+
public String getHttp_proxy_host();
public int getHttp_proxy_port();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
index 49e5f392..9ff1f187 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
@@ -18,6 +18,8 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
protected String agentId;
protected int expiresIn;
+ protected String oauth2redirectUri;
+
protected String http_proxy_host;
protected int http_proxy_port;
protected String http_proxy_username;
@@ -88,6 +90,15 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.agentId = agentId;
}
+ @Override
+ public String getOauth2redirectUri() {
+ return this.oauth2redirectUri;
+ }
+
+ public void setOauth2redirectUri(String oauth2redirectUri) {
+ this.oauth2redirectUri = oauth2redirectUri;
+ }
+
public String getHttp_proxy_host() {
return http_proxy_host;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java
index b82dddeb..861c610d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java
@@ -16,8 +16,9 @@ public interface WxCpMessageHandler {
*
* @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
+ * @param wxCpService
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null
*/
- public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context);
+ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java
index 7a09dacd..c1e7ee9d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java
@@ -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 context);
+ public boolean intercept(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
index 333fca9a..5d5828e5 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
@@ -41,16 +41,30 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
*/
public class WxCpMessageRouter {
+ private static final int DEFAULT_THREAD_POOL_SIZE = 20;
+
private final List rules = new ArrayList();
- private final ExecutorService es = Executors.newCachedThreadPool();
+ private final ExecutorService executorService;
+
+ private final WxCpService wxCpService;
+
+ public WxCpMessageRouter(WxCpService wxCpService) {
+ this.wxCpService = wxCpService;
+ this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
+ }
+
+ public WxCpMessageRouter(WxCpService wxMpService, int threadPoolSize) {
+ this.wxCpService = wxMpService;
+ this.executorService = Executors.newFixedThreadPool(threadPoolSize);
+ }
/**
* 开始一个新的Route规则
* @return
*/
public Rule rule() {
- return new Rule(this);
+ return new Rule(this, wxCpService);
}
/**
@@ -73,7 +87,7 @@ public class WxCpMessageRouter {
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,8 +115,12 @@ public class WxCpMessageRouter {
private final WxCpMessageRouter routerBuilder;
+ private final WxCpService wxCpService;
+
private boolean async = true;
+ private String fromUser;
+
private String msgType;
private String event;
@@ -121,8 +139,9 @@ public class WxCpMessageRouter {
private List interceptors = new ArrayList();
- protected Rule(WxCpMessageRouter routerBuilder) {
+ protected Rule(WxCpMessageRouter routerBuilder, WxCpService wxCpService) {
this.routerBuilder = routerBuilder;
+ this.wxCpService = wxCpService;
}
/**
@@ -195,6 +214,16 @@ public class WxCpMessageRouter {
return this;
}
+ /**
+ * 如果fromUser等于某值
+ * @param fromUser
+ * @return
+ */
+ public Rule fromUser(String fromUser) {
+ this.fromUser = fromUser;
+ return this;
+ }
+
/**
* 设置微信消息拦截器
* @param interceptor
@@ -265,6 +294,8 @@ public class WxCpMessageRouter {
protected boolean test(WxCpXmlMessage wxMessage) {
return
+ (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName()))
+ &&
(this.agentId == null || this.agentId.equals(wxMessage.getAgentId()))
&&
(this.msgType == null || this.msgType.equals(wxMessage.getMsgType()))
@@ -288,7 +319,7 @@ public class WxCpMessageRouter {
Map context = new HashMap();
// 如果拦截器不通过
for (WxCpMessageInterceptor interceptor : this.interceptors) {
- if (!interceptor.intercept(wxMessage, context)) {
+ if (!interceptor.intercept(wxMessage, context, wxCpService)) {
return null;
}
}
@@ -297,7 +328,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;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index 1355f17a..cc520f90 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -274,6 +274,27 @@ public interface WxCpService {
*/
public void tagAddUsers(String tagId, List userIds) throws WxErrorException;
+ /**
+ *
+ * 构造oauth2授权的url连接
+ * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code
+ *
+ * @param state
+ * @return code
+ */
+ public String oauth2buildAuthorizationUrl(String state);
+
+ /**
+ *
+ * 用oauth2获取用户信息
+ * http://qydev.weixin.qq.com/wiki/index.php?title=根据code获取成员信息
+ * 因为企业号oauth2.0必须在应用设置里设置通过ICP备案的可信域名,所以无法测试,因此这个方法很可能是坏的。
+ *
+ * @param code
+ * @return [userid, deviceid]
+ */
+ public String[] oauth2getUserInfo(String code) throws WxErrorException;
+
/**
* 移除标签成员
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
index 39b8e3db..c83d4b55 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
@@ -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 {
@@ -321,6 +316,41 @@ public class WxCpServiceImpl implements WxCpService {
execute(new SimplePostRequestExecutor(), url, jsonObject.toString());
}
+ @Override
+ public String oauth2buildAuthorizationUrl(String state) {
+ String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ;
+ url += "appid=" + wxCpConfigStorage.getCorpId();
+ url += "&redirect_uri=" + URIUtil.encodeURIComponent(wxCpConfigStorage.getOauth2redirectUri());
+ url += "&response_type=code";
+ url += "&scope=snsapi_base";
+ if (state != null) {
+ url += "&state=" + state;
+ }
+ url += "#wechat_redirect";
+ return url;
+ }
+
+ @Override
+ public String[] oauth2getUserInfo(String code) throws WxErrorException {
+ String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?";
+ url += "access_token=" + wxCpConfigStorage.getAccessToken();
+ url += "&code=" + code;
+ url += "agendid=" + wxCpConfigStorage.getAgentId();
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(getHttpclient(), httpProxy, url, null);
+ JsonElement je = Streams.parse(new JsonReader(new StringReader(responseText)));
+ JsonObject jo = je.getAsJsonObject();
+ return new String[] {GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")};
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
public String get(String url, String queryParam) throws WxErrorException {
return execute(new SimpleGetRequestExecutor(), url, queryParam);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMewsMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
similarity index 95%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMewsMessage.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
index 63c01fbf..76f28e2e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMewsMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
@@ -10,7 +10,7 @@ import java.util.List;
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
-public class WxCpXmlOutMewsMessage extends WxCpXmlOutMessage {
+public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
@XmlElement(name = "ArticleCount")
protected int articleCount;
@@ -19,7 +19,7 @@ public class WxCpXmlOutMewsMessage extends WxCpXmlOutMessage {
@XmlElement(name = "item")
protected final List- articles = new ArrayList
- ();
- public WxCpXmlOutMewsMessage() {
+ public WxCpXmlOutNewsMessage() {
this.msgType = WxConsts.XML_MSG_NEWS;
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
index 1785f714..5f0fa614 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
@@ -3,14 +3,14 @@ package me.chanjar.weixin.cp.bean.outxmlbuilder;
import java.util.ArrayList;
import java.util.List;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMewsMessage.Item;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
/**
* 图文消息builder
* @author Daniel Qian
*/
-public final class NewsBuilder extends BaseBuilder {
+public final class NewsBuilder extends BaseBuilder {
protected final List
- articles = new ArrayList
- ();
@@ -19,8 +19,8 @@ public final class NewsBuilder extends BaseBuilder {
messageJson.addProperty("msgtype", message.getMsgType());
if (StringUtils.isNotBlank(message.getToParty())) {
- messageJson.addProperty("toparty", message.getToUser());
+ messageJson.addProperty("toparty", message.getToParty());
}
if (StringUtils.isNotBlank(message.getToTag())) {
messageJson.addProperty("totag", message.getToUser());
@@ -75,6 +70,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer {
}
if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) {
+ JsonObject newsJsonObject = new JsonObject();
JsonArray articleJsonArray = new JsonArray();
for (WxCpMessage.WxArticle article : message.getArticles()) {
JsonObject articleJson = new JsonObject();
@@ -84,7 +80,8 @@ public class WxCpMessageGsonAdapter implements JsonSerializer {
articleJson.addProperty("picurl", article.getPicUrl());
articleJsonArray.add(articleJson);
}
- messageJson.add("articles", articleJsonArray);
+ newsJsonObject.add("articles", articleJsonArray);
+ messageJson.add("news", newsJsonObject);
}
return messageJson;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java
index 39914f44..21bb7a77 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java
@@ -59,6 +59,7 @@ public class XmlTransformer {
Marshaller m = JAXB_CONTEXT.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.setProperty(CharacterEscapeHandler.class.getName(), CHAR_ESCAPE_HANDLER);
+ m.setProperty(Marshaller.JAXB_FRAGMENT, true);
m.marshal(object, writer);
}
@@ -79,7 +80,7 @@ public class XmlTransformer {
return JAXBContext.newInstance(
WxCpXmlOutMessage.class,
WxCpXmlOutImageMessage.class,
- WxCpXmlOutMewsMessage.class,
+ WxCpXmlOutNewsMessage.class,
WxCpXmlOutTextMessage.class,
WxCpXmlOutVideoMessage.class,
WxCpXmlOutVoiceMessage.class,
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
index 07d7d0a6..032165eb 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
@@ -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;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
index 59962c6f..6b178f9b 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
@@ -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 context) {
+ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService) {
return null;
}
}).end();
@@ -149,7 +149,7 @@ public class WxCpMessageRouterTest {
}
@Override
- public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context) {
+ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService) {
sb.append(this.echoStr).append(',');
return null;
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
index c5b9e5b9..72169d2b 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
@@ -83,8 +83,8 @@ public class WxCpMessageTest {
article2.setTitle("Happy Day");
reply.getArticles().add(article2);
-
- Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}");
+
+ Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}");
}
public void testNewsBuild() {
@@ -101,8 +101,8 @@ public class WxCpMessageTest {
article2.setTitle("Happy Day");
WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build();
-
- Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}");
+
+ Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}");
}
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java
index 9f97e4b8..aef4ec45 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java
@@ -13,8 +13,7 @@ public class WxCpXmlOutImageMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxCpXmlOutImageMessageTest {
public void testBuild() {
WxCpXmlOutImageMessage m = WxCpXmlOutMessage.IMAGE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java
index f72c76b3..7848bfcd 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java
@@ -7,20 +7,19 @@ import org.testng.annotations.Test;
public class WxCpXmlOutNewsMessageTest {
public void test() {
- WxCpXmlOutMewsMessage m = new WxCpXmlOutMewsMessage();
+ WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage();
m.setCreateTime(1122l);
m.setFromUserName("fromUser");
m.setToUserName("toUser");
- WxCpXmlOutMewsMessage.Item item = new WxCpXmlOutMewsMessage.Item();
+ WxCpXmlOutNewsMessage.Item item = new WxCpXmlOutNewsMessage.Item();
item.setDescription("description");
item.setPicUrl("picUrl");
item.setTitle("title");
item.setUrl("url");
m.addArticle(item);
m.addArticle(item);
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -46,20 +45,19 @@ public class WxCpXmlOutNewsMessageTest {
}
public void testBuild() {
- WxCpXmlOutMewsMessage.Item item = new WxCpXmlOutMewsMessage.Item();
+ WxCpXmlOutNewsMessage.Item item = new WxCpXmlOutNewsMessage.Item();
item.setDescription("description");
item.setPicUrl("picUrl");
item.setTitle("title");
item.setUrl("url");
- WxCpXmlOutMewsMessage m = WxCpXmlOutMessage.NEWS()
+ WxCpXmlOutNewsMessage m = WxCpXmlOutMessage.NEWS()
.fromUser("fromUser")
.toUser("toUser")
.addArticle(item)
.addArticle(item)
.build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java
index 4dce4f16..75343cb4 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java
@@ -13,8 +13,7 @@ public class WxCpXmlOutTextMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxCpXmlOutTextMessageTest {
public void testBuild() {
WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content("content").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java
index b5ba2456..61e1cbfb 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java
@@ -15,8 +15,7 @@ public class WxCpXmlOutVideoMessageTest {
m.setFromUserName("fromUser");
m.setToUserName("toUser");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -39,8 +38,7 @@ public class WxCpXmlOutVideoMessageTest {
.title("title")
.description("ddfff")
.build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java
index fa73a329..897f5c37 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java
@@ -13,8 +13,7 @@ public class WxCpXmlOutVoiceMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxCpXmlOutVoiceMessageTest {
public void testBuild() {
WxCpXmlOutVoiceMessage m = WxCpXmlOutMessage.VOICE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
index b56d1780..2a248f98 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
@@ -1,20 +1,94 @@
package me.chanjar.weixin.cp.demo;
+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 org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import javax.xml.bind.JAXBException;
+import java.io.InputStream;
+import java.util.Map;
-/**
- * @author Daniel Qian
- */
public class WxCpDemoServer {
+
+ private static WxCpConfigStorage wxCpConfigStorage;
+ private static WxCpService wxCpService;
+ private static WxCpMessageRouter wxCpMessageRouter;
+
public static void main(String[] args) throws Exception {
+ initWeixin();
+
Server server = new Server(8080);
- ServletHandler handler = new ServletHandler();
- server.setHandler(handler);
+ ServletHandler servletHandler = new ServletHandler();
+ server.setHandler(servletHandler);
+
+ ServletHolder endpointServletHolder = new ServletHolder(new WxCpEndpointServlet(wxCpConfigStorage, wxCpService, wxCpMessageRouter));
+ servletHandler.addServletWithMapping(endpointServletHolder, "/*");
+
+ ServletHolder oauthServletHolder = new ServletHolder(new WxCpOAuth2Servlet(wxCpService));
+ servletHandler.addServletWithMapping(oauthServletHolder, "/oauth2/*");
- handler.addServletWithMapping(WxCpDemoServlet.class, "/*");
server.start();
server.join();
}
+
+ private static void initWeixin() {
+ try {
+ InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
+ WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1);
+
+ wxCpConfigStorage = config;
+ wxCpService = new WxCpServiceImpl();
+ wxCpService.setWxCpConfigStorage(config);
+
+ WxCpMessageHandler handler = new WxCpMessageHandler() {
+ @Override
+ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context,
+ WxCpService wxCpService) {
+ WxCpXmlOutTextMessage m = WxCpXmlOutMessage
+ .TEXT()
+ .content("测试加密消息")
+ .fromUser(wxMessage.getToUserName())
+ .toUser(wxMessage.getFromUserName())
+ .build();
+ return m;
+ }
+ };
+
+ WxCpMessageHandler oauth2handler = new WxCpMessageHandler() {
+ @Override
+ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context,
+ WxCpService wxCpService) {
+ String href = "测试oauth2";
+ return WxCpXmlOutMessage
+ .TEXT()
+ .content(href)
+ .fromUser(wxMessage.getToUserName())
+ .toUser(wxMessage.getFromUserName()).build();
+ }
+ };
+
+ wxCpMessageRouter = new WxCpMessageRouter(wxCpService);
+ wxCpMessageRouter
+ .rule()
+ .async(false)
+ .content("哈哈") // 拦截内容为“哈哈”的消息
+ .handler(handler)
+ .end()
+ .rule()
+ .async(false)
+ .content("oauth")
+ .handler(oauth2handler)
+ .end()
+ ;
+
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServlet.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
similarity index 55%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServlet.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
index b84d786f..320cc540 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServlet.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
@@ -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;
@@ -19,58 +19,31 @@ import java.util.Map;
/**
* @author Daniel Qian
*/
-public class WxCpDemoServlet extends HttpServlet {
+public class WxCpEndpointServlet extends HttpServlet {
- protected WxCpService wxCpService;
protected WxCpConfigStorage wxCpConfigStorage;
+ protected WxCpService wxCpService;
protected WxCpMessageRouter wxCpMessageRouter;
- @Override public void init() throws ServletException {
- //
- super.init();
- try {
- InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
- WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1);
-
- wxCpConfigStorage = config;
- wxCpService = new WxCpServiceImpl();
- wxCpService.setWxCpConfigStorage(config);
-
- WxCpMessageHandler handler = new WxCpMessageHandler() {
- @Override public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context) {
- WxCpXmlOutTextMessage m = WxCpXmlOutMessage
- .TEXT()
- .content("测试加密消息")
- .fromUser(wxMessage.getToUserName())
- .toUser(wxMessage.getFromUserName())
- .build();
- return m;
- }
- };
-
- wxCpMessageRouter = new WxCpMessageRouter();
- wxCpMessageRouter
- .rule()
- .async(false)
- .content("哈哈") // 拦截内容为“哈哈”的消息
- .handler(handler)
- .end();
-
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
+ public WxCpEndpointServlet(WxCpConfigStorage wxCpConfigStorage, WxCpService wxCpService,
+ WxCpMessageRouter wxCpMessageRouter) {
+ this.wxCpConfigStorage = wxCpConfigStorage;
+ this.wxCpService = wxCpService;
+ this.wxCpMessageRouter = wxCpMessageRouter;
}
- @Override protected void service(HttpServletRequest request, HttpServletResponse response)
+ @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 +57,9 @@ public class WxCpDemoServlet extends HttpServlet {
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);
-
if (outMessage != null) {
response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage));
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java
new file mode 100644
index 00000000..02b1bf5d
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.cp.demo;
+
+import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpService;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Created by qianjia on 14/11/28.
+ */
+public class WxCpOAuth2Servlet extends HttpServlet {
+
+ protected WxCpService wxCpService;
+
+ public WxCpOAuth2Servlet(WxCpService wxCpService) {
+ this.wxCpService = wxCpService;
+ }
+
+ @Override protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ response.setContentType("text/html;charset=utf-8");
+ response.setStatus(HttpServletResponse.SC_OK);
+
+ String code = request.getParameter("code");
+ try {
+ response.getWriter().println("
code
");
+ response.getWriter().println(code);
+
+ String[] res = wxCpService.oauth2getUserInfo(code);
+ response.getWriter().println("result
");
+ response.getWriter().println(Arrays.toString(res));
+ } catch (WxErrorException e) {
+ e.printStackTrace();
+ }
+
+ response.getWriter().flush();
+ response.getWriter().close();
+
+ }
+
+
+}
diff --git a/weixin-java-cp/src/test/resources/test-config.sample.xml b/weixin-java-cp/src/test/resources/test-config.sample.xml
index c30d7e35..02c98f3f 100644
--- a/weixin-java-cp/src/test/resources/test-config.sample.xml
+++ b/weixin-java-cp/src/test/resources/test-config.sample.xml
@@ -9,4 +9,5 @@
企业号通讯录里的某个userid
企业号通讯录的某个部门id
企业号通讯录里的某个tagid
+ 网页授权获取用户信息回调地址
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 940e79f3..f91e8291 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -6,7 +6,7 @@
me.chanjar
weixin-java-parent
- 1.0.4
+ 1.0.5
weixin-java-mp
WeiXin Java Tools - MP
diff --git a/weixin-java-mp/pom.xml.versionsBackup b/weixin-java-mp/pom.xml.versionsBackup
new file mode 100644
index 00000000..2e10c3ed
--- /dev/null
+++ b/weixin-java-mp/pom.xml.versionsBackup
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+ me.chanjar
+ weixin-java-parent
+ 1.0.5-SNAPSHOT
+
+ weixin-java-mp
+ WeiXin Java Tools - MP
+ 微信公众号Java SDK
+
+
+
+ me.chanjar
+ weixin-java-common
+ ${project.version}
+
+
+ junit
+ junit
+ test
+
+
+ org.testng
+ testng
+ 6.8.7
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+
+
+ com.google.inject
+ guice
+ 3.0
+ test
+
+
+ org.eclipse.jetty
+ jetty-server
+ 9.3.0.M0
+ test
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 9.3.0.M0
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/testng.xml
+
+
+
+
+
+
+
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
index e7ee779c..3ecbf155 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
@@ -25,6 +25,8 @@ public interface WxMpConfigStorage {
public int getExpiresIn();
+ public String getOauth2redirectUri();
+
public String getHttp_proxy_host();
public int getHttp_proxy_port();
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
index d0f9c33d..82c3d621 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
@@ -16,6 +16,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
protected String aesKey;
protected int expiresIn;
+ protected String oauth2redirectUri;
+
protected String http_proxy_host;
protected int http_proxy_port;
protected String http_proxy_username;
@@ -78,6 +80,15 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
this.expiresIn = expiresIn;
}
+ @Override
+ public String getOauth2redirectUri() {
+ return this.oauth2redirectUri;
+ }
+
+ public void setOauth2redirectUri(String oauth2redirectUri) {
+ this.oauth2redirectUri = oauth2redirectUri;
+ }
+
public String getHttp_proxy_host() {
return http_proxy_host;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
index e80ff5a1..8e6deeb6 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java
@@ -16,8 +16,9 @@ public interface WxMpMessageHandler {
*
* @param wxMessage
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
+ * @param wxMpService
* @return xml格式的消息,如果在异步规则里处理的话,可以返回null
*/
- public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context);
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
index 901defea..d940804f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java
@@ -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 context);
+ public boolean intercept(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
index f49cafe6..07451d6f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
@@ -40,17 +40,31 @@ import java.util.regex.Pattern;
*
*/
public class WxMpMessageRouter {
-
+
+ private static final int DEFAULT_THREAD_POOL_SIZE = 20;
+
private final List rules = new ArrayList();
- private final ExecutorService es = Executors.newCachedThreadPool();
-
+ private final ExecutorService executorService;
+
+ private final WxMpService wxMpService;
+
+ public WxMpMessageRouter(WxMpService wxMpService) {
+ this.wxMpService = wxMpService;
+ this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
+ }
+
+ public WxMpMessageRouter(WxMpService wxMpService, int threadPoolSize) {
+ this.wxMpService = wxMpService;
+ this.executorService = Executors.newFixedThreadPool(threadPoolSize);
+ }
+
/**
* 开始一个新的Route规则
* @return
*/
public Rule rule() {
- return new Rule(this);
+ return new Rule(this, wxMpService);
}
/**
@@ -73,7 +87,7 @@ public class WxMpMessageRouter {
if (matchRules.get(0).async) {
// 只要第一个是异步的,那就异步执行
// 在另一个线程里执行
- es.submit(new Runnable() {
+ executorService.execute(new Runnable() {
public void run() {
for (final Rule rule : matchRules) {
rule.service(wxMessage);
@@ -101,7 +115,11 @@ public class WxMpMessageRouter {
private final WxMpMessageRouter routerBuilder;
+ private final WxMpService wxMpService;
+
private boolean async = true;
+
+ private String fromUser;
private String msgType;
@@ -119,8 +137,9 @@ public class WxMpMessageRouter {
private List interceptors = new ArrayList();
- protected Rule(WxMpMessageRouter routerBuilder) {
+ protected Rule(WxMpMessageRouter routerBuilder, WxMpService wxMpService) {
this.routerBuilder = routerBuilder;
+ this.wxMpService = wxMpService;
}
/**
@@ -182,7 +201,17 @@ public class WxMpMessageRouter {
this.rContent = regex;
return this;
}
-
+
+ /**
+ * 如果fromUser等于某值
+ * @param fromUser
+ * @return
+ */
+ public Rule fromUser(String fromUser) {
+ this.fromUser = fromUser;
+ return this;
+ }
+
/**
* 设置微信消息拦截器
* @param interceptor
@@ -252,7 +281,9 @@ public class WxMpMessageRouter {
}
protected boolean test(WxMpXmlMessage wxMessage) {
- return
+ return
+ (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName()))
+ &&
(this.msgType == null || this.msgType.equals(wxMessage.getMsgType()))
&&
(this.event == null || this.event.equals(wxMessage.getEvent()))
@@ -274,7 +305,7 @@ public class WxMpMessageRouter {
Map context = new HashMap();
// 如果拦截器不通过
for (WxMpMessageInterceptor interceptor : this.interceptors) {
- if (!interceptor.intercept(wxMessage, context)) {
+ if (!interceptor.intercept(wxMessage, context, wxMpService)) {
return null;
}
}
@@ -283,7 +314,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;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
index daaa062f..8fc70e8e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
@@ -329,6 +329,54 @@ public interface WxMpService {
*/
WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException;
+ /**
+ *
+ * 构造oauth2授权的url连接
+ * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息
+ *
+ * @param scope
+ * @param state
+ * @return code
+ */
+ public String oauth2buildAuthorizationUrl(String scope, String state);
+
+ /**
+ *
+ * 用code换取oauth2的access token
+ * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=网页授权获取用户基本信息
+ *
+ * @param code
+ * @return
+ */
+ public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException;
+
+ /**
+ *
+ * 刷新oauth2的access token
+ *
+ * @param refreshToken
+ * @return
+ */
+ public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException;
+
+ /**
+ *
+ * 用oauth2获取用户信息, 当前面引导授权时的scope是snsapi_userinfo的时候才可以
+ *
+ * @param oAuth2AccessToken
+ * @param lang zh_CN, zh_TW, en
+ */
+ public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException;
+
+ /**
+ *
+ * 验证oauth2的access token是否有效
+ *
+ * @param oAuth2AccessToken
+ * @return
+ */
+ public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken);
+
/**
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求
* @param url
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
index a4b4cc37..93686ef6 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
@@ -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;
@@ -299,6 +297,98 @@ public class WxMpServiceImpl implements WxMpService {
return WxMpSemanticQueryResult.fromJson(responseContent);
}
+ @Override
+ public String oauth2buildAuthorizationUrl(String scope, String state) {
+ String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ;
+ url += "appid=" + wxMpConfigStorage.getAppId();
+ url += "&redirect_uri=" + URIUtil.encodeURIComponent(wxMpConfigStorage.getOauth2redirectUri());
+ url += "&response_type=code";
+ url += "&scope=" + scope;
+ if (state != null) {
+ url += "&state=" + state;
+ }
+ url += "#wechat_redirect";
+ return url;
+ }
+
+ @Override
+ public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/sns/oauth2/access_token?";
+ url += "appid=" + wxMpConfigStorage.getAppId();
+ url += "&secret=" + wxMpConfigStorage.getSecret();
+ url += "&code=" + code;
+ url += "&grant_type=authorization_code";
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(getHttpclient(), httpProxy, url, null);
+ return WxMpOAuth2AccessToken.fromJson(responseText);
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?";
+ url += "appid=" + wxMpConfigStorage.getAppId();
+ url += "&grant_type=refresh_token";
+ url += "&refresh_token=" + refreshToken;
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(getHttpclient(), httpProxy, url, null);
+ return WxMpOAuth2AccessToken.fromJson(responseText);
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/sns/userinfo?";
+ url += "access_token=" + oAuth2AccessToken.getAccessToken();
+ url += "&openid=" + oAuth2AccessToken.getOpenId();
+ if (lang == null) {
+ url += "&lang=zh_CN";
+ } else {
+ url += "&lang=" + lang;
+ }
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(getHttpclient(), httpProxy, url, null);
+ return WxMpUser.fromJson(responseText);
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) {
+ String url = "https://api.weixin.qq.com/sns/auth?";
+ url += "access_token=" + oAuth2AccessToken;
+ url += "&openid=" + oAuth2AccessToken.getOpenId();
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ executor.execute(getHttpclient(), httpProxy, url, null);
+ } catch (ClientProtocolException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (WxErrorException e) {
+ return false;
+ }
+ return true;
+ }
+
public String get(String url, String queryParam) throws WxErrorException {
return execute(new SimpleGetRequestExecutor(), url, queryParam);
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMewsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutNewsMessage.java
similarity index 95%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMewsMessage.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutNewsMessage.java
index 527dc6a7..4730a99b 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMewsMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutNewsMessage.java
@@ -10,7 +10,7 @@ import java.util.List;
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
-public class WxMpXmlOutMewsMessage extends WxMpXmlOutMessage {
+public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage {
@XmlElement(name = "ArticleCount")
protected int articleCount;
@@ -19,7 +19,7 @@ public class WxMpXmlOutMewsMessage extends WxMpXmlOutMessage {
@XmlElement(name = "item")
protected final List- articles = new ArrayList
- ();
- public WxMpXmlOutMewsMessage() {
+ public WxMpXmlOutNewsMessage() {
this.msgType = WxConsts.XML_MSG_NEWS;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/NewsBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/NewsBuilder.java
index 08a9da1e..6f225825 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/NewsBuilder.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/NewsBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.mp.bean.outxmlbuilder;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutMewsMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage;
import java.util.ArrayList;
import java.util.List;
@@ -9,18 +9,18 @@ import java.util.List;
* 图文消息builder
* @author chanjarster
*/
-public final class NewsBuilder extends BaseBuilder {
+public final class NewsBuilder extends BaseBuilder {
- protected final List articles = new ArrayList();
+ protected final List articles = new ArrayList();
- public NewsBuilder addArticle(WxMpXmlOutMewsMessage.Item item) {
+ public NewsBuilder addArticle(WxMpXmlOutNewsMessage.Item item) {
this.articles.add(item);
return this;
}
- public WxMpXmlOutMewsMessage build() {
- WxMpXmlOutMewsMessage m = new WxMpXmlOutMewsMessage();
- for(WxMpXmlOutMewsMessage.Item item : articles) {
+ public WxMpXmlOutNewsMessage build() {
+ WxMpXmlOutNewsMessage m = new WxMpXmlOutNewsMessage();
+ for(WxMpXmlOutNewsMessage.Item item : articles) {
m.addArticle(item);
}
setCommon(m);
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
new file mode 100644
index 00000000..88b732f9
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
@@ -0,0 +1,75 @@
+package me.chanjar.weixin.mp.bean.result;
+
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+/**
+ * Created by qianjia on 14/11/26.
+ */
+public class WxMpOAuth2AccessToken {
+
+ private String accessToken;
+
+ private int expiresIn = -1;
+
+ private String refreshToken;
+
+ private String openId;
+
+ private String scope;
+
+ public String getRefreshToken() {
+ return refreshToken;
+ }
+
+ public void setRefreshToken(String refreshToken) {
+ this.refreshToken = refreshToken;
+ }
+
+ public String getOpenId() {
+ return openId;
+ }
+
+ public void setOpenId(String openId) {
+ this.openId = openId;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public void setAccessToken(String accessToken) {
+ this.accessToken = accessToken;
+ }
+
+ public int getExpiresIn() {
+ return expiresIn;
+ }
+
+ public void setExpiresIn(int expiresIn) {
+ this.expiresIn = expiresIn;
+ }
+
+ public static WxMpOAuth2AccessToken fromJson(String json) {
+ return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class);
+ }
+
+ @Override
+ public String toString() {
+ return "WxMpOAuth2AccessToken{" +
+ "accessToken='" + accessToken + '\'' +
+ ", expiresIn=" + expiresIn +
+ ", refreshToken='" + refreshToken + '\'' +
+ ", openId='" + openId + '\'' +
+ ", scope='" + scope + '\'' +
+ '}';
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
index fa4aee6d..554a07db 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
@@ -9,7 +9,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
*/
public class WxMpUser {
- protected boolean subscribe;
+ protected Boolean subscribe;
protected String openId;
protected String nickname;
protected String sex;
@@ -18,13 +18,13 @@ public class WxMpUser {
protected String province;
protected String country;
protected String headImgUrl;
- protected long subscribeTime;
+ protected Long subscribeTime;
protected String unionId;
- public boolean isSubscribe() {
+ public Boolean isSubscribe() {
return subscribe;
}
- public void setSubscribe(boolean subscribe) {
+ public void setSubscribe(Boolean subscribe) {
this.subscribe = subscribe;
}
public String getOpenId() {
@@ -75,10 +75,10 @@ public class WxMpUser {
public void setHeadImgUrl(String headImgUrl) {
this.headImgUrl = headImgUrl;
}
- public long getSubscribeTime() {
+ public Long getSubscribeTime() {
return subscribeTime;
}
- public void setSubscribeTime(long subscribeTime) {
+ public void setSubscribeTime(Long subscribeTime) {
this.subscribeTime = subscribeTime;
}
public String getUnionId() {
@@ -91,5 +91,21 @@ public class WxMpUser {
public static WxMpUser fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUser.class);
}
-
+
+ @Override
+ public String toString() {
+ return "WxMpUser{" +
+ "subscribe=" + subscribe +
+ ", openId='" + openId + '\'' +
+ ", nickname='" + nickname + '\'' +
+ ", sex='" + sex + '\'' +
+ ", language='" + language + '\'' +
+ ", city='" + city + '\'' +
+ ", province='" + province + '\'' +
+ ", country='" + country + '\'' +
+ ", headImgUrl='" + headImgUrl + '\'' +
+ ", subscribeTime=" + subscribeTime +
+ ", unionId='" + unionId + '\'' +
+ '}';
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCustomMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCustomMessageGsonAdapter.java
index 6ff4b773..488dd8df 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCustomMessageGsonAdapter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCustomMessageGsonAdapter.java
@@ -64,6 +64,7 @@ public class WxMpCustomMessageGsonAdapter implements JsonSerializer {
+
+ public WxMpOAuth2AccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
+ JsonParseException {
+ WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken();
+ JsonObject accessTokenJsonObject = json.getAsJsonObject();
+
+ if (accessTokenJsonObject.get("access_token") != null && !accessTokenJsonObject.get("access_token").isJsonNull()) {
+ accessToken.setAccessToken(GsonHelper.getAsString(accessTokenJsonObject.get("access_token")));
+ }
+ if (accessTokenJsonObject.get("expires_in") != null && !accessTokenJsonObject.get("expires_in").isJsonNull()) {
+ accessToken.setExpiresIn(GsonHelper.getAsPrimitiveInt(accessTokenJsonObject.get("expires_in")));
+ }
+ if (accessTokenJsonObject.get("refresh_token") != null && !accessTokenJsonObject.get("refresh_token").isJsonNull()) {
+ accessToken.setRefreshToken(GsonHelper.getAsString(accessTokenJsonObject.get("refresh_token")));
+ }
+ if (accessTokenJsonObject.get("openid") != null && !accessTokenJsonObject.get("openid").isJsonNull()) {
+ accessToken.setOpenId(GsonHelper.getAsString(accessTokenJsonObject.get("openid")));
+ }
+ if (accessTokenJsonObject.get("scope") != null && !accessTokenJsonObject.get("scope").isJsonNull()) {
+ accessToken.setScope(GsonHelper.getAsString(accessTokenJsonObject.get("scope")));
+ }
+ return accessToken;
+ }
+
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java
index 5e619746..bff84eab 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java
@@ -56,6 +56,7 @@ public class XmlTransformer {
Marshaller m = JAXB_CONTEXT.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.setProperty(CharacterEscapeHandler.class.getName(), CHAR_ESCAPE_HANDLER);
+ m.setProperty(Marshaller.JAXB_FRAGMENT, true);
m.marshal(object, writer);
}
@@ -76,7 +77,7 @@ public class XmlTransformer {
return JAXBContext.newInstance(
WxMpXmlOutMessage.class,
WxMpMpXmlOutImageMessage.class,
- WxMpXmlOutMewsMessage.class,
+ WxMpXmlOutNewsMessage.class,
WxMpXmlOutMusicMessage.class,
WxMpXmlOutTextMessage.class,
WxMpXmlOutVideoMessage.class,
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java
index 65d88928..f87d97a4 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java
@@ -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;
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java
index b43ca3c8..b3c2460b 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java
@@ -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 context) {
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService) {
return null;
}
}).end();
@@ -149,7 +149,7 @@ public class WxMpMessageRouterTest {
}
@Override
- public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context) {
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService) {
sb.append(this.echoStr).append(',');
return null;
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java
index 68947b41..5e3d5620 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java
@@ -108,7 +108,7 @@ public class WxMpCustomMessageTest {
reply.getArticles().add(article2);
- Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}");
+ Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}");
}
public void testNewsBuild() {
@@ -125,8 +125,8 @@ public class WxMpCustomMessageTest {
article2.setTitle("Happy Day");
WxMpCustomMessage reply = WxMpCustomMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build();
-
- Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}");
+
+ Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}");
}
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java
index e0377cb6..f4b50e1d 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java
@@ -13,8 +13,7 @@ public class WxMpXmlOutImageMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxMpXmlOutImageMessageTest {
public void testBuild() {
WxMpMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutMusicMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutMusicMessageTest.java
index 0471e2c3..4397a677 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutMusicMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutMusicMessageTest.java
@@ -17,8 +17,7 @@ public class WxXmlOutMusicMessageTest {
m.setFromUserName("fromUser");
m.setToUserName("toUser");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -45,8 +44,7 @@ public class WxXmlOutMusicMessageTest {
.musicUrl("musicUrl")
.thumbMediaId("thumbMediaId")
.build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutNewsMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutNewsMessageTest.java
index 782a6abe..5e2da0b0 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutNewsMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutNewsMessageTest.java
@@ -7,20 +7,19 @@ import org.testng.annotations.Test;
public class WxXmlOutNewsMessageTest {
public void test() {
- WxMpXmlOutMewsMessage m = new WxMpXmlOutMewsMessage();
+ WxMpXmlOutNewsMessage m = new WxMpXmlOutNewsMessage();
m.setCreateTime(1122l);
m.setFromUserName("fromUser");
m.setToUserName("toUser");
- WxMpXmlOutMewsMessage.Item item = new WxMpXmlOutMewsMessage.Item();
+ WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setDescription("description");
item.setPicUrl("picUrl");
item.setTitle("title");
item.setUrl("url");
m.addArticle(item);
m.addArticle(item);
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -46,20 +45,19 @@ public class WxXmlOutNewsMessageTest {
}
public void testBuild() {
- WxMpXmlOutMewsMessage.Item item = new WxMpXmlOutMewsMessage.Item();
+ WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
item.setDescription("description");
item.setPicUrl("picUrl");
item.setTitle("title");
item.setUrl("url");
- WxMpXmlOutMewsMessage m = WxMpXmlOutMessage.NEWS()
+ WxMpXmlOutNewsMessage m = WxMpXmlOutMessage.NEWS()
.fromUser("fromUser")
.toUser("toUser")
.addArticle(item)
.addArticle(item)
.build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutTextMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutTextMessageTest.java
index a845abcd..2a752051 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutTextMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutTextMessageTest.java
@@ -13,8 +13,7 @@ public class WxXmlOutTextMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxXmlOutTextMessageTest {
public void testBuild() {
WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content("content").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVideoMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVideoMessageTest.java
index b033b040..19fbe62a 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVideoMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVideoMessageTest.java
@@ -15,8 +15,7 @@ public class WxXmlOutVideoMessageTest {
m.setFromUserName("fromUser");
m.setToUserName("toUser");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -39,8 +38,7 @@ public class WxXmlOutVideoMessageTest {
.title("title")
.description("ddfff")
.build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVoiceMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVoiceMessageTest.java
index 65644f3d..0eb848cd 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVoiceMessageTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxXmlOutVoiceMessageTest.java
@@ -13,8 +13,7 @@ public class WxXmlOutVoiceMessageTest {
m.setFromUserName("from");
m.setToUserName("to");
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
@@ -27,8 +26,7 @@ public class WxXmlOutVoiceMessageTest {
public void testBuild() {
WxMpXmlOutVoiceMessage m = WxMpXmlOutMessage.VOICE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
- String expected = ""
- + ""
+ String expected = ""
+ ""
+ ""
+ "1122"
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
index e0bb6498..0d7b126d 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
@@ -1,20 +1,124 @@
package me.chanjar.weixin.mp.demo;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.mp.api.*;
+import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.*;
+
+import javax.xml.bind.JAXBException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
-/**
- * @author Daniel Qian
- */
public class WxMpDemoServer {
+
+ private static WxMpConfigStorage wxMpConfigStorage;
+ private static WxMpService wxMpService;
+ private static WxMpMessageRouter wxMpMessageRouter;
+
public static void main(String[] args) throws Exception {
+ initWeixin();
+
Server server = new Server(8080);
- ServletHandler handler = new ServletHandler();
- server.setHandler(handler);
+ ServletHandler servletHandler = new ServletHandler();
+ server.setHandler(servletHandler);
+
+ ServletHolder endpointServletHolder = new ServletHolder(new WxMpEndpointServlt(wxMpConfigStorage, wxMpService, wxMpMessageRouter));
+ servletHandler.addServletWithMapping(endpointServletHolder, "/*");
+
+ ServletHolder oauthServletHolder = new ServletHolder(new WxMpOAuth2Servlet(wxMpService));
+ servletHandler.addServletWithMapping(oauthServletHolder, "/oauth2/*");
- handler.addServletWithMapping(WxMpDemoServlet.class, "/*");
server.start();
server.join();
}
+
+ private static void initWeixin() {
+ try {
+ InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
+ WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1);
+
+ wxMpConfigStorage = config;
+ wxMpService = new WxMpServiceImpl();
+ wxMpService.setWxMpConfigStorage(config);
+
+ WxMpMessageHandler textHandler = new WxMpMessageHandler() {
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context,
+ WxMpService wxMpService) {
+ WxMpXmlOutTextMessage m
+ = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName())
+ .toUser(wxMessage.getFromUserName()).build();
+ return m;
+ }
+ };
+
+ WxMpMessageHandler imageHandler = new WxMpMessageHandler() {
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context,
+ WxMpService wxMpService) {
+ try {
+ WxMediaUploadResult wxMediaUploadResult = wxMpService
+ .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg"));
+ WxMpMpXmlOutImageMessage m
+ = WxMpXmlOutMessage
+ .IMAGE()
+ .mediaId(wxMediaUploadResult.getMediaId())
+ .fromUser(wxMessage.getToUserName())
+ .toUser(wxMessage.getFromUserName())
+ .build();
+ return m;
+ } catch (WxErrorException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ };
+
+ WxMpMessageHandler oauth2handler = new WxMpMessageHandler() {
+ @Override
+ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context,
+ WxMpService wxMpService) {
+ String href = "测试oauth2";
+ return WxMpXmlOutMessage
+ .TEXT()
+ .content(href)
+ .fromUser(wxMessage.getToUserName())
+ .toUser(wxMessage.getFromUserName()).build();
+ }
+ };
+
+ wxMpMessageRouter = new WxMpMessageRouter(wxMpService);
+ wxMpMessageRouter
+ .rule()
+ .async(false)
+ .content("哈哈") // 拦截内容为“哈哈”的消息
+ .handler(textHandler)
+ .end()
+ .rule()
+ .async(false)
+ .content("图片")
+ .handler(imageHandler)
+ .end()
+ .rule()
+ .async(false)
+ .content("oauth")
+ .handler(oauth2handler)
+ .end()
+ ;
+
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java
similarity index 50%
rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java
rename to weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java
index 7ceb2e26..c99cd8b3 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java
@@ -1,10 +1,14 @@
package me.chanjar.weixin.mp.demo;
+import me.chanjar.weixin.common.api.WxConsts;
+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.mp.api.*;
+import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
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;
@@ -18,55 +22,29 @@ import java.util.Map;
/**
* @author Daniel Qian
*/
-public class WxMpDemoServlet extends HttpServlet {
+public class WxMpEndpointServlt extends HttpServlet {
- protected WxMpService wxMpService;
protected WxMpConfigStorage wxMpConfigStorage;
+ protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter;
- @Override public void init() throws ServletException {
- //
- super.init();
- try {
- InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
- WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1);
-
- wxMpConfigStorage = config;
- wxMpService = new WxMpServiceImpl();
- wxMpService.setWxMpConfigStorage(config);
-
- WxMpMessageHandler handler = new WxMpMessageHandler() {
- @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context) {
- WxMpXmlOutTextMessage m
- = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName())
- .toUser(wxMessage.getFromUserName()).build();
- return m;
- }
- };
-
- wxMpMessageRouter = new WxMpMessageRouter();
- wxMpMessageRouter
- .rule()
- .async(false)
- .content("哈哈") // 拦截内容为“哈哈”的消息
- .handler(handler)
- .end();
-
- } catch (JAXBException e) {
- throw new RuntimeException(e);
- }
+ public WxMpEndpointServlt(WxMpConfigStorage wxMpConfigStorage, WxMpService wxMpService,
+ WxMpMessageRouter wxMpMessageRouter) {
+ this.wxMpConfigStorage = wxMpConfigStorage;
+ this.wxMpService = wxMpService;
+ this.wxMpMessageRouter = wxMpMessageRouter;
}
@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 +62,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;
}
}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
new file mode 100644
index 00000000..6ddf4ad3
--- /dev/null
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
@@ -0,0 +1,65 @@
+package me.chanjar.weixin.mp.demo;
+
+import me.chanjar.weixin.common.api.WxConsts;
+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.mp.api.*;
+import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
+import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
+import me.chanjar.weixin.mp.bean.result.WxMpUser;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+public class WxMpOAuth2Servlet extends HttpServlet {
+
+ protected WxMpService wxMpService;
+
+ public WxMpOAuth2Servlet(WxMpService wxMpService) {
+ this.wxMpService = wxMpService;
+ }
+
+ @Override protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ response.setContentType("text/html;charset=utf-8");
+ response.setStatus(HttpServletResponse.SC_OK);
+
+ String code = request.getParameter("code");
+ try {
+ response.getWriter().println("
code
");
+ response.getWriter().println(code);
+
+ WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
+ response.getWriter().println("access token
");
+ response.getWriter().println(wxMpOAuth2AccessToken.toString());
+
+ WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
+ response.getWriter().println("user info
");
+ response.getWriter().println(wxMpUser.toString());
+
+ wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
+ response.getWriter().println("after refresh
");
+ response.getWriter().println(wxMpOAuth2AccessToken.toString());
+
+ } catch (WxErrorException e) {
+ e.printStackTrace();
+ }
+
+ response.getWriter().flush();
+ response.getWriter().close();
+
+ }
+
+}
diff --git a/weixin-java-mp/src/test/resources/test-config.sample.xml b/weixin-java-mp/src/test/resources/test-config.sample.xml
index 501620cd..19535f3c 100644
--- a/weixin-java-mp/src/test/resources/test-config.sample.xml
+++ b/weixin-java-mp/src/test/resources/test-config.sample.xml
@@ -6,4 +6,5 @@
可以不填写
可以不填写
某个加你公众号的用户的openId
+ 网页授权获取用户信息回调地址