| @@ -1,12 +1,26 @@ | |||||
| language: java | language: java | ||||
| jdk: | |||||
| - oraclejdk7 | |||||
| script: "mvn clean package -Dmaven.test.skip=true" | |||||
| sudo: false | |||||
| install: true | |||||
| addons: | |||||
| sonarqube: | |||||
| token: | |||||
| secure: "834110c7191f97ecb226970c46dcaff8e681da5a" | |||||
| jdk: | |||||
| - oraclejdk8 | |||||
| #script: "mvn clean package -Dmaven.test.skip=true" | |||||
| script: | |||||
| - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar | |||||
| branches: | branches: | ||||
| only: | only: | ||||
| - develop | - develop | ||||
| cache: | |||||
| directories: | |||||
| - '$HOME/.m2/repository' | |||||
| - '$HOME/.sonar/cache' | |||||
| notifications: | notifications: | ||||
| email: | email: | ||||
| @@ -1,7 +1,7 @@ | |||||
| Weixin Java Tools 微信公众号/企业号开发Java SDK | Weixin Java Tools 微信公众号/企业号开发Java SDK | ||||
| ===================================== | ===================================== | ||||
| [](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) | [](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) | ||||
| [](https://travis-ci.org/wechat-group/weixin-java-tools) | |||||
| [](https://travis-ci.org/Wechat-Group/weixin-java-tools) | |||||
| ### 注意: | ### 注意: | ||||
| 1. ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。*** | 1. ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。*** | ||||
| @@ -13,7 +13,7 @@ Weixin Java Tools 微信公众号/企业号开发Java SDK | |||||
| ## 开发交流方式及注意事项: | ## 开发交流方式及注意事项: | ||||
| 1. QQ群:343954419(推荐点击按钮入群: [](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [](http://jq.qq.com/?_wv=1027&k=40lRskK),如果无反应,可以自行搜索群号进行添加 ) | 1. QQ群:343954419(推荐点击按钮入群: [](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [](http://jq.qq.com/?_wv=1027&k=40lRskK),如果无反应,可以自行搜索群号进行添加 ) | ||||
| 1. 由于群容量有限即将爆满,现开启付费入群模式,并不定期清理长时间不活跃人士; | |||||
| 1. 由于群容量有限,即将爆满,故开启付费入群模式以保证只有真实交流需求的人进入,并为保证群的活跃度,将不定期清理长时间不活跃的同学; | |||||
| 1. 微信群: 因微信群已达到100人限制,故如有想加入微信群的,请入QQ群后联系管理员,提供微信号以便邀请加入; | 1. 微信群: 因微信群已达到100人限制,故如有想加入微信群的,请入QQ群后联系管理员,提供微信号以便邀请加入; | ||||
| 1. 新手提问前,请先阅读此文章:http://t.cn/RV93MRB | 1. 新手提问前,请先阅读此文章:http://t.cn/RV93MRB | ||||
| 1. 寻求帮助时需贴代码或大长串异常信息的,请利用http://paste.ubuntu.com | 1. 寻求帮助时需贴代码或大长串异常信息的,请利用http://paste.ubuntu.com | ||||
| @@ -25,12 +25,12 @@ Weixin Java Tools 微信公众号/企业号开发Java SDK | |||||
| =========== | =========== | ||||
| ## 版本说明 | ## 版本说明 | ||||
| 1. 本项目定为每月发布一次正式版,版本号格式为X.X.0(如2.1.0,2.2.0等),月初或月底发布新版本,遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request; | |||||
| 1. 本项目定为每两个月发布一次正式版,版本号格式为X.X.0(如2.1.0,2.2.0等),月底发布新版本,遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request; | |||||
| 1. BUG修复和新特性一般会先发布成小版本作为临时版本(如2.0.1,2.0.2等,即尾号不为0,以区别于正式版); | 1. BUG修复和新特性一般会先发布成小版本作为临时版本(如2.0.1,2.0.2等,即尾号不为0,以区别于正式版); | ||||
| 1. 目前最新版本号为 [](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) ,也可以通过访问链接 [【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22) 、[【企业号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22) | 1. 目前最新版本号为 [](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) ,也可以通过访问链接 [【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22) 、[【企业号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22) | ||||
| 分别查看所有最新的版本。 | 分别查看所有最新的版本。 | ||||
| ## Maven & Gradle | |||||
| ## Maven & Gradle 最新正式版本 | |||||
| * 公众号(订阅号、服务号): | * 公众号(订阅号、服务号): | ||||
| @@ -20,8 +20,7 @@ public class WxError implements Serializable { | |||||
| private String json; | private String json; | ||||
| public static WxError fromJson(String json) { | public static WxError fromJson(String json) { | ||||
| WxError error = WxGsonBuilder.create().fromJson(json, WxError.class); | |||||
| return error; | |||||
| return WxGsonBuilder.create().fromJson(json, WxError.class); | |||||
| } | } | ||||
| public static Builder newBuilder() { | public static Builder newBuilder() { | ||||
| @@ -11,12 +11,12 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| /** | /** | ||||
| * The string manager for this package. | * The string manager for this package. | ||||
| */ | */ | ||||
| protected static final StringManager sm = | |||||
| StringManager.getManager(Constants.Package); | |||||
| protected static final StringManager sm = StringManager.getManager(Constants.Package); | |||||
| /** | /** | ||||
| * Type array. | * Type array. | ||||
| */ | */ | ||||
| protected static final String EMPTY_ARRAY[] = new String[0]; | |||||
| private static final String[] EMPTY_ARRAY = new String[0]; | |||||
| // ------------------------------ WxSession | // ------------------------------ WxSession | ||||
| protected Map<String, Object> attributes = new ConcurrentHashMap<>(); | protected Map<String, Object> attributes = new ConcurrentHashMap<>(); | ||||
| /** | /** | ||||
| @@ -71,20 +71,23 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public Object getAttribute(String name) { | public Object getAttribute(String name) { | ||||
| if (!isValidInternal()) | |||||
| if (!isValidInternal()) { | |||||
| throw new IllegalStateException | throw new IllegalStateException | ||||
| (sm.getString("sessionImpl.getAttribute.ise")); | |||||
| (sm.getString("sessionImpl.getAttribute.ise")); | |||||
| } | |||||
| if (name == null) return null; | |||||
| if (name == null) { | |||||
| return null; | |||||
| } | |||||
| return (this.attributes.get(name)); | |||||
| return this.attributes.get(name); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public Enumeration<String> getAttributeNames() { | public Enumeration<String> getAttributeNames() { | ||||
| if (!isValidInternal()) | |||||
| throw new IllegalStateException | |||||
| (sm.getString("sessionImpl.getAttributeNames.ise")); | |||||
| if (!isValidInternal()) { | |||||
| throw new IllegalStateException(sm.getString("sessionImpl.getAttributeNames.ise")); | |||||
| } | |||||
| Set<String> names = new HashSet<>(); | Set<String> names = new HashSet<>(); | ||||
| names.addAll(this.attributes.keySet()); | names.addAll(this.attributes.keySet()); | ||||
| @@ -94,9 +97,9 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public void setAttribute(String name, Object value) { | public void setAttribute(String name, Object value) { | ||||
| // Name cannot be null | // Name cannot be null | ||||
| if (name == null) | |||||
| throw new IllegalArgumentException | |||||
| (sm.getString("sessionImpl.setAttribute.namenull")); | |||||
| if (name == null) { | |||||
| throw new IllegalArgumentException(sm.getString("sessionImpl.setAttribute.namenull")); | |||||
| } | |||||
| // Null value is the same as removeAttribute() | // Null value is the same as removeAttribute() | ||||
| if (value == null) { | if (value == null) { | ||||
| @@ -105,9 +108,9 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| } | } | ||||
| // Validate our current state | // Validate our current state | ||||
| if (!isValidInternal()) | |||||
| throw new IllegalStateException(sm.getString( | |||||
| "sessionImpl.setAttribute.ise", getIdInternal())); | |||||
| if (!isValidInternal()) { | |||||
| throw new IllegalStateException(sm.getString("sessionImpl.setAttribute.ise", getIdInternal())); | |||||
| } | |||||
| this.attributes.put(name, value); | this.attributes.put(name, value); | ||||
| @@ -121,8 +124,7 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public void invalidate() { | public void invalidate() { | ||||
| if (!isValidInternal()) | if (!isValidInternal()) | ||||
| throw new IllegalStateException | |||||
| (sm.getString("sessionImpl.invalidate.ise")); | |||||
| throw new IllegalStateException(sm.getString("sessionImpl.invalidate.ise")); | |||||
| // Cause this session to expire | // Cause this session to expire | ||||
| expire(); | expire(); | ||||
| @@ -131,12 +133,11 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public WxSession getSession() { | public WxSession getSession() { | ||||
| if (this.facade == null) { | if (this.facade == null) { | ||||
| this.facade = new StandardSessionFacade(this); | this.facade = new StandardSessionFacade(this); | ||||
| } | } | ||||
| return (this.facade); | |||||
| return this.facade; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -185,12 +186,14 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public String getIdInternal() { | public String getIdInternal() { | ||||
| return (this.id); | |||||
| return this.id; | |||||
| } | } | ||||
| protected void removeAttributeInternal(String name) { | protected void removeAttributeInternal(String name) { | ||||
| // Avoid NPE | // Avoid NPE | ||||
| if (name == null) return; | |||||
| if (name == null) { | |||||
| return; | |||||
| } | |||||
| // Remove this attribute from our collection | // Remove this attribute from our collection | ||||
| this.attributes.remove(name); | this.attributes.remove(name); | ||||
| @@ -202,19 +205,22 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| // Check to see if session has already been invalidated. | // Check to see if session has already been invalidated. | ||||
| // Do not check expiring at this point as expire should not return until | // Do not check expiring at this point as expire should not return until | ||||
| // isValid is false | // isValid is false | ||||
| if (!this.isValid) | |||||
| if (!this.isValid) { | |||||
| return; | return; | ||||
| } | |||||
| synchronized (this) { | synchronized (this) { | ||||
| // Check again, now we are inside the sync so this code only runs once | // Check again, now we are inside the sync so this code only runs once | ||||
| // Double check locking - isValid needs to be volatile | // Double check locking - isValid needs to be volatile | ||||
| // The check of expiring is to ensure that an infinite loop is not | // The check of expiring is to ensure that an infinite loop is not | ||||
| // entered as per bug 56339 | // entered as per bug 56339 | ||||
| if (this.expiring || !this.isValid) | |||||
| if (this.expiring || !this.isValid) { | |||||
| return; | return; | ||||
| } | |||||
| if (this.manager == null) | |||||
| if (this.manager == null) { | |||||
| return; | return; | ||||
| } | |||||
| // Mark this session as "being expired" | // Mark this session as "being expired" | ||||
| this.expiring = true; | this.expiring = true; | ||||
| @@ -230,9 +236,9 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| this.expiring = false; | this.expiring = false; | ||||
| // Unbind any objects associated with this session | // Unbind any objects associated with this session | ||||
| String keys[] = keys(); | |||||
| for (int i = 0; i < keys.length; i++) { | |||||
| removeAttributeInternal(keys[i]); | |||||
| String[] keys = keys(); | |||||
| for (String key : keys) { | |||||
| removeAttributeInternal(key); | |||||
| } | } | ||||
| } | } | ||||
| @@ -273,13 +279,15 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public void setId(String id) { | public void setId(String id) { | ||||
| if ((this.id != null) && (this.manager != null)) | |||||
| if ((this.id != null) && (this.manager != null)) { | |||||
| this.manager.remove(this); | this.manager.remove(this); | ||||
| } | |||||
| this.id = id; | this.id = id; | ||||
| if (this.manager != null) | |||||
| if (this.manager != null) { | |||||
| this.manager.add(this); | this.manager.add(this); | ||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -295,21 +303,41 @@ public class StandardSession implements WxSession, InternalSession { | |||||
| @Override | @Override | ||||
| public boolean equals(Object o) { | public boolean equals(Object o) { | ||||
| if (this == o) return true; | |||||
| if (!(o instanceof StandardSession)) return false; | |||||
| if (this == o) { | |||||
| return true; | |||||
| } | |||||
| if (!(o instanceof StandardSession)) { | |||||
| return false; | |||||
| } | |||||
| StandardSession session = (StandardSession) o; | StandardSession session = (StandardSession) o; | ||||
| if (this.creationTime != session.creationTime) return false; | |||||
| if (this.expiring != session.expiring) return false; | |||||
| if (this.isValid != session.isValid) return false; | |||||
| if (this.maxInactiveInterval != session.maxInactiveInterval) return false; | |||||
| if (this.thisAccessedTime != session.thisAccessedTime) return false; | |||||
| if (!this.accessCount.equals(session.accessCount)) return false; | |||||
| if (!this.attributes.equals(session.attributes)) return false; | |||||
| if (!this.facade.equals(session.facade)) return false; | |||||
| if (!this.id.equals(session.id)) return false; | |||||
| return this.manager.equals(session.manager); | |||||
| if (this.creationTime != session.creationTime) { | |||||
| return false; | |||||
| } | |||||
| if (this.expiring != session.expiring) { | |||||
| return false; | |||||
| } | |||||
| if (this.isValid != session.isValid) { | |||||
| return false; | |||||
| } | |||||
| if (this.maxInactiveInterval != session.maxInactiveInterval) { | |||||
| return false; | |||||
| } | |||||
| if (this.thisAccessedTime != session.thisAccessedTime) { | |||||
| return false; | |||||
| } | |||||
| if (this.accessCount.get() != session.accessCount.get()) { | |||||
| return false; | |||||
| } | |||||
| if (!this.attributes.equals(session.attributes)) { | |||||
| return false; | |||||
| } | |||||
| if (!this.facade.equals(session.facade)) { | |||||
| return false; | |||||
| } | |||||
| return this.id.equals(session.id) && this.manager.equals(session.manager); | |||||
| } | } | ||||
| @@ -538,8 +538,16 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| int retryTimes = 0; | int retryTimes = 0; | ||||
| do { | do { | ||||
| try { | try { | ||||
| return executeInternal(executor, uri, data); | |||||
| T result = this.executeInternal(executor, uri, data); | |||||
| this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",uri, data, result); | |||||
| return result; | |||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| if (retryTimes + 1 > this.maxRetryTimes) { | |||||
| this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); | |||||
| //最后一次重试失败后,直接抛出异常,不再等待 | |||||
| throw new RuntimeException("微信服务端异常,超出重试次数"); | |||||
| } | |||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /* | /* | ||||
| * -1 系统繁忙, 1000ms后重试 | * -1 系统繁忙, 1000ms后重试 | ||||
| @@ -547,8 +555,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| if (error.getErrorCode() == -1) { | if (error.getErrorCode() == -1) { | ||||
| int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | ||||
| try { | try { | ||||
| this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, | |||||
| retryTimes + 1); | |||||
| this.log.debug("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||||
| Thread.sleep(sleepMillis); | Thread.sleep(sleepMillis); | ||||
| } catch (InterruptedException e1) { | } catch (InterruptedException e1) { | ||||
| throw new RuntimeException(e1); | throw new RuntimeException(e1); | ||||
| @@ -557,8 +564,9 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| throw e; | throw e; | ||||
| } | } | ||||
| } | } | ||||
| } while (++retryTimes < this.maxRetryTimes); | |||||
| } while (retryTimes++ < this.maxRetryTimes); | |||||
| this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); | |||||
| throw new RuntimeException("微信服务端异常,超出重试次数"); | throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||
| } | } | ||||
| @@ -572,8 +580,7 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; | ||||
| try { | try { | ||||
| return executor.execute(getHttpclient(), this.httpProxy, | |||||
| uriWithAccessToken, data); | |||||
| return executor.execute(getHttpclient(), this.httpProxy, uriWithAccessToken, data); | |||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| /* | /* | ||||
| @@ -586,11 +593,14 @@ public class WxCpServiceImpl implements WxCpService { | |||||
| this.configStorage.expireAccessToken(); | this.configStorage.expireAccessToken(); | ||||
| return execute(executor, uri, data); | return execute(executor, uri, data); | ||||
| } | } | ||||
| if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
| this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, error); | |||||
| throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
| } | } | ||||
| return null; | return null; | ||||
| } catch (IOException e) { | } catch (IOException e) { | ||||
| this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", uri, data, e.getMessage()); | |||||
| throw new RuntimeException(e); | throw new RuntimeException(e); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,17 +1,16 @@ | |||||
| package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Test; | |||||
| import java.util.concurrent.ExecutionException; | import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||
| import java.util.concurrent.Future; | import java.util.concurrent.Future; | ||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Test; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| @Test | @Test | ||||
| public class WxCpBusyRetryTest { | public class WxCpBusyRetryTest { | ||||
| @@ -23,6 +22,7 @@ public class WxCpBusyRetryTest { | |||||
| protected synchronized <T, E> T executeInternal( | protected synchronized <T, E> T executeInternal( | ||||
| RequestExecutor<T, E> executor, String uri, E data) | RequestExecutor<T, E> executor, String uri, E data) | ||||
| throws WxErrorException { | throws WxErrorException { | ||||
| this.log.info("Executed"); | |||||
| WxError error = new WxError(); | WxError error = new WxError(); | ||||
| error.setErrorCode(-1); | error.setErrorCode(-1); | ||||
| throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
| @@ -0,0 +1,80 @@ | |||||
| package me.chanjar.weixin.mp.api; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.mp.bean.device.*; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public interface WxMpDeviceService { | |||||
| /** | |||||
| * <pre> | |||||
| * 主动发送消息给设备 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-3 | |||||
| * </pre> | |||||
| */ | |||||
| TransMsgResp transMsg(WxDeviceMsg msg) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取一组新的deviceid和设备二维码 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-6 | |||||
| * </pre> | |||||
| * @param productId 产品id | |||||
| * @return 返回WxDeviceQrCodeResult | |||||
| */ | |||||
| WxDeviceQrCodeResult getQrCode(String productId) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 将device id及其属性信息提交公众平台进行授权 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-6 | |||||
| * </pre> | |||||
| * @param wxDeviceAuthorize 授权请求对象 | |||||
| * @return WxDeviceAuthorizeResult | |||||
| */ | |||||
| WxDeviceAuthorizeResult authorize(WxDeviceAuthorize wxDeviceAuthorize) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 第三方后台绑定成功后,通知公众平台 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html/page=3-4-7 | |||||
| * </pre> | |||||
| * @param wxDeviceBind 绑定请求对象 | |||||
| * @return WxDeviceBindResult | |||||
| */ | |||||
| WxDeviceBindResult bind(WxDeviceBind wxDeviceBind) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 强制绑定用户和设备 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-7 | |||||
| * </pre> | |||||
| * @param wxDeviceBind 强制绑定请求对象 | |||||
| * @return WxDeviceBindResult | |||||
| */ | |||||
| WxDeviceBindResult compelBind(WxDeviceBind wxDeviceBind) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 第三方确认用户和设备的解绑操作 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html/page=3-4-7 | |||||
| * </pre> | |||||
| * @param wxDeviceBind 绑定请求对象 | |||||
| * @return WxDeviceBidResult | |||||
| */ | |||||
| WxDeviceBindResult unbind(WxDeviceBind wxDeviceBind) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 强制解绑用户和设备 | |||||
| * 详情请见:http://iot.weixin.qq.com/wiki/new/index.html?page=3-4-7 | |||||
| * </pre> | |||||
| * @param wxDeviceBind 强制解绑请求对象 | |||||
| * @return WxDeviceBindResult | |||||
| */ | |||||
| WxDeviceBindResult compelUnbind(WxDeviceBind wxDeviceBind) throws WxErrorException; | |||||
| } | |||||
| @@ -345,4 +345,11 @@ public interface WxMpService { | |||||
| * @return WxMpTemplateMsgService | * @return WxMpTemplateMsgService | ||||
| */ | */ | ||||
| WxMpTemplateMsgService getTemplateMsgService(); | WxMpTemplateMsgService getTemplateMsgService(); | ||||
| /** | |||||
| * 返回硬件平台相关接口方法的实现类对象,以方便调用其各个接口 | |||||
| * | |||||
| * @return WxMpDeviceService | |||||
| */ | |||||
| WxMpDeviceService getDeviceService(); | |||||
| } | } | ||||
| @@ -0,0 +1,72 @@ | |||||
| package me.chanjar.weixin.mp.api.impl; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.mp.api.WxMpDeviceService; | |||||
| import me.chanjar.weixin.mp.api.WxMpService; | |||||
| import me.chanjar.weixin.mp.bean.device.*; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxMpDeviceServiceImpl implements WxMpDeviceService { | |||||
| private static final String API_URL_PREFIX = "https://api.weixin.qq.com/device"; | |||||
| private static Logger log = LoggerFactory.getLogger(WxMpMenuServiceImpl.class); | |||||
| private WxMpService wxMpService; | |||||
| WxMpDeviceServiceImpl(WxMpService wxMpService) { | |||||
| this.wxMpService = wxMpService; | |||||
| } | |||||
| @Override | |||||
| public TransMsgResp transMsg(WxDeviceMsg msg) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/transmsg"; | |||||
| String response = this.wxMpService.post(url,msg.toJson()); | |||||
| return TransMsgResp.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceQrCodeResult getQrCode(String productId) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/getqrcode"; | |||||
| String response = this.wxMpService.get(url, "product_id=" + productId); | |||||
| return WxDeviceQrCodeResult.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceAuthorizeResult authorize(WxDeviceAuthorize wxDeviceAuthorize) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/authorize_device"; | |||||
| String response = this.wxMpService.post(url,wxDeviceAuthorize.toJson()); | |||||
| return WxDeviceAuthorizeResult.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceBindResult bind(WxDeviceBind wxDeviceBind) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/bind"; | |||||
| String response = this.wxMpService.post(url,wxDeviceBind.toJson()); | |||||
| return WxDeviceBindResult.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceBindResult compelBind(WxDeviceBind wxDeviceBind) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/compel_bind"; | |||||
| String response = this.wxMpService.post(url,wxDeviceBind.toJson()); | |||||
| return WxDeviceBindResult.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceBindResult unbind(WxDeviceBind wxDeviceBind) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/unbind?"; | |||||
| String response = this.wxMpService.post(url, wxDeviceBind.toJson()); | |||||
| return WxDeviceBindResult.fromJson(response); | |||||
| } | |||||
| @Override | |||||
| public WxDeviceBindResult compelUnbind(WxDeviceBind wxDeviceBind) throws WxErrorException { | |||||
| String url = API_URL_PREFIX + "/compel_unbind?"; | |||||
| String response = this.wxMpService.post(url, wxDeviceBind.toJson()); | |||||
| return WxDeviceBindResult.fromJson(response); | |||||
| } | |||||
| } | |||||
| @@ -62,6 +62,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | ||||
| private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | |||||
| private CloseableHttpClient httpClient; | private CloseableHttpClient httpClient; | ||||
| private HttpHost httpProxy; | private HttpHost httpProxy; | ||||
| @@ -367,12 +369,18 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",uri, data, result); | this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}",uri, data, result); | ||||
| return result; | return result; | ||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| if (retryTimes + 1 > this.maxRetryTimes) { | |||||
| this.log.warn("重试达到最大次数【{}】", maxRetryTimes); | |||||
| //最后一次重试失败后,直接抛出异常,不再等待 | |||||
| throw new RuntimeException("微信服务端异常,超出重试次数"); | |||||
| } | |||||
| WxError error = e.getError(); | WxError error = e.getError(); | ||||
| // -1 系统繁忙, 1000ms后重试 | // -1 系统繁忙, 1000ms后重试 | ||||
| if (error.getErrorCode() == -1) { | if (error.getErrorCode() == -1) { | ||||
| int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | ||||
| try { | try { | ||||
| this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||||
| this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | |||||
| Thread.sleep(sleepMillis); | Thread.sleep(sleepMillis); | ||||
| } catch (InterruptedException e1) { | } catch (InterruptedException e1) { | ||||
| throw new RuntimeException(e1); | throw new RuntimeException(e1); | ||||
| @@ -381,8 +389,9 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| throw e; | throw e; | ||||
| } | } | ||||
| } | } | ||||
| } while (++retryTimes < this.maxRetryTimes); | |||||
| } while (retryTimes++ < this.maxRetryTimes); | |||||
| this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); | |||||
| throw new RuntimeException("微信服务端异常,超出重试次数"); | throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||
| } | } | ||||
| @@ -540,4 +549,8 @@ public class WxMpServiceImpl implements WxMpService { | |||||
| return this.templateMsgService; | return this.templateMsgService; | ||||
| } | } | ||||
| @Override | |||||
| public WxMpDeviceService getDeviceService() { | |||||
| return this.deviceService; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,12 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| /** | |||||
| * Created by keungtung on 14/12/2016. | |||||
| */ | |||||
| public abstract class AbstractDeviceBean { | |||||
| public String toJson() { | |||||
| return WxGsonBuilder.create().toJson(this); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,60 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class BaseResp extends AbstractDeviceBean{ | |||||
| @SerializedName("base_info") | |||||
| private BaseInfo baseInfo; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| public Integer getErrCode() { | |||||
| return errCode; | |||||
| } | |||||
| public void setErrCode(Integer errCode) { | |||||
| this.errCode = errCode; | |||||
| } | |||||
| public BaseInfo getBaseInfo() { | |||||
| return baseInfo; | |||||
| } | |||||
| public void setBaseInfo(BaseInfo baseInfo) { | |||||
| this.baseInfo = baseInfo; | |||||
| } | |||||
| public String getErrMsg() { | |||||
| return errMsg; | |||||
| } | |||||
| public void setErrMsg(String errMsg) { | |||||
| this.errMsg = errMsg; | |||||
| } | |||||
| private class BaseInfo { | |||||
| private String device_type; | |||||
| private String device_id; | |||||
| public String getDevice_type() { | |||||
| return device_type; | |||||
| } | |||||
| public void setDevice_type(String device_type) { | |||||
| this.device_type = device_type; | |||||
| } | |||||
| public String getDevice_id() { | |||||
| return device_id; | |||||
| } | |||||
| public void setDevice_id(String device_id) { | |||||
| this.device_id = device_id; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class RespMsg extends AbstractDeviceBean{ | |||||
| @SerializedName("ret_code") | |||||
| private Integer retCode; | |||||
| @SerializedName("error_info") | |||||
| private String errorInfo; | |||||
| public Integer getRetCode() { | |||||
| return retCode; | |||||
| } | |||||
| public void setRetCode(Integer retCode) { | |||||
| this.retCode = retCode; | |||||
| } | |||||
| public String getErrorInfo() { | |||||
| return errorInfo; | |||||
| } | |||||
| public void setErrorInfo(String errorInfo) { | |||||
| this.errorInfo = errorInfo; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,53 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| /** | |||||
| * Created by keungtung on 14/12/2016. | |||||
| */ | |||||
| public class TransMsgResp extends AbstractDeviceBean{ | |||||
| private Integer ret; | |||||
| @SerializedName("ret_info") | |||||
| private String retInfo; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| public static TransMsgResp fromJson(String json) { | |||||
| return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); | |||||
| } | |||||
| public Integer getRet() { | |||||
| return ret; | |||||
| } | |||||
| public void setRet(Integer ret) { | |||||
| this.ret = ret; | |||||
| } | |||||
| public String getRetInfo() { | |||||
| return retInfo; | |||||
| } | |||||
| public void setRetInfo(String retInfo) { | |||||
| this.retInfo = retInfo; | |||||
| } | |||||
| public Integer getErrCode() { | |||||
| return errCode; | |||||
| } | |||||
| public void setErrCode(Integer errCode) { | |||||
| this.errCode = errCode; | |||||
| } | |||||
| public String getErrMsg() { | |||||
| return errMsg; | |||||
| } | |||||
| public void setErrMsg(String errMsg) { | |||||
| this.errMsg = errMsg; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,117 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDevice { | |||||
| private String id; | |||||
| private String mac; | |||||
| @SerializedName("connect_protocol") | |||||
| private String connectProtocol; | |||||
| @SerializedName("auth_key") | |||||
| private String authKey; | |||||
| @SerializedName("close_strategy") | |||||
| private String closeStrategy; | |||||
| @SerializedName("conn_strategy") | |||||
| private String connStrategy; | |||||
| @SerializedName("crypt_method") | |||||
| private String cryptMethod; | |||||
| @SerializedName("auth_ver") | |||||
| private String authVer; | |||||
| @SerializedName("manu_mac_pos") | |||||
| private String manuMacPos; | |||||
| @SerializedName("ser_mac_pos") | |||||
| private String serMacPos; | |||||
| @SerializedName("ble_simple_protocol") | |||||
| private String bleSimpleProtocol; | |||||
| public String getId() { | |||||
| return id; | |||||
| } | |||||
| public void setId(String id) { | |||||
| this.id = id; | |||||
| } | |||||
| public String getMac() { | |||||
| return mac; | |||||
| } | |||||
| public void setMac(String mac) { | |||||
| this.mac = mac; | |||||
| } | |||||
| public String getConnectProtocol() { | |||||
| return connectProtocol; | |||||
| } | |||||
| public void setConnectProtocol(String connectProtocol) { | |||||
| this.connectProtocol = connectProtocol; | |||||
| } | |||||
| public String getAuthKey() { | |||||
| return authKey; | |||||
| } | |||||
| public void setAuthKey(String authKey) { | |||||
| this.authKey = authKey; | |||||
| } | |||||
| public String getCloseStrategy() { | |||||
| return closeStrategy; | |||||
| } | |||||
| public void setCloseStrategy(String closeStrategy) { | |||||
| this.closeStrategy = closeStrategy; | |||||
| } | |||||
| public String getConnStrategy() { | |||||
| return connStrategy; | |||||
| } | |||||
| public void setConnStrategy(String connStrategy) { | |||||
| this.connStrategy = connStrategy; | |||||
| } | |||||
| public String getCryptMethod() { | |||||
| return cryptMethod; | |||||
| } | |||||
| public void setCryptMethod(String cryptMethod) { | |||||
| this.cryptMethod = cryptMethod; | |||||
| } | |||||
| public String getAuthVer() { | |||||
| return authVer; | |||||
| } | |||||
| public void setAuthVer(String authVer) { | |||||
| this.authVer = authVer; | |||||
| } | |||||
| public String getManuMacPos() { | |||||
| return manuMacPos; | |||||
| } | |||||
| public void setManuMacPos(String manuMacPos) { | |||||
| this.manuMacPos = manuMacPos; | |||||
| } | |||||
| public String getSerMacPos() { | |||||
| return serMacPos; | |||||
| } | |||||
| public void setSerMacPos(String serMacPos) { | |||||
| this.serMacPos = serMacPos; | |||||
| } | |||||
| public String getBleSimpleProtocol() { | |||||
| return bleSimpleProtocol; | |||||
| } | |||||
| public void setBleSimpleProtocol(String bleSimpleProtocol) { | |||||
| this.bleSimpleProtocol = bleSimpleProtocol; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,47 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import java.util.Arrays; | |||||
| import java.util.LinkedList; | |||||
| import java.util.List; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceAuthorize extends AbstractDeviceBean { | |||||
| @SerializedName("device_num") | |||||
| private String deviceNum; | |||||
| @SerializedName("op_type") | |||||
| private String opType; | |||||
| @SerializedName("device_list") | |||||
| private List<WxDevice> deviceList = new LinkedList<>(); | |||||
| public String getDeviceNum() { | |||||
| return deviceNum; | |||||
| } | |||||
| public void setDeviceNum(String deviceNum) { | |||||
| this.deviceNum = deviceNum; | |||||
| } | |||||
| public String getOpType() { | |||||
| return opType; | |||||
| } | |||||
| public void setOpType(String opType) { | |||||
| this.opType = opType; | |||||
| } | |||||
| public List<WxDevice> getDeviceList() { | |||||
| return deviceList; | |||||
| } | |||||
| public void setDeviceList(List<WxDevice> deviceList) { | |||||
| this.deviceList = deviceList; | |||||
| } | |||||
| public void addDevice(WxDevice... devices) { | |||||
| this.deviceList.addAll(Arrays.asList(devices)); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import java.util.List; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceAuthorizeResult extends AbstractDeviceBean{ | |||||
| private List<BaseResp> resp; | |||||
| public static WxDeviceAuthorizeResult fromJson(String response) { | |||||
| return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); | |||||
| } | |||||
| public List<BaseResp> getResp() { | |||||
| return resp; | |||||
| } | |||||
| public void setResp(List<BaseResp> resp) { | |||||
| this.resp = resp; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,38 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceBind extends AbstractDeviceBean{ | |||||
| private String ticket; | |||||
| @SerializedName("device_id") | |||||
| private String deviceId; | |||||
| @SerializedName("openid") | |||||
| private String openId; | |||||
| public String getTicket() { | |||||
| return ticket; | |||||
| } | |||||
| public void setTicket(String ticket) { | |||||
| this.ticket = ticket; | |||||
| } | |||||
| public String getDeviceId() { | |||||
| return deviceId; | |||||
| } | |||||
| public void setDeviceId(String deviceId) { | |||||
| this.deviceId = deviceId; | |||||
| } | |||||
| public String getOpenId() { | |||||
| return openId; | |||||
| } | |||||
| public void setOpenId(String openId) { | |||||
| this.openId = openId; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceBindResult extends AbstractDeviceBean{ | |||||
| @SerializedName("base_resp") | |||||
| private BaseResp baseResp; | |||||
| public static WxDeviceBindResult fromJson(String json) { | |||||
| return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); | |||||
| } | |||||
| public BaseResp getBaseResp() { | |||||
| return baseResp; | |||||
| } | |||||
| public void setBaseResp(BaseResp baseResp) { | |||||
| this.baseResp = baseResp; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import me.chanjar.weixin.common.util.ToStringUtils; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceMsg extends AbstractDeviceBean{ | |||||
| @SerializedName("device_type") | |||||
| private String deviceType; | |||||
| @SerializedName("device_id") | |||||
| private String deviceId; | |||||
| @SerializedName("open_id") | |||||
| private String openId; | |||||
| private String content; | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringUtils.toSimpleString(this); | |||||
| } | |||||
| public String getDeviceType() { | |||||
| return deviceType; | |||||
| } | |||||
| public void setDeviceType(String deviceType) { | |||||
| this.deviceType = deviceType; | |||||
| } | |||||
| public String getDeviceId() { | |||||
| return deviceId; | |||||
| } | |||||
| public void setDeviceId(String deviceId) { | |||||
| this.deviceId = deviceId; | |||||
| } | |||||
| public String getOpenId() { | |||||
| return openId; | |||||
| } | |||||
| public void setOpenId(String openId) { | |||||
| this.openId = openId; | |||||
| } | |||||
| public String getContent() { | |||||
| return content; | |||||
| } | |||||
| public void setContent(String content) { | |||||
| this.content = content; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package me.chanjar.weixin.mp.bean.device; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
| /** | |||||
| * Created by keungtung on 10/12/2016. | |||||
| */ | |||||
| public class WxDeviceQrCodeResult extends AbstractDeviceBean{ | |||||
| @SerializedName("deviceid") | |||||
| private String deviceId; | |||||
| @SerializedName("qrticket") | |||||
| private String qrTicket; | |||||
| @SerializedName("devicelicence") | |||||
| private String deviceLicence; | |||||
| @SerializedName("resp_msg") | |||||
| private RespMsg respMsg; | |||||
| public static WxDeviceQrCodeResult fromJson(String json) { | |||||
| return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); | |||||
| } | |||||
| public String getDeviceLicence() { | |||||
| return deviceLicence; | |||||
| } | |||||
| public void setDeviceLicence(String deviceLicence) { | |||||
| this.deviceLicence = deviceLicence; | |||||
| } | |||||
| public RespMsg getRespMsg() { | |||||
| return respMsg; | |||||
| } | |||||
| public void setRespMsg(RespMsg respMsg) { | |||||
| this.respMsg = respMsg; | |||||
| } | |||||
| public String getDeviceId() { | |||||
| return deviceId; | |||||
| } | |||||
| public void setDeviceId(String deviceId) { | |||||
| this.deviceId = deviceId; | |||||
| } | |||||
| public String getQrTicket() { | |||||
| return qrTicket; | |||||
| } | |||||
| public void setQrTicket(String qrTicket) { | |||||
| this.qrTicket = qrTicket; | |||||
| } | |||||
| } | |||||
| @@ -1,17 +1,16 @@ | |||||
| package me.chanjar.weixin.mp.api; | package me.chanjar.weixin.mp.api; | ||||
| import java.util.concurrent.ExecutionException; | |||||
| import java.util.concurrent.ExecutorService; | |||||
| import java.util.concurrent.Executors; | |||||
| import java.util.concurrent.Future; | |||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Test; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
| import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | ||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Test; | |||||
| import java.util.concurrent.ExecutionException; | |||||
| import java.util.concurrent.ExecutorService; | |||||
| import java.util.concurrent.Executors; | |||||
| import java.util.concurrent.Future; | |||||
| @Test | @Test | ||||
| public class WxMpBusyRetryTest { | public class WxMpBusyRetryTest { | ||||
| @@ -24,6 +23,7 @@ public class WxMpBusyRetryTest { | |||||
| protected synchronized <T, E> T executeInternal( | protected synchronized <T, E> T executeInternal( | ||||
| RequestExecutor<T, E> executor, String uri, E data) | RequestExecutor<T, E> executor, String uri, E data) | ||||
| throws WxErrorException { | throws WxErrorException { | ||||
| this.log.info("Executed"); | |||||
| WxError error = new WxError(); | WxError error = new WxError(); | ||||
| error.setErrorCode(-1); | error.setErrorCode(-1); | ||||
| throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
| @@ -32,9 +32,7 @@ public class WxMpBusyRetryTest { | |||||
| service.setMaxRetryTimes(3); | service.setMaxRetryTimes(3); | ||||
| service.setRetrySleepMillis(500); | service.setRetrySleepMillis(500); | ||||
| return new Object[][] { | |||||
| new Object[] { service } | |||||
| }; | |||||
| return new Object[][] { { service } }; | |||||
| } | } | ||||
| @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) | @Test(dataProvider = "getService", expectedExceptions = RuntimeException.class) | ||||
| @@ -0,0 +1,40 @@ | |||||
| package me.chanjar.weixin.mp.api.impl; | |||||
| import com.google.inject.Inject; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.mp.api.ApiTestModule; | |||||
| import me.chanjar.weixin.mp.api.WxMpService; | |||||
| import me.chanjar.weixin.mp.bean.device.WxDeviceQrCodeResult; | |||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Guice; | |||||
| import org.testng.annotations.Test; | |||||
| /** | |||||
| * Created by keungtung on 14/12/2016. | |||||
| */ | |||||
| @Test(groups = "deviceApi") | |||||
| @Guice(modules = ApiTestModule.class) | |||||
| public class WxMpDeviceServiceImplTest { | |||||
| @Inject | |||||
| protected WxMpService wxService; | |||||
| @Test(dataProvider = "productId") | |||||
| public void testGetQrcode(String productId) { | |||||
| try { | |||||
| WxDeviceQrCodeResult result = wxService.getDeviceService().getQrCode(productId); | |||||
| println(result.toJson()); | |||||
| } catch (WxErrorException e) { | |||||
| println(e.getMessage()); | |||||
| } | |||||
| } | |||||
| private void println(String content) { | |||||
| System.out.println(content); | |||||
| } | |||||
| @DataProvider(name = "productId") | |||||
| public Object[][] getProductId() { | |||||
| return new Object[][]{new Object[]{"25639"}}; | |||||
| } | |||||
| } | |||||
| @@ -10,63 +10,63 @@ public class WxMpXmlMessageTest { | |||||
| public void testFromXml() { | public void testFromXml() { | ||||
| String xml = "<xml>" | String xml = "<xml>" | ||||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||||
| + "<CreateTime>1348831860</CreateTime>" | |||||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||||
| + "<Content><![CDATA[this is a test]]></Content>" | |||||
| + "<MsgId>1234567890123456</MsgId>" | |||||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||||
| + "<Format><![CDATA[Format]]></Format>" | |||||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||||
| + "<Location_X>23.134521</Location_X>" | |||||
| + "<Location_Y>113.358803</Location_Y>" | |||||
| + "<Scale>20</Scale>" | |||||
| + "<Label><![CDATA[位置信息]]></Label>" | |||||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||||
| + "<Url><![CDATA[url]]></Url>" | |||||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||||
| + "<Event><![CDATA[subscribe]]></Event>" | |||||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||||
| + "<Latitude>23.137466</Latitude>" | |||||
| + "<Longitude>113.352425</Longitude>" | |||||
| + "<Precision>119.385040</Precision>" | |||||
| + "<ScanCodeInfo>" | |||||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||||
| + "</ScanCodeInfo>" | |||||
| + "<SendPicsInfo>" | |||||
| + " <Count>1</Count>\n" | |||||
| + " <PicList>" | |||||
| + " <item>" | |||||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||||
| + " </item>" | |||||
| + " </PicList>" | |||||
| + "</SendPicsInfo>" | |||||
| + "<SendLocationInfo>" | |||||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||||
| + "</SendLocationInfo>" | |||||
| + "</xml>"; | |||||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||||
| + "<CreateTime>1348831860</CreateTime>" | |||||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||||
| + "<Content><![CDATA[this is a test]]></Content>" | |||||
| + "<MsgId>1234567890123456</MsgId>" | |||||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||||
| + "<Format><![CDATA[Format]]></Format>" | |||||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||||
| + "<Location_X>23.134521</Location_X>" | |||||
| + "<Location_Y>113.358803</Location_Y>" | |||||
| + "<Scale>20</Scale>" | |||||
| + "<Label><![CDATA[位置信息]]></Label>" | |||||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||||
| + "<Url><![CDATA[url]]></Url>" | |||||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||||
| + "<Event><![CDATA[subscribe]]></Event>" | |||||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||||
| + "<Latitude>23.137466</Latitude>" | |||||
| + "<Longitude>113.352425</Longitude>" | |||||
| + "<Precision>119.385040</Precision>" | |||||
| + "<ScanCodeInfo>" | |||||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||||
| + "</ScanCodeInfo>" | |||||
| + "<SendPicsInfo>" | |||||
| + " <Count>1</Count>\n" | |||||
| + " <PicList>" | |||||
| + " <item>" | |||||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||||
| + " </item>" | |||||
| + " </PicList>" | |||||
| + "</SendPicsInfo>" | |||||
| + "<SendLocationInfo>" | |||||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||||
| + "</SendLocationInfo>" | |||||
| + "</xml>"; | |||||
| WxMpXmlMessage wxMessage = WxMpXmlMessage.fromXml(xml); | WxMpXmlMessage wxMessage = WxMpXmlMessage.fromXml(xml); | ||||
| Assert.assertEquals(wxMessage.getToUser(), "toUser"); | Assert.assertEquals(wxMessage.getToUser(), "toUser"); | ||||
| Assert.assertEquals(wxMessage.getFromUser(), "fromUser"); | Assert.assertEquals(wxMessage.getFromUser(), "fromUser"); | ||||
| Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); | |||||
| Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860L)); | |||||
| Assert.assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); | Assert.assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); | ||||
| Assert.assertEquals(wxMessage.getContent(), "this is a test"); | Assert.assertEquals(wxMessage.getContent(), "this is a test"); | ||||
| Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); | |||||
| Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); | |||||
| Assert.assertEquals(wxMessage.getPicUrl(), "this is a url"); | Assert.assertEquals(wxMessage.getPicUrl(), "this is a url"); | ||||
| Assert.assertEquals(wxMessage.getMediaId(), "media_id"); | Assert.assertEquals(wxMessage.getMediaId(), "media_id"); | ||||
| Assert.assertEquals(wxMessage.getFormat(), "Format"); | Assert.assertEquals(wxMessage.getFormat(), "Format"); | ||||
| Assert.assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); | Assert.assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); | ||||
| Assert.assertEquals(wxMessage.getLocationX(), new Double(23.134521d)); | |||||
| Assert.assertEquals(wxMessage.getLocationY(), new Double(113.358803d)); | |||||
| Assert.assertEquals(wxMessage.getScale(), new Double(20)); | |||||
| Assert.assertEquals(wxMessage.getLocationX(), 23.134521d); | |||||
| Assert.assertEquals(wxMessage.getLocationY(), 113.358803d); | |||||
| Assert.assertEquals(wxMessage.getScale(), 20d); | |||||
| Assert.assertEquals(wxMessage.getLabel(), "位置信息"); | Assert.assertEquals(wxMessage.getLabel(), "位置信息"); | ||||
| Assert.assertEquals(wxMessage.getDescription(), "公众平台官网链接"); | Assert.assertEquals(wxMessage.getDescription(), "公众平台官网链接"); | ||||
| Assert.assertEquals(wxMessage.getUrl(), "url"); | Assert.assertEquals(wxMessage.getUrl(), "url"); | ||||
| @@ -74,12 +74,12 @@ public class WxMpXmlMessageTest { | |||||
| Assert.assertEquals(wxMessage.getEvent(), "subscribe"); | Assert.assertEquals(wxMessage.getEvent(), "subscribe"); | ||||
| Assert.assertEquals(wxMessage.getEventKey(), "qrscene_123123"); | Assert.assertEquals(wxMessage.getEventKey(), "qrscene_123123"); | ||||
| Assert.assertEquals(wxMessage.getTicket(), "TICKET"); | Assert.assertEquals(wxMessage.getTicket(), "TICKET"); | ||||
| Assert.assertEquals(wxMessage.getLatitude(), new Double(23.137466)); | |||||
| Assert.assertEquals(wxMessage.getLongitude(), new Double(113.352425)); | |||||
| Assert.assertEquals(wxMessage.getPrecision(), new Double(119.385040)); | |||||
| Assert.assertEquals(wxMessage.getLatitude(), 23.137466); | |||||
| Assert.assertEquals(wxMessage.getLongitude(), 113.352425); | |||||
| Assert.assertEquals(wxMessage.getPrecision(), 119.385040); | |||||
| Assert.assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); | Assert.assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); | ||||
| Assert.assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); | Assert.assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); | ||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); | |||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1L)); | |||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); | Assert.assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); | ||||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); | Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); | ||||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | ||||
| @@ -91,63 +91,63 @@ public class WxMpXmlMessageTest { | |||||
| public void testFromXml2() { | public void testFromXml2() { | ||||
| String xml = "<xml>" | String xml = "<xml>" | ||||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||||
| + "<CreateTime>1348831860</CreateTime>" | |||||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||||
| + "<Content><![CDATA[this is a test]]></Content>" | |||||
| + "<MsgID>1234567890123456</MsgID>" | |||||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||||
| + "<Format><![CDATA[Format]]></Format>" | |||||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||||
| + "<Location_X>23.134521</Location_X>" | |||||
| + "<Location_Y>113.358803</Location_Y>" | |||||
| + "<Scale>20</Scale>" | |||||
| + "<Label><![CDATA[位置信息]]></Label>" | |||||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||||
| + "<Url><![CDATA[url]]></Url>" | |||||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||||
| + "<Event><![CDATA[subscribe]]></Event>" | |||||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||||
| + "<Latitude>23.137466</Latitude>" | |||||
| + "<Longitude>113.352425</Longitude>" | |||||
| + "<Precision>119.385040</Precision>" | |||||
| + "<ScanCodeInfo>" | |||||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||||
| + "</ScanCodeInfo>" | |||||
| + "<SendPicsInfo>" | |||||
| + " <Count>1</Count>\n" | |||||
| + " <PicList>" | |||||
| + " <item>" | |||||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||||
| + " </item>" | |||||
| + " </PicList>" | |||||
| + "</SendPicsInfo>" | |||||
| + "<SendLocationInfo>" | |||||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||||
| + "</SendLocationInfo>" | |||||
| + "</xml>"; | |||||
| + "<ToUserName><![CDATA[toUser]]></ToUserName>" | |||||
| + "<FromUserName><![CDATA[fromUser]]></FromUserName> " | |||||
| + "<CreateTime>1348831860</CreateTime>" | |||||
| + "<MsgType><![CDATA[text]]></MsgType>" | |||||
| + "<Content><![CDATA[this is a test]]></Content>" | |||||
| + "<MsgID>1234567890123456</MsgID>" | |||||
| + "<PicUrl><![CDATA[this is a url]]></PicUrl>" | |||||
| + "<MediaId><![CDATA[media_id]]></MediaId>" | |||||
| + "<Format><![CDATA[Format]]></Format>" | |||||
| + "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>" | |||||
| + "<Location_X>23.134521</Location_X>" | |||||
| + "<Location_Y>113.358803</Location_Y>" | |||||
| + "<Scale>20</Scale>" | |||||
| + "<Label><![CDATA[位置信息]]></Label>" | |||||
| + "<Description><![CDATA[公众平台官网链接]]></Description>" | |||||
| + "<Url><![CDATA[url]]></Url>" | |||||
| + "<Title><![CDATA[公众平台官网链接]]></Title>" | |||||
| + "<Event><![CDATA[subscribe]]></Event>" | |||||
| + "<EventKey><![CDATA[qrscene_123123]]></EventKey>" | |||||
| + "<Ticket><![CDATA[TICKET]]></Ticket>" | |||||
| + "<Latitude>23.137466</Latitude>" | |||||
| + "<Longitude>113.352425</Longitude>" | |||||
| + "<Precision>119.385040</Precision>" | |||||
| + "<ScanCodeInfo>" | |||||
| + " <ScanType><![CDATA[qrcode]]></ScanType>" | |||||
| + " <ScanResult><![CDATA[1]]></ScanResult>" | |||||
| + "</ScanCodeInfo>" | |||||
| + "<SendPicsInfo>" | |||||
| + " <Count>1</Count>\n" | |||||
| + " <PicList>" | |||||
| + " <item>" | |||||
| + " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>" | |||||
| + " </item>" | |||||
| + " </PicList>" | |||||
| + "</SendPicsInfo>" | |||||
| + "<SendLocationInfo>" | |||||
| + " <Location_X><![CDATA[23]]></Location_X>\n" | |||||
| + " <Location_Y><![CDATA[113]]></Location_Y>\n" | |||||
| + " <Scale><![CDATA[15]]></Scale>\n" | |||||
| + " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n" | |||||
| + " <Poiname><![CDATA[wo de poi]]></Poiname>\n" | |||||
| + "</SendLocationInfo>" | |||||
| + "</xml>"; | |||||
| WxMpXmlMessage wxMessage = WxMpXmlMessage.fromXml(xml); | WxMpXmlMessage wxMessage = WxMpXmlMessage.fromXml(xml); | ||||
| Assert.assertEquals(wxMessage.getToUser(), "toUser"); | Assert.assertEquals(wxMessage.getToUser(), "toUser"); | ||||
| Assert.assertEquals(wxMessage.getFromUser(), "fromUser"); | Assert.assertEquals(wxMessage.getFromUser(), "fromUser"); | ||||
| Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); | |||||
| Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860L)); | |||||
| Assert.assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); | Assert.assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); | ||||
| Assert.assertEquals(wxMessage.getContent(), "this is a test"); | Assert.assertEquals(wxMessage.getContent(), "this is a test"); | ||||
| Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); | |||||
| Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); | |||||
| Assert.assertEquals(wxMessage.getPicUrl(), "this is a url"); | Assert.assertEquals(wxMessage.getPicUrl(), "this is a url"); | ||||
| Assert.assertEquals(wxMessage.getMediaId(), "media_id"); | Assert.assertEquals(wxMessage.getMediaId(), "media_id"); | ||||
| Assert.assertEquals(wxMessage.getFormat(), "Format"); | Assert.assertEquals(wxMessage.getFormat(), "Format"); | ||||
| Assert.assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); | Assert.assertEquals(wxMessage.getThumbMediaId(), "thumb_media_id"); | ||||
| Assert.assertEquals(wxMessage.getLocationX(), new Double(23.134521d)); | |||||
| Assert.assertEquals(wxMessage.getLocationY(), new Double(113.358803d)); | |||||
| Assert.assertEquals(wxMessage.getScale(), new Double(20)); | |||||
| Assert.assertEquals(wxMessage.getLocationX(), 23.134521d); | |||||
| Assert.assertEquals(wxMessage.getLocationY(), 113.358803d); | |||||
| Assert.assertEquals(wxMessage.getScale(), 20d); | |||||
| Assert.assertEquals(wxMessage.getLabel(), "位置信息"); | Assert.assertEquals(wxMessage.getLabel(), "位置信息"); | ||||
| Assert.assertEquals(wxMessage.getDescription(), "公众平台官网链接"); | Assert.assertEquals(wxMessage.getDescription(), "公众平台官网链接"); | ||||
| Assert.assertEquals(wxMessage.getUrl(), "url"); | Assert.assertEquals(wxMessage.getUrl(), "url"); | ||||
| @@ -155,12 +155,12 @@ public class WxMpXmlMessageTest { | |||||
| Assert.assertEquals(wxMessage.getEvent(), "subscribe"); | Assert.assertEquals(wxMessage.getEvent(), "subscribe"); | ||||
| Assert.assertEquals(wxMessage.getEventKey(), "qrscene_123123"); | Assert.assertEquals(wxMessage.getEventKey(), "qrscene_123123"); | ||||
| Assert.assertEquals(wxMessage.getTicket(), "TICKET"); | Assert.assertEquals(wxMessage.getTicket(), "TICKET"); | ||||
| Assert.assertEquals(wxMessage.getLatitude(), new Double(23.137466)); | |||||
| Assert.assertEquals(wxMessage.getLongitude(), new Double(113.352425)); | |||||
| Assert.assertEquals(wxMessage.getPrecision(), new Double(119.385040)); | |||||
| Assert.assertEquals(wxMessage.getLatitude(), 23.137466); | |||||
| Assert.assertEquals(wxMessage.getLongitude(), 113.352425); | |||||
| Assert.assertEquals(wxMessage.getPrecision(), 119.385040); | |||||
| Assert.assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); | Assert.assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); | ||||
| Assert.assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); | Assert.assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); | ||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); | |||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1L)); | |||||
| Assert.assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); | Assert.assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); | ||||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); | Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); | ||||
| Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | Assert.assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | ||||