Merge pull request #2 from wechat-group/develop

同步版本
This commit is contained in:
Jonk
2016-09-20 16:38:00 +08:00
committed by GitHub
109 changed files with 2042 additions and 1083 deletions

View File

@@ -8,8 +8,10 @@ import java.util.List;
/**
* 用户分组相关操作接口
* @author Binary Wang
* 分组接口属于老接口,不知道啥时候被替换成用户标签接口
*
*/
@Deprecated
public interface WxMpGroupService {

View File

@@ -1,12 +1,18 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.result.*;
import java.io.File;
import java.util.Date;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
/**
* 客服接口
* 命名采用kefu拼音的原因是
@@ -17,6 +23,14 @@ import java.util.Date;
*/
public interface WxMpKefuService {
/**
* <pre>
* 发送客服消息
* 详情请见: <a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547&token=&lang=zh_CN">发送客服消息</a>
* </pre>
*/
boolean customMessageSend(WxMpCustomMessage message) throws WxErrorException;
//*******************客服管理接口***********************//
/**

View File

@@ -1,18 +1,5 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.InternalSessionManager;
import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.LogExceptionHandler;
import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -20,6 +7,20 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.InternalSessionManager;
import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.LogExceptionHandler;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
/**
* <pre>
* 微信消息路由器通过代码化的配置把来自微信的消息交给handler处理
@@ -155,7 +156,7 @@ public class WxMpMessageRouter {
}
WxMpXmlOutMessage res = null;
final List<Future> futures = new ArrayList<>();
final List<Future<?>> futures = new ArrayList<>();
for (final WxMpMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果
if(rule.isAsync()) {
@@ -179,7 +180,7 @@ public class WxMpMessageRouter {
this.executorService.submit(new Runnable() {
@Override
public void run() {
for (Future future : futures) {
for (Future<?> future : futures) {
try {
future.get();
WxMpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName());

View File

@@ -3,18 +3,25 @@ package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.*;
import java.text.SimpleDateFormat;
import me.chanjar.weixin.mp.bean.WxMpIndustry;
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage;
import me.chanjar.weixin.mp.bean.WxMpMassNews;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage;
import me.chanjar.weixin.mp.bean.WxMpMassVideo;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
/**
* 微信API的Service
*/
public interface WxMpService {
SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
/**
* <pre>
* 验证推送过来的消息的正确性
@@ -74,14 +81,6 @@ public interface WxMpService {
*/
WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
/**
* <pre>
* 发送客服消息
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=发送客服消息
* </pre>
*/
void customMessageSend(WxMpCustomMessage message) throws WxErrorException;
/**
* <pre>
* 上传群发用的图文消息,上传后才能群发图文消息
@@ -152,6 +151,20 @@ public interface WxMpService {
*/
WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException;
/**
* <pre>
* 构造第三方使用网站应用授权登录的url
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN">网站应用微信登录开发指南</a>
* URL格式为https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
* </pre>
*
* @param redirectURI 用户授权完成后的重定向链接无需urlencode, 方法内会进行encode
* @param scope 应用授权作用域,拥有多个作用域用逗号(,分隔网页应用目前仅填写snsapi_login即可
* @param state 非必填用于保持请求和回调的状态授权请求后原样带回给第三方。该参数可用于防止csrf攻击跨站请求伪造攻击建议第三方带上该参数可设置为简单的随机数加session进行校验
* @return url
*/
String buildQrConnectUrl(String redirectURI, String scope, String state);
/**
* <pre>
* 构造oauth2授权的url连接
@@ -314,8 +327,16 @@ public interface WxMpService {
*
* @return WxMpGroupService
*/
WxMpGroupService getGroupService();
/**
* 返回用户标签相关接口的方法实现类,以方便调用个其各种接口
*
* @return WxMpUserTagService
*/
WxMpUserTagService getUserTagService();
/**
* 返回二维码相关接口的方法实现类,以方便调用个其各种接口
*
@@ -343,4 +364,11 @@ public interface WxMpService {
* @return WxMpDataCubeService
*/
WxMpDataCubeService getDataCubeService();
/**
* 返回用户黑名单管理相关接口的方法实现类,以方便调用其各种借口
*
* @return WxMpUserBlackListService
*/
WxMpUserBlacklistService getBlackListService();
}

View File

@@ -0,0 +1,35 @@
package me.chanjar.weixin.mp.api;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult;
import java.util.List;
/**
* @author miller
*/
public interface WxMpUserBlacklistService {
/**
* <pre>
* 获取公众号的黑名单列表
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN
* </pre>
*/
WxMpUserBlacklistGetResult getBlacklist(String nextOpenid) throws WxErrorException;
/**
* <pre>
* 拉黑用户
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN
* </pre>
*/
void pushToBlacklist(List<String> openidList) throws WxErrorException;
/**
* <pre>
* 取消拉黑用户
* 详情请见http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1471422259_pJMWA&token=&lang=zh_CN
* </pre>
*/
void pullFromBlacklist(List<String> openidList) throws WxErrorException;
}

View File

@@ -0,0 +1,58 @@
package me.chanjar.weixin.mp.api;
import java.util.List;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
/**
* 用户标签管理相关接口
* Created by Binary Wang on 2016/9/2.
* @author binarywang(https://github.com/binarywang)
*
*/
public interface WxMpUserTagService {
/**
* <pre>
* 创建标签
* 一个公众号最多可以创建100个标签。
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a>
* 接口url格式 https://api.weixin.qq.com/cgi-bin/tags/create?access_token=ACCESS_TOKEN
* </pre>
*
* @param name 标签名字30个字符以内
*/
WxUserTag tagCreate(String name) throws WxErrorException;
/**
* <pre>
* 获取公众号已创建的标签
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a>
* 接口url格式 https://api.weixin.qq.com/cgi-bin/tags/get?access_token=ACCESS_TOKEN
* </pre>
*
*/
List<WxUserTag> tagGet() throws WxErrorException;
/**
* <pre>
* 编辑标签
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a>
* 接口url格式 https://api.weixin.qq.com/cgi-bin/tags/update?access_token=ACCESS_TOKEN
* </pre>
*
*/
Boolean tagUpdate(Integer id, String name) throws WxErrorException;
/**
* <pre>
* 删除标签
* 详情请见:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837&token=&lang=zh_CN">用户标签管理</a>
* 接口url格式 https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=ACCESS_TOKEN
* </pre>
*
*/
Boolean tagDelete(Integer id) throws WxErrorException;
}

View File

@@ -1,6 +1,5 @@
package me.chanjar.weixin.mp.api.impl;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import org.slf4j.Logger;
@@ -111,16 +110,12 @@ public class WxMpCardServiceImpl implements WxMpCardService {
signParam[optionalSignParam.length] = String.valueOf(timestamp);
signParam[optionalSignParam.length + 1] = nonceStr;
signParam[optionalSignParam.length + 2] = cardApiTicket;
try {
String signature = SHA1.gen(signParam);
WxCardApiSignature cardApiSignature = new WxCardApiSignature();
cardApiSignature.setTimestamp(timestamp);
cardApiSignature.setNonceStr(nonceStr);
cardApiSignature.setSignature(signature);
return cardApiSignature;
} catch (NoSuchAlgorithmException e) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build());
}
String signature = SHA1.gen(signParam);
WxCardApiSignature cardApiSignature = new WxCardApiSignature();
cardApiSignature.setTimestamp(timestamp);
cardApiSignature.setNonceStr(nonceStr);
cardApiSignature.setSignature(signature);
return cardApiSignature;
}
/**

View File

@@ -1,8 +1,15 @@
package me.chanjar.weixin.mp.api.impl;
import java.text.Format;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.time.FastDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpDataCubeService;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -12,12 +19,6 @@ import me.chanjar.weixin.mp.bean.datacube.WxDataCubeInterfaceResult;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeMsgResult;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
/**
* Created by Binary Wang on 2016/8/23.
@@ -27,6 +28,9 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
protected final Logger log = LoggerFactory.getLogger(WxMpDataCubeServiceImpl.class);
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/datacube";
private final Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd");
private WxMpService wxMpService;
public WxMpDataCubeServiceImpl(WxMpService wxMpService) {
@@ -37,104 +41,88 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
public List<WxDataCubeUserSummary> getUserSummary(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getusersummary";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeUserSummary>>() {
}.getType());
return WxDataCubeUserSummary.fromJson(responseContent);
}
@Override
public List<WxDataCubeUserCumulate> getUserCumulate(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getusercumulate";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeUserCumulate>>() {
}.getType());
return WxDataCubeUserCumulate.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleResult> getArticleSummary(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getarticlesummary";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
return WxDataCubeArticleResult.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleTotal> getArticleTotal(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getarticletotal";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleTotal>>() {
}.getType());
return WxDataCubeArticleTotal.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleResult> getUserRead(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getuserread";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
return WxDataCubeArticleResult.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleResult> getUserReadHour(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getuserreadhour";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
return WxDataCubeArticleResult.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleResult> getUserShare(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getusershare";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
return WxDataCubeArticleResult.fromJson(responseContent);
}
@Override
public List<WxDataCubeArticleResult> getUserShareHour(Date beginDate, Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getusersharehour";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
return WxDataCubeArticleResult.fromJson(responseContent);
}
@Override
@@ -142,13 +130,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsg";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -156,13 +142,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsghour";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -170,13 +154,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsgweek";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -184,13 +166,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsgmonth";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -198,13 +178,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsgdist";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -212,13 +190,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsgdistweek";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -226,13 +202,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getupstreammsgdistmonth";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
return WxDataCubeMsgResult.fromJson(responseContent);
}
@Override
@@ -240,13 +214,11 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getinterfacesummary";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeInterfaceResult>>() {
}.getType());
return WxDataCubeInterfaceResult.fromJson(responseContent);
}
@Override
@@ -254,12 +226,10 @@ public class WxMpDataCubeServiceImpl implements WxMpDataCubeService {
Date endDate) throws WxErrorException {
String url = API_URL_PREFIX + "/getinterfacesummaryhour";
JsonObject param = new JsonObject();
param.addProperty("begin_date", WxMpService.SIMPLE_DATE_FORMAT.format(beginDate));
param.addProperty("end_date", WxMpService.SIMPLE_DATE_FORMAT.format(endDate));
param.addProperty("begin_date", this.dateFormat.format(beginDate));
param.addProperty("end_date", this.dateFormat.format(endDate));
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}",url, param, responseContent);
return WxMpGsonBuilder.INSTANCE.create().fromJson(new JsonParser().parse(responseContent).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeInterfaceResult>>() {
}.getType());
return WxDataCubeInterfaceResult.fromJson(responseContent);
}
}

View File

@@ -1,12 +1,9 @@
package me.chanjar.weixin.mp.api.impl;
import java.util.List;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
@@ -16,9 +13,12 @@ import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpGroup;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.util.List;
/**
* Created by Binary Wang on 2016/7/21.
*/
@Deprecated
public class WxMpGroupServiceImpl implements WxMpGroupService {
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/groups";
private WxMpService wxMpService;

View File

@@ -3,15 +3,18 @@ package me.chanjar.weixin.mp.api.impl;
import java.io.File;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
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.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
@@ -27,6 +30,8 @@ import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
*
*/
public class WxMpKefuServiceImpl implements WxMpKefuService {
protected final Logger log = LoggerFactory
.getLogger(WxMpKefuServiceImpl.class);
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/customservice";
private WxMpService wxMpService;
@@ -34,19 +39,31 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
this.wxMpService = wxMpService;
}
@Override
public boolean customMessageSend(WxMpCustomMessage message)
throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
String responseContent = this.wxMpService.post(url, message.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, message.toJson(),
responseContent);
return true;
}
@Override
public WxMpKfList kfList() throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
String responseContent = this.wxMpService
.execute(new SimpleGetRequestExecutor(), url, null);
String url = API_URL_PREFIX + "/getkflist";
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return WxMpKfList.fromJson(responseContent);
}
@Override
public WxMpKfOnlineList kfOnlineList() throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist";
String responseContent = this.wxMpService
.execute(new SimpleGetRequestExecutor(), url, null);
String url = API_URL_PREFIX + "/getonlinekflist";
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return WxMpKfOnlineList.fromJson(responseContent);
}
@@ -54,8 +71,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public boolean kfAccountAdd(WxMpKfAccountRequest request)
throws WxErrorException {
String url = API_URL_PREFIX + "/kfaccount/add";
this.wxMpService.execute(new SimplePostRequestExecutor(), url,
request.toJson());
String responseContent = this.wxMpService.post(url, request.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(),
responseContent);
return true;
}
@@ -63,16 +81,18 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public boolean kfAccountUpdate(WxMpKfAccountRequest request)
throws WxErrorException {
String url = API_URL_PREFIX + "/kfaccount/update";
this.wxMpService.execute(new SimplePostRequestExecutor(), url,
request.toJson());
String responseContent = this.wxMpService.post(url, request.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(),
responseContent);
return true;
}
@Override
public boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException {
String url = API_URL_PREFIX + "/kfaccount/inviteworker";
this.wxMpService.execute(new SimplePostRequestExecutor(), url,
request.toJson());
String responseContent = this.wxMpService.post(url, request.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(),
responseContent);
return true;
}
@@ -80,14 +100,20 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public boolean kfAccountUploadHeadImg(String kfAccount, File imgFile)
throws WxErrorException {
String url = API_URL_PREFIX + "/kfaccount/uploadheadimg?kf_account=" + kfAccount;
this.wxMpService.execute(new MediaUploadRequestExecutor(), url, imgFile);
WxMediaUploadResult responseContent = this.wxMpService
.execute(new MediaUploadRequestExecutor(), url, imgFile);
this.log.debug("\nurl:{}\nparams:{}&file:{}\nresponse:{}", url, kfAccount,
imgFile.getAbsolutePath(),
responseContent);
return true;
}
@Override
public boolean kfAccountDel(String kfAccount) throws WxErrorException {
String url = API_URL_PREFIX + "/kfaccount/del?kf_account=" + kfAccount;
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return true;
}
@@ -96,8 +122,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
throws WxErrorException {
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid);
String url = API_URL_PREFIX + "/kfsession/create";
this.wxMpService.execute(new SimplePostRequestExecutor(), url,
request.toJson());
String responseContent = this.wxMpService.post(url, request.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(),
responseContent);
return true;
}
@@ -106,8 +133,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
throws WxErrorException {
WxMpKfSessionRequest request = new WxMpKfSessionRequest(kfAccount, openid);
String url = API_URL_PREFIX + "/kfsession/close";
this.wxMpService.execute(new SimplePostRequestExecutor(), url,
request.toJson());
String responseContent = this.wxMpService.post(url, request.toJson());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, request.toJson(),
responseContent);
return true;
}
@@ -115,8 +143,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public WxMpKfSessionGetResult kfSessionGet(String openid)
throws WxErrorException {
String url = API_URL_PREFIX + "/kfsession/getsession?openid=" + openid;
String responseContent = this.wxMpService
.execute(new SimpleGetRequestExecutor(), url, null);
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return WxMpKfSessionGetResult.fromJson(responseContent);
}
@@ -124,8 +153,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public WxMpKfSessionList kfSessionList(String kfAccount)
throws WxErrorException {
String url = API_URL_PREFIX + "/kfsession/getsessionlist?kf_account=" + kfAccount;
String responseContent = this.wxMpService
.execute(new SimpleGetRequestExecutor(), url, null);
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return WxMpKfSessionList.fromJson(responseContent);
}
@@ -133,8 +163,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
public WxMpKfSessionWaitCaseList kfSessionGetWaitCase()
throws WxErrorException {
String url = API_URL_PREFIX + "/kfsession/getwaitcase";
String responseContent = this.wxMpService
.execute(new SimpleGetRequestExecutor(), url, null);
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, null,
responseContent);
return WxMpKfSessionWaitCaseList.fromJson(responseContent);
}
@@ -156,7 +187,9 @@ public class WxMpKefuServiceImpl implements WxMpKefuService {
param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大从1开始
param.addProperty("number", number); //number 每次获取条数最多10000条
String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, param.toString());
String responseContent = this.wxMpService.post(url, param.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, param.toString(),
responseContent);
return WxMpKfMsgList.fromJson(responseContent);
}

