sd4324530 / fastweixin Goto Github PK
View Code? Open in Web Editor NEW极其方便的实现微信公众平台服务端开发,2行代码完成服务器绑定,3行代码实现用户消息监听
Home Page: https://github.com/sd4324530/fastweixin
License: Apache License 2.0
极其方便的实现微信公众平台服务端开发,2行代码完成服务器绑定,3行代码实现用户消息监听
Home Page: https://github.com/sd4324530/fastweixin
License: Apache License 2.0
或者提供接口自己实现
不明白..
多线程环境下,保证这两个变量的线程可见性
topcolor字段微信开发平台无对应的字段,设置无效,可以在设置了的情况下作为没有设置消息字段的颜色的默认颜色值
v1.3.11
加密模式
现在微信可以生成带字符串参数的临时二维码,请增加这个枚举值:QR_STR_SCENE
参考: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542
验证token、appid、appsecret都通过,代码也返回true,但是微信开发者服务器绑定却总提示失败,排查后的解决方案是:
com.github.sd4324530.fastweixin.servlet.WeixinControllerSupport:line 27加上
(produces = "application/xml;charset=UTF-8")
目前系统中较多应用使用微信token,最好把fastweixin单独部署成服务。(之前部分系统存在实现获取token的逻辑)
但是基于现状,尚未实现。因此希望可以accessToken可以手动刷新。
比如场景:用户手动操作了刷新accessToken之后,fastweixin报错,但是对于报错后不支持直接刷新,反而等到7100s之后才会刷新
public String getAccessToken() {
long now = System.currentTimeMillis();
long time = now - this.weixinTokenStartTime;
try {
/*
* 判断优先顺序:
* 1.官方给出的超时时间是7200秒,这里用7100秒来做,防止出现已经过期的情况
* 2.刷新标识判断,如果已经在刷新了,则也直接跳过,避免多次重复刷新,如果没有在刷新,则开始刷新
*/
if (time > 7100000 && this.tokenRefreshing.compareAndSet(false, true)) {
LOG.debug("准备刷新token.............");
initToken(now);
}
} catch (Exception e) {
LOG.warn("刷新Token出错.", e);
//刷新工作出现有异常,将标识设置回false
this.tokenRefreshing.set(false);
}
return accessToken;
}
/**
菜单对象,包含所有菜单按钮
@author peiyu
*/
public class Menu implements Model {
/**
public List getButton() {
return button;
}
public void setButton(List button) {
if(null == button || button.size() > 3) {
throw new RuntimeException("主菜单最多3个");
}
}
@OverRide
public String toJsonString() {
return JSONUtil.toJson(this);
}
}
set方法少了一行this.button = button
没有文档和Demo,只能读代码,基于这个之后,才可能快速起来啦。
该问题的出现一直没有发现规律,也不知道如何解决?
2016-12-25 09:49:26 DEBUG [com.github.sd4324530.fastweixin.util.NetWorkCenter.doRequest:273] - [-----------------请求成功-----------------]
2016-12-25 09:49:26 DEBUG [com.github.sd4324530.fastweixin.util.NetWorkCenter.doRequest:274] - [响应结果:]
2016-12-25 09:49:26 DEBUG [com.github.sd4324530.fastweixin.util.NetWorkCenter.doRequest:275] - [{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [dLTTea0566vr46!]"}]
我的服务需要部署多个节点,但是多个节点就会产生ApiConfig不一致的情况,会使之前获取的token失效,这种情况应该怎么处理
能否支持这个接口呢?
我建议对于微信调用控制方式的实现不要太多的依赖于其他框架,特别是web框架,微信API的控制我想不应该和web程序有任何关系吧?
com.github.sd4324530.fastweixin.util.CollectionUtil.newArrayList(T... ele) 会产生含有空元素的ArrayList.
java.lang.NullPointerException
com.github.sd4324530.fastweixin.util.NetWorkCenter.doRequest(NetWorkCenter.java:246)
com.github.sd4324530.fastweixin.util.NetWorkCenter.post(NetWorkCenter.java:134)
com.github.sd4324530.fastweixin.util.NetWorkCenter.post(NetWorkCenter.java:139)
com.github.sd4324530.fastweixin.api.BaseAPI.executePost(BaseAPI.java:102)
com.github.sd4324530.fastweixin.api.BaseAPI.executePost(BaseAPI.java:83)
com.github.sd4324530.fastweixin.api.MessageAPI.sendCustomMessage(MessageAPI.java:99)
企业号文件上传API中,MediaType枚举没有 普通文件(file)
代码在QYMediaAPI.java 54行
在刷新jsApiTicket的时候没有考虑accessToken的有效性,会造成jsApiTicket刷新失败,返回的还是旧的jsApiTicket
private void initJSToken() {
LOG.debug("初始化 jsapi_ticket........");
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
NetWorkCenter.get(url, null, new NetWorkCenter.ResponseCallback() {
@Override
public void onResponse(int resultCode, String resultJson) {
if (HttpStatus.SC_OK == resultCode) {
GetJsApiTicketResponse response = JSONUtil.toBean(resultJson, GetJsApiTicketResponse.class);
LOG.debug("获取jsapi_ticket:{}", response.getTicket());
ApiConfig.this.jsApiTicket = response.getTicket();
jsTokenStartTime = System.currentTimeMillis();
}
}
});
}
偶然看到这个项目,mvc的挺有兴趣就看了下
WeixinSupport类里面处理消息的逻辑感觉有点不对:
msg = handleTextMsg(textReqMsg);
if (isNull(msg)) {
msg = processMessageHandle(textReqMsg);
}
private BaseMsg processMessageHandle(BaseReqMsg msg) {
if (isEmpty(messageHandles)) {
synchronized (lock) {
messageHandles = this.getMessageHandles();
}
}
if (isNotEmpty(messageHandles)) {
for (MessageHandle messageHandle : messageHandles) {
BaseMsg resultMsg = messageHandle.handle(msg);
if (nonNull(resultMsg)) {
return resultMsg;
}
}
}
return null;
}
这几行的意思是先处理消息,要是没有处理就交给messageHandles,而开始在controller复写的这个方法会返回一个list,也就是每次请求不管是什么类型都要走一遍所有的MessageHandle ?这块感觉有误,不知道我理解的对不对
请支持mass/delete,群发消息删除接口
https://mp.weixin.qq.com/wiki?action=doc&id=mp1481187827_i0l21#4
http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/mass/delete
你好,麻烦修复下解析xml的漏洞问题
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing";
dbf.setFeature(FEATURE, true);
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder builder = dbf.newDocumentBuilder();
// 读取xml文件内容
FileInputStream fis = new FileInputStream("path/to/xxexml");
InputSource is = new InputSource(fis);
Document doc = builder.parse(is);
public static BaseResponse post(String url, String paramData, List fileList) {
final BaseResponse[] response = new BaseResponse[]{null};
post(url, paramData, fileList, new ResponseCallback() {
@OverRide
public void onResponse(int resultCode, String resultJson) {
if (200 == resultCode) {
BaseResponse r = JSONUtil.toBean(resultJson, BaseResponse.class);
if(StrUtil.isBlank(r.getErrcode())) {
r.setErrcode("0");
}
r.setErrmsg(resultJson);
response[0] = r;
} else {//请求本身就失败了
response[0] = new BaseResponse();
response[0].setErrcode(String.valueOf(resultCode));
response[0].setErrmsg("请求失败");
}
}
});
return response[0];
}
当请求失败的时候errmsg为"请求失败",导致外层API调用时,在请求异常时,json解析失败
例如 BaseResponse r = executePost(url, null, file);
response = JSONUtil.toBean(r.getErrmsg(), UploadMediaResponse.class);
可以将上面的请求失败的时候errmsg设置成返回数据,方法2,在所有调用的api处,检查errcode分别处理正常和异常的情况
ResultType中缺少错误码为45047的值,所以会导致微信接口返回这个码时,fastweixin相关接口会返回NULL
如题,getErrMsg会抛出NullPointerException.
返回示例如下:
{"errcode":48003,"errmsg":"user not agree mass-send protocol"}
建议修改为,返回码不包含在ResultType中时,直接返回原始errmsg.
明文模式下 aesKey是为空的,如果把空值传入 parseXml 函数
parseXml(HttpServletRequest request, String token, String appId, String aesKey)
那么 inputStream 成员就没有数据下面的代码就会抛出异常。
有些情况不能用兼容模式或者安全模式(服务器没有打安全策略补丁),只可以用明文模式也是很常见的,我觉得这是个重大 BUG。
public class TemplateMsgAPI extends BaseAPI {
private static final Logger LOG = LoggerFactory.getLogger(CustomAPI.class);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.