View File

@@ -12,10 +12,38 @@ import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.*;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.*;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpCardService;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpDataCubeService;
import me.chanjar.weixin.mp.api.WxMpGroupService;
import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import me.chanjar.weixin.mp.api.WxMpUserTagService;
import me.chanjar.weixin.mp.bean.WxMpIndustry;
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage;
import me.chanjar.weixin.mp.bean.WxMpMassNews;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage;
import me.chanjar.weixin.mp.bean.WxMpMassVideo;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -28,7 +56,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
public class WxMpServiceImpl implements WxMpService {
@@ -46,8 +73,8 @@ public class WxMpServiceImpl implements WxMpService {
*/
private final Object globalJsapiTicketRefreshLock = new Object();
private WxMpConfigStorage wxMpConfigStorage;
private WxMpConfigStorage configStorage;
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this);
@@ -58,6 +85,8 @@ public class WxMpServiceImpl implements WxMpService {
private WxMpGroupService groupService = new WxMpGroupServiceImpl(this);
private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this);
private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this);
private WxMpCardService cardService = new WxMpCardServiceImpl(this);
@@ -66,6 +95,8 @@ public class WxMpServiceImpl implements WxMpService {
private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this);
private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this);
private CloseableHttpClient httpClient;
private HttpHost httpProxy;
@@ -79,7 +110,8 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public boolean checkSignature(String timestamp, String nonce, String signature) {
try {
return SHA1.gen(this.wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature);
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce)
.equals(signature);
} catch (Exception e) {
return false;
}
@@ -93,14 +125,14 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
this.wxMpConfigStorage.expireAccessToken();
this.configStorage.expireAccessToken();
}
if (this.wxMpConfigStorage.isAccessTokenExpired()) {
if (this.configStorage.isAccessTokenExpired()) {
synchronized (this.globalAccessTokenRefreshLock) {
if (this.wxMpConfigStorage.isAccessTokenExpired()) {
if (this.configStorage.isAccessTokenExpired()) {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
"&appid=" + this.wxMpConfigStorage.getAppId() +
"&secret=" + this.wxMpConfigStorage.getSecret();
"&appid=" + this.configStorage.getAppId() + "&secret="
+ this.configStorage.getSecret();
try {
HttpGet httpGet = new HttpGet(url);
if (this.httpProxy != null) {
@@ -114,7 +146,8 @@ public class WxMpServiceImpl implements WxMpService {
throw new WxErrorException(error);
}
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
this.wxMpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
this.configStorage.updateAccessToken(accessToken.getAccessToken(),
accessToken.getExpiresIn());
}finally {
httpGet.releaseConnection();
}
@@ -124,7 +157,7 @@ public class WxMpServiceImpl implements WxMpService {
}
}
}
return this.wxMpConfigStorage.getAccessToken();
return this.configStorage.getAccessToken();
}
@Override
@@ -135,23 +168,23 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
this.wxMpConfigStorage.expireJsapiTicket();
this.configStorage.expireJsapiTicket();
}
if (this.wxMpConfigStorage.isJsapiTicketExpired()) {
if (this.configStorage.isJsapiTicketExpired()) {
synchronized (this.globalJsapiTicketRefreshLock) {
if (this.wxMpConfigStorage.isJsapiTicketExpired()) {
if (this.configStorage.isJsapiTicketExpired()) {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
this.wxMpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds);
this.configStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds);
}
}
}
return this.wxMpConfigStorage.getJsapiTicket();
return this.configStorage.getJsapiTicket();
}
@Override
@@ -159,29 +192,15 @@ public class WxMpServiceImpl implements WxMpService {
long timestamp = System.currentTimeMillis() / 1000;
String noncestr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false);
try {
String signature = SHA1.genWithAmple(
"jsapi_ticket=" + jsapiTicket,
"noncestr=" + noncestr,
"timestamp=" + timestamp,
"url=" + url
);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setAppid(this.wxMpConfigStorage.getAppId());
jsapiSignature.setTimestamp(timestamp);
jsapiSignature.setNoncestr(noncestr);
jsapiSignature.setUrl(url);
jsapiSignature.setSignature(signature);
return jsapiSignature;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
@Override
public void customMessageSend(WxMpCustomMessage message) throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
execute(new SimplePostRequestExecutor(), url, message.toJson());
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
"noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setAppid(this.configStorage.getAppId());
jsapiSignature.setTimestamp(timestamp);
jsapiSignature.setNoncestr(noncestr);
jsapiSignature.setUrl(url);
jsapiSignature.setSignature(signature);
return jsapiSignature;
}
@Override
@@ -271,7 +290,7 @@ public class WxMpServiceImpl implements WxMpService {
public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) {
StringBuilder url = new StringBuilder();
url.append("https://open.weixin.qq.com/connect/oauth2/authorize?");
url.append("appid=").append(this.wxMpConfigStorage.getAppId());
url.append("appid=").append(this.configStorage.getAppId());
url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI));
url.append("&response_type=code");
url.append("&scope=").append(scope);
@@ -282,6 +301,23 @@ public class WxMpServiceImpl implements WxMpService {
return url.toString();
}
@Override
public String buildQrConnectUrl(String redirectURI, String scope,
String state) {
StringBuilder url = new StringBuilder();
url.append("https://open.weixin.qq.com/connect/qrconnect?");
url.append("appid=").append(this.configStorage.getAppId());
url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI));
url.append("&response_type=code");
url.append("&scope=").append(scope);
if (state != null) {
url.append("&state=").append(state);
}
url.append("#wechat_redirect");
return url.toString();
}
private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException {
try {
RequestExecutor<String, String> executor = new SimpleGetRequestExecutor();
@@ -296,8 +332,8 @@ public class WxMpServiceImpl implements WxMpService {
public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException {
StringBuilder url = new StringBuilder();
url.append("https://api.weixin.qq.com/sns/oauth2/access_token?");
url.append("appid=").append(this.wxMpConfigStorage.getAppId());
url.append("&secret=").append(this.wxMpConfigStorage.getSecret());
url.append("appid=").append(this.configStorage.getAppId());
url.append("&secret=").append(this.configStorage.getSecret());
url.append("&code=").append(code);
url.append("&grant_type=authorization_code");
@@ -308,7 +344,7 @@ public class WxMpServiceImpl implements WxMpService {
public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException {
StringBuilder url = new StringBuilder();
url.append("https://api.weixin.qq.com/sns/oauth2/refresh_token?");
url.append("appid=").append(this.wxMpConfigStorage.getAppId());
url.append("appid=").append(this.configStorage.getAppId());
url.append("&grant_type=refresh_token");
url.append("&refresh_token=").append(refreshToken);
@@ -428,7 +464,7 @@ public class WxMpServiceImpl implements WxMpService {
*/
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) {
// 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.wxMpConfigStorage.expireAccessToken();
this.configStorage.expireAccessToken();
return execute(executor, uri, data);
}
if (error.getErrorCode() != 0) {
@@ -439,7 +475,7 @@ public class WxMpServiceImpl implements WxMpService {
throw new RuntimeException(e);
}
}
public HttpHost getHttpProxy() {
return this.httpProxy;
}
@@ -450,33 +486,39 @@ public class WxMpServiceImpl implements WxMpService {
@Override
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) {
this.wxMpConfigStorage = wxConfigProvider;
this.configStorage = wxConfigProvider;
this.initHttpClient();
}
private void initHttpClient() {
ApacheHttpClientBuilder apacheHttpClientBuilder = this.wxMpConfigStorage.getApacheHttpClientBuilder();
ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage
.getApacheHttpClientBuilder();
if (null == apacheHttpClientBuilder) {
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
}
apacheHttpClientBuilder.httpProxyHost(this.wxMpConfigStorage.getHttpProxyHost())
.httpProxyPort(this.wxMpConfigStorage.getHttpProxyPort())
.httpProxyUsername(this.wxMpConfigStorage.getHttpProxyUsername())
.httpProxyPassword(this.wxMpConfigStorage.getHttpProxyPassword());
if (this.wxMpConfigStorage.getSSLContext() != null){
apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost())
.httpProxyPort(this.configStorage.getHttpProxyPort())
.httpProxyUsername(this.configStorage.getHttpProxyUsername())
.httpProxyPassword(this.configStorage.getHttpProxyPassword());
if (this.configStorage.getSSLContext() != null) {
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
this.wxMpConfigStorage.getSSLContext(), new String[] { "TLSv1" }, null, new DefaultHostnameVerifier());
this.configStorage.getSSLContext(), new String[] { "TLSv1" }, null,
new DefaultHostnameVerifier());
apacheHttpClientBuilder.sslConnectionSocketFactory(sslsf);
}
if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort());
}
this.httpClient = apacheHttpClientBuilder.build();
}
@Override
public WxMpConfigStorage getWxMpConfigStorage() {
return this.wxMpConfigStorage;
return this.configStorage;
}
@Override
@@ -514,6 +556,11 @@ public class WxMpServiceImpl implements WxMpService {
return this.groupService;
}
@Override
public WxMpUserTagService getUserTagService() {
return this.tagService;
}
@Override
public WxMpQrcodeService getQrcodeService() {
return this.qrCodeService;
@@ -534,4 +581,9 @@ public class WxMpServiceImpl implements WxMpService {
return this.dataCubeService;
}
@Override
public WxMpUserBlacklistService getBlackListService() {
return this.blackListService;
}
}

View File

@@ -0,0 +1,50 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService;
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author miller
*/
public class WxMpUserBlacklistServiceImpl implements WxMpUserBlacklistService {
private static final String API_BLACKLIST_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags/members";
private WxMpService wxMpService;
public WxMpUserBlacklistServiceImpl(WxMpService wxMpService) {
this.wxMpService = wxMpService;
}
@Override
public WxMpUserBlacklistGetResult getBlacklist(String nextOpenid) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("begin_openid", nextOpenid);
String url = API_BLACKLIST_PREFIX + "/getblacklist";
String responseContent = this.wxMpService.execute(new SimplePostRequestExecutor(), url, jsonObject.toString());
return WxMpUserBlacklistGetResult.fromJson(responseContent);
}
@Override
public void pushToBlacklist(List<String> openidList) throws WxErrorException {
Map<String, Object> map = new HashMap<>();
map.put("openid_list", openidList);
String url = API_BLACKLIST_PREFIX + "/batchblacklist";
this.wxMpService.execute(new SimplePostRequestExecutor(), url, new Gson().toJson(map));
}
@Override
public void pullFromBlacklist(List<String> openidList) throws WxErrorException {
Map<String, Object> map = new HashMap<>();
map.put("openid_list", openidList);
String url = API_BLACKLIST_PREFIX + "/batchunblacklist";
this.wxMpService.execute(new SimplePostRequestExecutor(), url, new Gson().toJson(map));
}
}

View File

@@ -0,0 +1,95 @@
package me.chanjar.weixin.mp.api.impl;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpUserTagService;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
/**
*
* @author binarywang(https://github.com/binarywang)
* Created by Binary Wang on 2016/9/2.
*/
public class WxMpUserTagServiceImpl implements WxMpUserTagService {
protected final Logger log = LoggerFactory
.getLogger(WxMpDataCubeServiceImpl.class);
private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags";
private WxMpService wxMpService;
public WxMpUserTagServiceImpl(WxMpService wxMpService) {
this.wxMpService = wxMpService;
}
@Override
public WxUserTag tagCreate(String name) throws WxErrorException {
String url = API_URL_PREFIX + "/create";
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("name", name);
json.add("tag", tagJson);
String responseContent = this.wxMpService.post(url, json.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(),
responseContent);
return WxUserTag.fromJson(responseContent);
}
@Override
public List<WxUserTag> tagGet() throws WxErrorException {
String url = API_URL_PREFIX + "/get";
String responseContent = this.wxMpService.get(url, null);
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, "[empty]",
responseContent);
return WxUserTag.listFromJson(responseContent);
}
@Override
public Boolean tagUpdate(Integer id, String name) throws WxErrorException {
String url = API_URL_PREFIX + "/update";
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("id", id);
tagJson.addProperty("name", name);
json.add("tag", tagJson);
String responseContent = this.wxMpService.post(url, json.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(), responseContent);
WxError wxError = WxError.fromJson(responseContent);
if (wxError.getErrorCode() == 0) {
return true;
}
throw new WxErrorException(wxError);
}
@Override
public Boolean tagDelete(Integer id) throws WxErrorException {
String url = API_URL_PREFIX + "/delete";
JsonObject json = new JsonObject();
JsonObject tagJson = new JsonObject();
tagJson.addProperty("id", id);
json.add("tag", tagJson);
String responseContent = this.wxMpService.post(url, json.toString());
this.log.debug("\nurl:{}\nparams:{}\nresponse:{}", url, json.toString(),
responseContent);
WxError wxError = WxError.fromJson(responseContent);
if (wxError.getErrorCode() == 0) {
return true;
}
throw new WxErrorException(wxError);
}
}

View File

@@ -6,8 +6,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import me.chanjar.weixin.mp.util.json.WxLongTimeJsonSerializer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@@ -49,7 +47,6 @@ public class WxMpXmlMessage implements Serializable {
private String fromUserName;
@XStreamAlias("CreateTime")
@JsonSerialize(using = WxLongTimeJsonSerializer.class)
private Long createTime;
@XStreamAlias("MsgType")

View File

@@ -1,6 +1,12 @@
package me.chanjar.weixin.mp.bean.datacube;
import java.util.List;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* 图文分析数据接口返回结果对象
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName;
*/
public class WxDataCubeArticleResult extends WxDataCubeBaseResult {
private static final JsonParser JSON_PARSER = new JsonParser();
/**
* ref_hour
* 数据的小时包括从000到2300分别代表的是[000,100)到[2300,2400)即每日的第1小时和最后1小时
@@ -203,5 +211,11 @@ public class WxDataCubeArticleResult extends WxDataCubeBaseResult {
public void setUserSource(Integer userSource) {
this.userSource = userSource;
}
public static List<WxDataCubeArticleResult> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleResult>>() {
}.getType());
}
}

View File

@@ -1,9 +1,13 @@
package me.chanjar.weixin.mp.bean.datacube;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* 图文分析数据接口返回结果对象
* @author binarywang(https://github.com/binarywang)
@@ -11,6 +15,8 @@ import java.util.List;
*/
public class WxDataCubeArticleTotal extends WxDataCubeBaseResult {
private static final JsonParser JSON_PARSER = new JsonParser();
/**
* msgid
* 请注意这里的msgid实际上是由msgid图文消息id这也就是群发接口调用后返回的msg_data_id和index消息次序索引组成 例如12003_3 其中12003是msgid即一次群发的消息的id 3为index假设该次群发的图文消息共5个文章因为可能为多图文3表示5个中的第3个
@@ -55,5 +61,11 @@ public class WxDataCubeArticleTotal extends WxDataCubeBaseResult {
public void setDetails(List<WxDataCubeArticleTotalDetail> details) {
this.details = details;
}
public static List<WxDataCubeArticleTotal> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeArticleTotal>>() {
}.getType());
}
}

View File

@@ -1,6 +1,12 @@
package me.chanjar.weixin.mp.bean.datacube;
import java.util.List;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* 接口分析数据接口返回结果对象
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName;
*/
public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult {
private static final JsonParser JSON_PARSER = new JsonParser();
/**
* ref_hour
* 数据的小时包括从000到2300分别代表的是[000,100)到[2300,2400)即每日的第1小时和最后1小时
@@ -83,5 +91,12 @@ public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult {
public void setMaxTimeCost(Integer maxTimeCost) {
this.maxTimeCost = maxTimeCost;
}
public static List<WxDataCubeInterfaceResult> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeInterfaceResult>>() {
}.getType());
}
}

View File

@@ -1,6 +1,12 @@
package me.chanjar.weixin.mp.bean.datacube;
import java.util.List;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* 消息分析数据接口返回结果对象
@@ -9,6 +15,8 @@ import com.google.gson.annotations.SerializedName;
*/
public class WxDataCubeMsgResult extends WxDataCubeBaseResult {
private static final JsonParser JSON_PARSER = new JsonParser();
/**
* ref_hour
* 数据的小时包括从000到2300分别代表的是[000,100)到[2300,2400)即每日的第1小时和最后1小时
@@ -114,4 +122,11 @@ public class WxDataCubeMsgResult extends WxDataCubeBaseResult {
this.oriPageReadUser = oriPageReadUser;
}
public static List<WxDataCubeMsgResult> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeMsgResult>>() {
}.getType());
}
}

View File

@@ -1,19 +1,27 @@
package me.chanjar.weixin.mp.bean.datacube;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.util.Date;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* <pre>
* 累计用户数据接口的返回JSON数据包
* http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
* 详情查看文档:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN">用户分析数据接口</a>
* </pre>
*/
public class WxDataCubeUserCumulate implements Serializable {
private static final JsonParser JSON_PARSER = new JsonParser();
private static final long serialVersionUID = -3570981300225093657L;
private Date refDate;
@@ -40,4 +48,11 @@ public class WxDataCubeUserCumulate implements Serializable {
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
public static List<WxDataCubeUserCumulate> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeUserCumulate>>() {
}.getType());
}
}

View File

@@ -1,20 +1,28 @@
package me.chanjar.weixin.mp.bean.datacube;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.util.Date;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* <pre>
* 用户增减数据接口的返回JSON数据包
* http://mp.weixin.qq.com/wiki/3/ecfed6e1a0a03b5f35e5efac98e864b7.html
* 详情查看文档:<a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141082&token=&lang=zh_CN">用户分析数据接口</a>
* </pre>
*/
public class WxDataCubeUserSummary implements Serializable {
private static final long serialVersionUID = -2336654489906694173L;
private static final JsonParser JSON_PARSER = new JsonParser();
private Date refDate;
private Integer userSource;
@@ -59,4 +67,11 @@ public class WxDataCubeUserSummary implements Serializable {
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
public static List<WxDataCubeUserSummary> fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(
JSON_PARSER.parse(json).getAsJsonObject().get("list"),
new TypeToken<List<WxDataCubeUserSummary>>() {
}.getType());
}
}

View File

@@ -1,11 +1,10 @@
package me.chanjar.weixin.mp.bean.kefu.result;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.gson.annotations.SerializedName;
import me.chanjar.weixin.mp.util.json.WxLongTimeJsonSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.google.gson.annotations.SerializedName;
/**
* Created by Binary Wang on 2016/7/18.
*/
@@ -38,7 +37,6 @@ public class WxMpKfMsgRecord {
* time 操作时间unix时间戳
*/
@SerializedName("time")
@JsonSerialize(using = WxLongTimeJsonSerializer.class)
private Long time;
@Override

View File

@@ -0,0 +1,57 @@
package me.chanjar.weixin.mp.bean.result;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
import java.util.ArrayList;
import java.util.List;
/**
* @author miller
*/
public class WxMpUserBlacklistGetResult {
protected int total = -1;
protected int count = -1;
protected List<String> openidList = new ArrayList<>();
protected String nextOpenid;
public static WxMpUserBlacklistGetResult fromJson(String json) {
return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserBlacklistGetResult.class);
}
public int getTotal() {
return this.total;
}
public void setTotal(int total) {
this.total = total;
}
public int getCount() {
return this.count;
}
public void setCount(int count) {
this.count = count;
}
public List<String> getOpenidList() {
return this.openidList;
}
public void setOpenidList(List<String> openidList) {
this.openidList = openidList;
}
public String getNextOpenid() {
return this.nextOpenid;
}
public void setNextOpenid(String nextOpenid) {
this.nextOpenid = nextOpenid;
}
@Override
public String toString() {
return WxMpGsonBuilder.INSTANCE.create().toJson(this);
}
}

View File

@@ -0,0 +1,78 @@
package me.chanjar.weixin.mp.bean.tag;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
/**
* 用户标签对象
* @author binarywang(https://github.com/binarywang)
* Created by Binary Wang on 2016/9/2.
*/
public class WxUserTag {
/**
* id 标签id由微信分配
*/
private Integer id;
/**
* name 标签名UTF8编码
*/
private String name;
/**
* count 此标签下粉丝数
*/
private Integer count;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return this.count;
}
public void setCount(Integer count) {
this.count = count;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public static WxUserTag fromJson(String json) {
return WxMpGsonBuilder.create().fromJson(
new JsonParser().parse(json).getAsJsonObject().get("tag"),
WxUserTag.class);
}
public static List<WxUserTag> listFromJson(String json) {
return WxMpGsonBuilder.create().fromJson(
new JsonParser().parse(json).getAsJsonObject().get("tags"),
new TypeToken<List<WxUserTag>>(){}.getType());
}
public String toJson() {
return WxMpGsonBuilder.create().toJson(this);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}
}

View File

@@ -1,23 +0,0 @@
package me.chanjar.weixin.mp.util.json;
import java.io.IOException;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Created by Binary Wang on 2016/7/13.
*/
public class WxLongTimeJsonSerializer extends JsonSerializer<Long> {
private static SimpleDateFormat DF = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
@Override
public void serialize(Long value, JsonGenerator gen,
SerializerProvider serializers)
throws IOException {
gen.writeString(DF.format(value * 1000));
}
}

View File

@@ -45,6 +45,7 @@ public class WxMpGsonBuilder {
INSTANCE.registerTypeAdapter(WxMpMassPreviewMessage.class, new WxMpMassPreviewMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMediaImgUploadResult.class, new WxMediaImgUploadResultGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpIndustry.class, new WxMpIndustryGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter());
}
public static Gson create() {

View File

@@ -1,5 +1,7 @@
package me.chanjar.weixin.mp.util.json;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@@ -7,38 +9,43 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.Industry;
import me.chanjar.weixin.mp.bean.WxMpIndustry;
import java.lang.reflect.Type;
/**
* @author miller
*/
public class WxMpIndustryGsonAdapter implements JsonSerializer<WxMpIndustry>, JsonDeserializer<WxMpIndustry> {
@Override
public JsonElement serialize(WxMpIndustry wxMpIndustry, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject json = new JsonObject();
json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getId());
json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getId());
return json;
}
public class WxMpIndustryGsonAdapter
implements JsonSerializer<WxMpIndustry>, JsonDeserializer<WxMpIndustry> {
@Override
public JsonElement serialize(WxMpIndustry wxMpIndustry, Type type,
JsonSerializationContext jsonSerializationContext) {
JsonObject json = new JsonObject();
json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getId());
json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getId());
return json;
}
@Override
public WxMpIndustry deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
WxMpIndustry wxMpIndustry = new WxMpIndustry();
JsonObject primaryIndustry = jsonElement.getAsJsonObject().get("primary_industry").getAsJsonObject();
wxMpIndustry.setPrimaryIndustry(convertFromJson(primaryIndustry));
JsonObject secondaryIndustry = jsonElement.getAsJsonObject().get("secondary_industry").getAsJsonObject();
wxMpIndustry.setSecondIndustry(convertFromJson(secondaryIndustry));
return wxMpIndustry;
}
@Override
public WxMpIndustry deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException {
WxMpIndustry wxMpIndustry = new WxMpIndustry();
JsonObject primaryIndustry = jsonElement.getAsJsonObject()
.get("primary_industry").getAsJsonObject();
wxMpIndustry.setPrimaryIndustry(convertFromJson(primaryIndustry));
JsonObject secondaryIndustry = jsonElement.getAsJsonObject()
.get("secondary_industry").getAsJsonObject();
wxMpIndustry.setSecondIndustry(convertFromJson(secondaryIndustry));
return wxMpIndustry;
}
private Industry convertFromJson(JsonObject json) {
Industry industry = new Industry();
industry.setFirstClass(GsonHelper.getString(json, "first_class"));
industry.setSecondClass(GsonHelper.getString(json, "second_class"));
return industry;
}
private static Industry convertFromJson(JsonObject json) {
Industry industry = new Industry();
industry.setFirstClass(GsonHelper.getString(json, "first_class"));
industry.setSecondClass(GsonHelper.getString(json, "second_class"));
return industry;
}
}

View File

@@ -8,13 +8,19 @@
*/
package me.chanjar.weixin.mp.util.json;
import com.google.gson.*;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.commons.lang3.time.FastDateFormat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate;
/**
*
@@ -23,7 +29,8 @@ import java.text.SimpleDateFormat;
*/
public class WxMpUserCumulateGsonAdapter implements JsonDeserializer<WxDataCubeUserCumulate> {
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private static final FastDateFormat DATE_FORMAT = FastDateFormat
.getInstance("yyyy-MM-dd");
@Override
public WxDataCubeUserCumulate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
@@ -33,7 +40,7 @@ public class WxMpUserCumulateGsonAdapter implements JsonDeserializer<WxDataCubeU
try {
String refDate = GsonHelper.getString(summaryJsonObject, "ref_date");
if (refDate != null) {
cumulate.setRefDate(SIMPLE_DATE_FORMAT.parse(refDate));
cumulate.setRefDate(DATE_FORMAT.parse(refDate));
}
cumulate.setCumulateUser(GsonHelper.getInteger(summaryJsonObject, "cumulate_user"));
} catch (ParseException e) {

View File

@@ -8,20 +8,27 @@
*/
package me.chanjar.weixin.mp.util.json;
import com.google.gson.*;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.commons.lang3.time.FastDateFormat;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary;
/**
* @author Daniel Qian
*/
public class WxMpUserSummaryGsonAdapter implements JsonDeserializer<WxDataCubeUserSummary> {
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private static final FastDateFormat DATE_FORMAT = FastDateFormat
.getInstance("yyyy-MM-dd");
@Override
public WxDataCubeUserSummary deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
@@ -32,7 +39,7 @@ public class WxMpUserSummaryGsonAdapter implements JsonDeserializer<WxDataCubeUs
try {
String refDate = GsonHelper.getString(summaryJsonObject, "ref_date");
if (refDate != null) {
summary.setRefDate(SIMPLE_DATE_FORMAT.parse(refDate));
summary.setRefDate(DATE_FORMAT.parse(refDate));
}
summary.setUserSource(GsonHelper.getInteger(summaryJsonObject, "user_source"));
summary.setNewUser(GsonHelper.getInteger(summaryJsonObject, "new_user"));

View File

@@ -0,0 +1,28 @@
package me.chanjar.weixin.mp.util.json;
import com.google.gson.*;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult;
import java.lang.reflect.Type;
/**
* @author miller
*/
public class WxUserBlacklistGetResultGsonAdapter implements JsonDeserializer<WxMpUserBlacklistGetResult> {
@Override
public WxMpUserBlacklistGetResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject o = json.getAsJsonObject();
WxMpUserBlacklistGetResult wxMpUserBlacklistGetResult = new WxMpUserBlacklistGetResult();
wxMpUserBlacklistGetResult.setTotal(GsonHelper.getInteger(o, "total"));
wxMpUserBlacklistGetResult.setCount(GsonHelper.getInteger(o, "count"));
wxMpUserBlacklistGetResult.setNextOpenid(GsonHelper.getString(o, "next_openid"));
if (o.get("data") != null && !o.get("data").isJsonNull() && !o.get("data").getAsJsonObject().get("openid").isJsonNull()) {
JsonArray data = o.get("data").getAsJsonObject().get("openid").getAsJsonArray();
for (int i = 0; i < data.size(); i++) {
wxMpUserBlacklistGetResult.getOpenidList().add(GsonHelper.getAsString(data.get(i)));
}
}
return wxMpUserBlacklistGetResult;
}
}

View File

@@ -1,16 +1,25 @@
package me.chanjar.weixin.mp.util.xml;
import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.bean.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutImageMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMusicMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutTransferCustomerServiceMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutVideoMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutVoiceMessage;
public class XStreamTransformer {
protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
protected static final Map<Class<?>, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
/**
* xml -> pojo
@@ -32,7 +41,7 @@ public class XStreamTransformer {
* @param clz 类型
* @param xStream xml解析器
*/
public static void register(Class clz,XStream xStream){
public static void register(Class<?> clz, XStream xStream) {
CLASS_2_XSTREAM_INSTANCE.put(clz,xStream);
}
@@ -44,8 +53,8 @@ public class XStreamTransformer {
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
}
private static Map<Class, XStream> configXStreamInstance() {
Map<Class, XStream> map = new HashMap<>();
private static Map<Class<?>, XStream> configXStreamInstance() {
Map<Class<?>, XStream> map = new HashMap<>();
map.put(WxMpXmlMessage.class, config_WxMpXmlMessage());
map.put(WxMpXmlOutMusicMessage.class, config_WxMpXmlOutMusicMessage());
map.put(WxMpXmlOutNewsMessage.class, config_WxMpXmlOutNewsMessage());

View File

@@ -31,6 +31,7 @@ public class ApiTestModule implements Module {
}
}
@SuppressWarnings("unchecked")
public static <T> T fromXml(Class<T> clazz, InputStream is) {
XStream xstream = XStreamInitializer.getInstance();
xstream.alias("xml", clazz);
@@ -42,15 +43,16 @@ public class ApiTestModule implements Module {
public static class WxXmlMpInMemoryConfigStorage
extends WxMpInMemoryConfigStorage {
private String openId;
private String openid;
private String kfAccount;
private String qrconnectRedirectUrl;
public String getOpenId() {
return this.openId;
public String getOpenid() {
return this.openid;
}
public void setOpenId(String openId) {
this.openId = openId;
public void setOpenid(String openid) {
this.openid = openid;
}
@Override
@@ -66,6 +68,14 @@ public class ApiTestModule implements Module {
this.kfAccount = kfAccount;
}
public String getQrconnectRedirectUrl() {
return this.qrconnectRedirectUrl;
}
public void setQrconnectRedirectUrl(String qrconnectRedirectUrl) {
this.qrconnectRedirectUrl = qrconnectRedirectUrl;
}
}
}

View File

@@ -1,17 +1,18 @@
package me.chanjar.weixin.mp.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 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;
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;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
@Test
public class WxMpBusyRetryTest {
@@ -20,7 +21,9 @@ public class WxMpBusyRetryTest {
WxMpService service = new WxMpServiceImpl() {
@Override
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
protected synchronized <T, E> T executeInternal(
RequestExecutor<T, E> executor, String uri, E data)
throws WxErrorException {
WxError error = new WxError();
error.setErrorCode(-1);
throw new WxErrorException(error);

View File

@@ -1,44 +0,0 @@
package me.chanjar.weixin.mp.api;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
/***
* 测试发送客服消息
* @author chanjarster
*
*/
@Test(groups="customMessageAPI")
@Guice(modules = ApiTestModule.class)
public class WxMpCustomMessageAPITest {
@Inject
protected WxMpServiceImpl wxService;
public void testSendCustomMessage() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
WxMpCustomMessage message = new WxMpCustomMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setToUser(configStorage.getOpenId());
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
this.wxService.customMessageSend(message);
}
public void testSendCustomMessageWithKfAccount() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
WxMpCustomMessage message = new WxMpCustomMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setToUser(configStorage.getOpenId());
message.setKfAccount(configStorage.getKfAccount());
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
this.wxService.customMessageSend(message);
}
}

View File

@@ -1,14 +1,14 @@
package me.chanjar.weixin.mp.api;
import com.google.inject.Inject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import java.security.NoSuchAlgorithmException;
import com.google.inject.Inject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
/**
* 测试jsapi ticket接口
@@ -29,7 +29,7 @@ public class WxMpJsAPITest {
Assert.assertNotNull(jsapiTicket);
}
public void test() throws NoSuchAlgorithmException {
public void test() {
long timestamp = 1419835025l;
String url = "http://omstest.vmall.com:23568/thirdparty/wechat/vcode/gotoshare?quantity=1&batchName=MATE7";
String noncestr = "82693e11-b9bc-448e-892f-f5289f46cd0f";

View File

@@ -41,7 +41,7 @@ public class WxMpMassMessageAPITest {
WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage();
massMessage.setMsgType(WxConsts.MASS_MSG_TEXT);
massMessage.setContent("测试群发消息\n欢迎欢迎热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
massMessage.getToUsers().add(configProvider.getOpenId());
massMessage.getToUsers().add(configProvider.getOpenid());
WxMpMassSendResult massResult = this.wxService
.massOpenIdsMessageSend(massMessage);
@@ -58,7 +58,7 @@ public class WxMpMassMessageAPITest {
WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage();
massMessage.setMsgType(massMsgType);
massMessage.setMediaId(mediaId);
massMessage.getToUsers().add(configProvider.getOpenId());
massMessage.getToUsers().add(configProvider.getOpenid());
WxMpMassSendResult massResult = this.wxService
.massOpenIdsMessageSend(massMessage);
@@ -73,13 +73,13 @@ public class WxMpMassMessageAPITest {
massMessage.setContent("测试群发消息\n欢迎欢迎热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
massMessage
.setGroupId(this.wxService.getGroupService().groupGet().get(0).getId());
WxMpMassSendResult massResult = this.wxService
.massGroupMessageSend(massMessage);
Assert.assertNotNull(massResult);
Assert.assertNotNull(massResult.getMsgId());
}
@Test(dataProvider="massMessages")
public void testMediaMassGroupMessageSend(String massMsgType, String mediaId)
throws WxErrorException {
@@ -94,7 +94,7 @@ public class WxMpMassMessageAPITest {
Assert.assertNotNull(massResult);
Assert.assertNotNull(massResult.getMsgId());
}
@DataProvider
public Object[][] massMessages() throws WxErrorException, IOException {
Object[][] messages = new Object[4][];
@@ -109,7 +109,7 @@ public class WxMpMassMessageAPITest {
.mediaUpload(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream);
Assert.assertNotNull(uploadMediaRes);
Assert.assertNotNull(uploadMediaRes.getMediaId());
// 把视频变成可被群发的媒体
WxMpMassVideo video = new WxMpMassVideo();
video.setTitle("测试标题");
@@ -155,7 +155,7 @@ public class WxMpMassMessageAPITest {
.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream);
Assert.assertNotNull(uploadMediaRes);
Assert.assertNotNull(uploadMediaRes.getMediaId());
// 上传图文消息
WxMpMassNews news = new WxMpMassNews();
WxMpMassNews.WxMpMassNewsArticle article1 = new WxMpMassNews.WxMpMassNewsArticle();
@@ -163,7 +163,7 @@ public class WxMpMassMessageAPITest {
article1.setContent("内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1");
article1.setThumbMediaId(uploadMediaRes.getMediaId());
news.addArticle(article1);
WxMpMassNews.WxMpMassNewsArticle article2 = new WxMpMassNews.WxMpMassNewsArticle();
article2.setTitle("标题2");
article2.setContent("内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2");
@@ -173,7 +173,7 @@ public class WxMpMassMessageAPITest {
article2.setContentSourceUrl("www.baidu.com");
article2.setDigest("摘要2");
news.addArticle(article2);
WxMpMassUploadResult massUploadResult = this.wxService
.massNewsUpload(news);
Assert.assertNotNull(massUploadResult);
@@ -183,5 +183,5 @@ public class WxMpMassMessageAPITest {
return messages;
}
}

View File

@@ -1,10 +1,10 @@
package me.chanjar.weixin.mp.api.impl;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.time.FastDateFormat;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
@@ -28,39 +28,39 @@ import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary;
*/
@Guice(modules = ApiTestModule.class)
public class WxMpDataCubeServiceImplTest {
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd");
private FastDateFormat simpleDateFormat = FastDateFormat
.getInstance("yyyy-MM-dd");
@Inject
protected WxMpServiceImpl wxService;
@DataProvider
public Object[][] oneDay() throws ParseException {
return new Object[][] { { simpleDateFormat.parse("2016-08-22") } };
return new Object[][] { { this.simpleDateFormat.parse("2016-08-22") } };
}
@DataProvider
public Object[][] threeDays() throws ParseException {
return new Object[][] { { simpleDateFormat.parse("2016-08-20"),
simpleDateFormat.parse("2016-08-22") } };
return new Object[][] { { this.simpleDateFormat.parse("2016-08-20"),
this.simpleDateFormat.parse("2016-08-22") } };
}
@DataProvider
public Object[][] sevenDays() throws ParseException {
return new Object[][] { { simpleDateFormat.parse("2016-08-16"),
simpleDateFormat.parse("2016-08-22") } };
return new Object[][] { { this.simpleDateFormat.parse("2016-08-16"),
this.simpleDateFormat.parse("2016-08-22") } };
}
@DataProvider
public Object[][] fifteenDays() throws ParseException {
return new Object[][] { { simpleDateFormat.parse("2016-08-14"),
simpleDateFormat.parse("2016-08-27") } };
return new Object[][] { { this.simpleDateFormat.parse("2016-08-14"),
this.simpleDateFormat.parse("2016-08-27") } };
}
@DataProvider
public Object[][] thirtyDays() throws ParseException {
return new Object[][] { { simpleDateFormat.parse("2016-07-30"),
simpleDateFormat.parse("2016-08-27") } };
return new Object[][] { { this.simpleDateFormat.parse("2016-07-30"),
this.simpleDateFormat.parse("2016-08-27") } };
}
@Test(dataProvider = "sevenDays")

View File

@@ -12,9 +12,10 @@ import java.util.List;
/**
* 测试分组接口
*
*
* @author chanjarster
*/
@Deprecated
@Test(groups = "groupAPI")
@Guice(modules = ApiTestModule.class)
public class WxMpGroupServiceImplTest {
@@ -23,7 +24,7 @@ public class WxMpGroupServiceImplTest {
protected WxMpServiceImpl wxService;
protected WxMpGroup group;
public void testGroupCreate() throws WxErrorException {
WxMpGroup res = this.wxService.getGroupService().groupCreate("测试分组1");
Assert.assertEquals(res.getName(), "测试分组1");
@@ -39,11 +40,22 @@ public class WxMpGroupServiceImplTest {
Assert.assertNotNull(g.getName());
}
}
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"})
public void getGroupUpdate() throws WxErrorException {
this.group.setName("分组改名");
this.wxService.getGroupService().groupUpdate(this.group);
}
public void testGroupQueryUserGroup() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
long groupid = this.wxService.getGroupService().userGetGroup(configStorage.getOpenid());
Assert.assertTrue(groupid != -1l);
}
public void testGroupMoveUser() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
this.wxService.getGroupService().userUpdateGroup(configStorage.getOpenid(), this.wxService.getGroupService().groupGet().get(3).getId());
}
}

View File

@@ -9,13 +9,13 @@ import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.api.ApiTestModule.WxXmlMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfInfo;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
@@ -37,6 +37,31 @@ public class WxMpKefuServiceImplTest {
@Inject
protected WxMpServiceImpl wxService;
public void testSendCustomMessage() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
WxMpCustomMessage message = new WxMpCustomMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setToUser(configStorage.getOpenid());
message.setContent(
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
this.wxService.getKefuService().customMessageSend(message);
}
public void testSendCustomMessageWithKfAccount() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
WxMpCustomMessage message = new WxMpCustomMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setToUser(configStorage.getOpenid());
message.setKfAccount(configStorage.getKfAccount());
message.setContent(
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
this.wxService.getKefuService().customMessageSend(message);
}
public void testKfList() throws WxErrorException {
WxMpKfList kfList = this.wxService.getKefuService().kfList();
Assert.assertNotNull(kfList);
@@ -80,7 +105,7 @@ public class WxMpKefuServiceImplTest {
"testKfAccountAdd" }, dataProvider = "getKfAccount")
public void testKfAccountInviteWorker(String kfAccount) throws WxErrorException {
WxMpKfAccountRequest request = WxMpKfAccountRequest.builder()
.kfAccount(kfAccount).inviteWx("www_ucredit_com").build();
.kfAccount(kfAccount).inviteWx(" ").build();
Assert.assertTrue(this.wxService.getKefuService().kfAccountInviteWorker(request));
}
@@ -105,7 +130,7 @@ public class WxMpKefuServiceImplTest {
WxXmlMpInMemoryConfigStorage configStorage = (WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
return new Object[][] {
{ configStorage.getKfAccount(), configStorage.getOpenId() } };
{ configStorage.getKfAccount(), configStorage.getOpenid() } };
}
@Test(dataProvider = "getKfAccountAndOpenid")
@@ -125,7 +150,7 @@ public class WxMpKefuServiceImplTest {
}
@Test(dataProvider = "getKfAccountAndOpenid")
public void testKfSessionGet(String kfAccount,
public void testKfSessionGet(@SuppressWarnings("unused") String kfAccount,
String openid) throws WxErrorException {
WxMpKfSessionGetResult result = this.wxService.getKefuService()
.kfSessionGet(openid);
@@ -150,20 +175,20 @@ public class WxMpKefuServiceImplTest {
}
@Test
public void testKfMsgList() throws WxErrorException, JsonProcessingException {
public void testKfMsgList() throws WxErrorException {
Date startTime = DateTime.now().minusDays(1).toDate();
Date endTime = DateTime.now().minusDays(0).toDate();
WxMpKfMsgList result = this.wxService.getKefuService().kfMsgList(startTime,endTime, 1L, 50);
Assert.assertNotNull(result);
System.err.println(new ObjectMapper().writeValueAsString(result));
System.err.println(result);
}
@Test
public void testKfMsgListAll() throws WxErrorException, JsonProcessingException {
public void testKfMsgListAll() throws WxErrorException {
Date startTime = DateTime.now().minusDays(1).toDate();
Date endTime = DateTime.now().minusDays(0).toDate();
WxMpKfMsgList result = this.wxService.getKefuService().kfMsgList(startTime,endTime);
Assert.assertNotNull(result);
System.err.println(new ObjectMapper().writeValueAsString(result));
System.err.println(result);
}
}

View File

@@ -0,0 +1,159 @@
package me.chanjar.weixin.mp.api.impl;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.api.ApiTestModule.WxXmlMpInMemoryConfigStorage;
@Test
@Guice(modules = ApiTestModule.class)
public class WxMpServiceImplTest {
@Inject
private WxMpServiceImpl wxService;
@Test
public void testCheckSignature() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetAccessToken() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetAccessTokenBoolean() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetJsapiTicket() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetJsapiTicketBoolean() {
Assert.fail("Not yet implemented");
}
@Test
public void testCreateJsapiSignature() {
Assert.fail("Not yet implemented");
}
@Test
public void testCustomMessageSend() {
Assert.fail("Not yet implemented");
}
@Test
public void testMassNewsUpload() {
Assert.fail("Not yet implemented");
}
@Test
public void testMassVideoUpload() {
Assert.fail("Not yet implemented");
}
@Test
public void testMassGroupMessageSend() {
Assert.fail("Not yet implemented");
}
@Test
public void testMassOpenIdsMessageSend() {
Assert.fail("Not yet implemented");
}
@Test
public void testMassMessagePreview() {
Assert.fail("Not yet implemented");
}
@Test
public void testShortUrl() {
Assert.fail("Not yet implemented");
}
@Test
public void testTemplateSend() {
Assert.fail("Not yet implemented");
}
@Test
public void testSetIndustry() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetIndustry() {
Assert.fail("Not yet implemented");
}
@Test
public void testSemanticQuery() {
Assert.fail("Not yet implemented");
}
@Test
public void testOauth2buildAuthorizationUrl() {
Assert.fail("Not yet implemented");
}
@Test
public void testBuildQrConnectUrl() {
String qrconnectRedirectUrl = ((WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage()).getQrconnectRedirectUrl();
String qrConnectUrl = this.wxService.buildQrConnectUrl(qrconnectRedirectUrl,
WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, null);
Assert.assertNotNull(qrConnectUrl);
System.out.println(qrConnectUrl);
}
@Test
public void testOauth2getAccessToken() {
Assert.fail("Not yet implemented");
}
@Test
public void testOauth2refreshAccessToken() {
Assert.fail("Not yet implemented");
}
@Test
public void testOauth2getUserInfo() {
Assert.fail("Not yet implemented");
}
@Test
public void testOauth2validateAccessToken() {
Assert.fail("Not yet implemented");
}
@Test
public void testGetCallbackIP() {
Assert.fail("Not yet implemented");
}
@Test
public void testGet() {
Assert.fail("Not yet implemented");
}
@Test
public void testPost() {
Assert.fail("Not yet implemented");
}
@Test
public void testExecute() {
Assert.fail("Not yet implemented");
}
}

View File

@@ -0,0 +1,52 @@
package me.chanjar.weixin.mp.api.impl;
import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
/**
* @author miller
*/
@Test(groups = "userAPI")
@Guice(modules = ApiTestModule.class)
public class WxMpUserBlacklistServiceImplTest {
@Inject
protected WxMpServiceImpl wxService;
@Test
public void testGetBlacklist() throws Exception {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
WxMpUserBlacklistGetResult wxMpUserBlacklistGetResult = this.wxService.getBlackListService().getBlacklist(configStorage.getOpenid());
Assert.assertNotNull(wxMpUserBlacklistGetResult);
Assert.assertFalse(wxMpUserBlacklistGetResult.getCount() == -1);
Assert.assertFalse(wxMpUserBlacklistGetResult.getTotal() == -1);
Assert.assertFalse(wxMpUserBlacklistGetResult.getOpenidList().size() == -1);
System.out.println(wxMpUserBlacklistGetResult);
}
@Test
public void testPushToBlacklist() throws Exception {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
List<String> openidList = new ArrayList<>();
openidList.add(configStorage.getOpenid());
this.wxService.getBlackListService().pushToBlacklist(openidList);
}
@Test
public void testPullFromBlacklist() throws Exception {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService
.getWxMpConfigStorage();
List<String> openidList = new ArrayList<>();
openidList.add(configStorage.getOpenid());
this.wxService.getBlackListService().pullFromBlacklist(openidList);
}
}

View File

@@ -26,12 +26,12 @@ public class WxMpUserServiceImplTest {
public void testUserUpdateRemark() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
this.wxService.getUserService().userUpdateRemark(configProvider.getOpenId(), "测试备注名");
this.wxService.getUserService().userUpdateRemark(configProvider.getOpenid(), "测试备注名");
}
public void testUserInfo() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configProvider = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
WxMpUser user = this.wxService.getUserService().userInfo(configProvider.getOpenId(), null);
WxMpUser user = this.wxService.getUserService().userInfo(configProvider.getOpenid(), null);
Assert.assertNotNull(user);
System.out.println(user);
}
@@ -45,15 +45,4 @@ public class WxMpUserServiceImplTest {
System.out.println(wxMpUserList);
}
public void testGroupQueryUserGroup() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
long groupid = this.wxService.getGroupService().userGetGroup(configStorage.getOpenId());
Assert.assertTrue(groupid != -1l);
}
public void testGroupMoveUser() throws WxErrorException {
ApiTestModule.WxXmlMpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlMpInMemoryConfigStorage) this.wxService.getWxMpConfigStorage();
this.wxService.getGroupService().userUpdateGroup(configStorage.getOpenId(), this.wxService.getGroupService().groupGet().get(3).getId());
}
}

View File

@@ -0,0 +1,58 @@
package me.chanjar.weixin.mp.api.impl;
import java.util.List;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import com.google.inject.Inject;
import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
/**
*
* @author binarywang(https://github.com/binarywang)
* Created by Binary Wang on 2016/9/2.
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMpUserTagServiceImplTest {
@Inject
protected WxMpServiceImpl wxService;
private Integer tagId;
@Test
public void testTagCreate() throws Exception {
String tagName = "测试标签" + System.currentTimeMillis();
WxUserTag res = this.wxService.getUserTagService().tagCreate(tagName);
System.out.println(res);
this.tagId = res.getId();
Assert.assertEquals(tagName, res.getName());
}
@Test
public void testTagGet() throws Exception {
List<WxUserTag> res = this.wxService.getUserTagService().tagGet();
System.out.println(res);
Assert.assertNotNull(res);
}
@Test(dependsOnMethods = { "testTagCreate" })
public void testTagUpdate() throws Exception {
String tagName = "修改标签" + System.currentTimeMillis();
Boolean res = this.wxService.getUserTagService().tagUpdate(this.tagId, tagName);
System.out.println(res);
Assert.assertTrue(res);
}
@Test(dependsOnMethods = { "testTagCreate" })
public void testTagDelete() throws Exception {
Boolean res = this.wxService.getUserTagService().tagDelete(this.tagId);
System.out.println(res);
Assert.assertTrue(res);
}
}

View File

@@ -1,5 +1,9 @@
package me.chanjar.weixin.mp.demo;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.session.WxSession;
import me.chanjar.weixin.common.session.WxSessionManager;
@@ -10,10 +14,6 @@ import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;
public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMatcher {
private Random random = new Random();
@@ -57,14 +57,14 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa
.toUser(wxMessage.getFromUserName())
.content("请猜一个100以内的数字")
.build();
wxMpService.customMessageSend(m);
wxMpService.getKefuService().customMessageSend(m);
} else {
WxMpCustomMessage m = WxMpCustomMessage
.TEXT()
.toUser(wxMessage.getFromUserName())
.content("放弃了吗那请重新猜一个100以内的数字")
.build();
wxMpService.customMessageSend(m);
wxMpService.getKefuService().customMessageSend(m);
}
session.setAttribute("guessing", Boolean.TRUE);
@@ -92,7 +92,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa
.toUser(wxMessage.getFromUserName())
.content("小了")
.build();
wxMpService.customMessageSend(m);
wxMpService.getKefuService().customMessageSend(m);
} else if (guessNumber > answer) {
WxMpCustomMessage m = WxMpCustomMessage
@@ -100,7 +100,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa
.toUser(wxMessage.getFromUserName())
.content("大了")
.build();
wxMpService.customMessageSend(m);
wxMpService.getKefuService().customMessageSend(m);
} else {
WxMpCustomMessage m = WxMpCustomMessage
.TEXT()
@@ -108,7 +108,7 @@ public class DemoGuessNumberHandler implements WxMpMessageHandler, WxMpMessageMa
.content("Bingo!")
.build();
session.removeAttribute("guessing");
wxMpService.customMessageSend(m);
wxMpService.getKefuService().customMessageSend(m);
}
}

View File

@@ -1,5 +1,12 @@
package me.chanjar.weixin.mp.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
@@ -7,21 +14,12 @@ import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Daniel Qian
*/
public class WxMpEndpointServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
protected WxMpConfigStorage wxMpConfigStorage;
protected WxMpService wxMpService;
protected WxMpMessageRouter wxMpMessageRouter;
@@ -33,7 +31,8 @@ public class WxMpEndpointServlet extends HttpServlet {
this.wxMpMessageRouter = wxMpMessageRouter;
}
@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");

View File

@@ -1,29 +1,28 @@
package me.chanjar.weixin.mp.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class WxMpOAuth2Servlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
protected WxMpService wxMpService;
public WxMpOAuth2Servlet(WxMpService wxMpService) {
this.wxMpService = wxMpService;
}
@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");

View File

@@ -5,7 +5,8 @@
<aesKey>公众号EncodingAESKey</aesKey>
<accessToken>可以不填写</accessToken>
<expiresTime>可以不填写</expiresTime>
<openId>某个加你公众号的用户的openId</openId>
<openid>某个加你公众号的用户的openId</openid>
<oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri>
<qrconnectRedirectUrl>网页应用授权登陆回调地址</qrconnectRedirectUrl>
<kfAccount>完整客服账号,格式为:账号前缀@公众号微信号</kfAccount>
</xml>