2
0
mirror of https://gitee.com/hotlcc/wechat4j.git synced 2025-06-29 05:32:48 +08:00

提交代码

This commit is contained in:
hotlcc 2018-07-25 11:03:59 +08:00
parent 03bbe2d858
commit 83e9411bcd
10 changed files with 550 additions and 57 deletions

View File

@ -5,7 +5,11 @@ import com.alibaba.fastjson.JSONObject;
import com.hotlcc.wechat4j.api.WebWeixinApi; import com.hotlcc.wechat4j.api.WebWeixinApi;
import com.hotlcc.wechat4j.enums.ExitTypeEnum; import com.hotlcc.wechat4j.enums.ExitTypeEnum;
import com.hotlcc.wechat4j.enums.LoginTipEnum; import com.hotlcc.wechat4j.enums.LoginTipEnum;
import com.hotlcc.wechat4j.enums.RetcodeEnum;
import com.hotlcc.wechat4j.enums.SelectorEnum;
import com.hotlcc.wechat4j.handler.ExitEventHandler; import com.hotlcc.wechat4j.handler.ExitEventHandler;
import com.hotlcc.wechat4j.handler.ReceivedMsgHandler;
import com.hotlcc.wechat4j.model.ReceivedMsg;
import com.hotlcc.wechat4j.util.CommonUtil; import com.hotlcc.wechat4j.util.CommonUtil;
import com.hotlcc.wechat4j.util.PropertiesUtil; import com.hotlcc.wechat4j.util.PropertiesUtil;
import com.hotlcc.wechat4j.util.QRCodeUtil; import com.hotlcc.wechat4j.util.QRCodeUtil;
@ -67,6 +71,8 @@ public class Wechat {
//退出事件处理器 //退出事件处理器
private List<ExitEventHandler> exitEventHandlers; private List<ExitEventHandler> exitEventHandlers;
//接收消息处理器
private List<ReceivedMsgHandler> receivedMsgHandlers;
public Wechat(CookieStore cookieStore) { public Wechat(CookieStore cookieStore) {
this.cookieStore = cookieStore; this.cookieStore = cookieStore;
@ -82,6 +88,9 @@ public class Wechat {
} }
public void addExitEventHandler(ExitEventHandler handler) { public void addExitEventHandler(ExitEventHandler handler) {
if (handler == null) {
return;
}
if (exitEventHandlers == null) { if (exitEventHandlers == null) {
exitEventHandlers = new ArrayList<>(); exitEventHandlers = new ArrayList<>();
} }
@ -90,10 +99,37 @@ public class Wechat {
} }
public void addExitEventHandler(Collection<ExitEventHandler> handlers) { public void addExitEventHandler(Collection<ExitEventHandler> handlers) {
if (handlers == null || handlers.isEmpty()) {
return;
}
if (exitEventHandlers == null) { if (exitEventHandlers == null) {
exitEventHandlers = new ArrayList<>(); exitEventHandlers = new ArrayList<>();
} }
exitEventHandlers.addAll(handlers); for (ExitEventHandler handler : handlers) {
addExitEventHandler(handler);
}
}
public void addReceivedMsgHandler(ReceivedMsgHandler handler) {
if (handler == null) {
return;
}
if (receivedMsgHandlers == null) {
receivedMsgHandlers = new ArrayList<>();
}
receivedMsgHandlers.add(handler);
}
public void addReceivedMsgHandler(Collection<ReceivedMsgHandler> handlers) {
if (handlers == null || handlers.isEmpty()) {
return;
}
if (receivedMsgHandlers == null) {
receivedMsgHandlers = new ArrayList<>();
}
for (ReceivedMsgHandler handler : handlers) {
addReceivedMsgHandler(handler);
}
} }
private HttpClient buildHttpClient(CookieStore cookieStore) { private HttpClient buildHttpClient(CookieStore cookieStore) {
@ -103,7 +139,7 @@ public class Wechat {
long keepAlive = super.getKeepAliveDuration(response, context); long keepAlive = super.getKeepAliveDuration(response, context);
if (keepAlive == -1) { if (keepAlive == -1) {
//如果服务器没有设置keep-alive这个参数我们就把它设置成1分钟 //如果服务器没有设置keep-alive这个参数我们就把它设置成1分钟
keepAlive = 5000; keepAlive = 60000;
} }
return keepAlive; return keepAlive;
} }
@ -561,7 +597,7 @@ public class Wechat {
//人为退出 //人为退出
int retcode = result.getIntValue("retcode"); int retcode = result.getIntValue("retcode");
if (retcode != 0) { if (retcode != RetcodeEnum.RECODE_0.getCode()) {
logger.info("微信退出或从其它设备登录"); logger.info("微信退出或从其它设备登录");
logout(); logout();
processExitEvent(ExitTypeEnum.REMOTE_EXIT, null); processExitEvent(ExitTypeEnum.REMOTE_EXIT, null);
@ -622,25 +658,25 @@ public class Wechat {
try { try {
switch (type) { switch (type) {
case ERROR_EXIT: case ERROR_EXIT:
handler.forError(wechat); handler.handleErrorExitEvent(wechat);
break; break;
case REMOTE_EXIT: case REMOTE_EXIT:
handler.forRemote(wechat); handler.handleRemoteExitEvent(wechat);
break; break;
case LOCAL_EXIT: case LOCAL_EXIT:
handler.forLocal(wechat); handler.handleLocalExitEvent(wechat);
break; break;
default: default:
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Exit event \"" + type.name() + "\" process error.", e); logger.error("Exit event process error.", e);
} }
try { try {
handler.forAll(wechat, type, t); handler.handleAllType(wechat, type, t);
} catch (Exception e) { } catch (Exception e) {
logger.error("ForAll Exit event process error.", e); logger.error("Exit event process error.", e);
} }
} }
@ -650,7 +686,124 @@ public class Wechat {
* @param selector * @param selector
*/ */
private void processSelector(int selector) { private void processSelector(int selector) {
System.out.println(selector); try {
SelectorEnum e = SelectorEnum.valueOf(selector);
if (e == null) {
logger.warn("Cannot process selector for error selector {}", selector);
return;
}
switch (e) {
case SELECTOR_0:
break;
case SELECTOR_2:
webWxSync();
break;
case SELECTOR_4:
break;
case SELECTOR_7:
break;
default:
break;
}
} catch (Exception e) {
logger.error("Execute processSelector error.", e);
}
}
/**
* 同步数据
*
* @return
*/
private void webWxSync() {
try {
JSONObject result = webWeixinApi.webWxSync(httpClient, passTicket, wxsid, skey, wxuin, SyncKey);
if (result == null) {
logger.error("从服务端同步新数据异常");
return;
}
JSONObject BaseResponse = result.getJSONObject("BaseResponse");
if (BaseResponse == null) {
logger.warn("同步接口返回数据格式错误");
return;
}
int Ret = BaseResponse.getIntValue("Ret");
if (Ret != RetcodeEnum.RECODE_0.getCode()) {
logger.warn("同步接口返回错误代码:{}", Ret);
return;
}
//新消息处理
JSONArray AddMsgList = result.getJSONArray("AddMsgList");
processNewMsg(AddMsgList);
//更新SyncKey
try {
SyncKeyLock.lock();
SyncKey = result.getJSONObject("SyncKey");
} finally {
SyncKeyLock.unlock();
}
} catch (Exception e) {
logger.error("Execute webWxSync error.", e);
}
}
/**
* 处理新消息
*
* @param AddMsgList
*/
private void processNewMsg(JSONArray AddMsgList) {
try {
if (AddMsgList != null && !AddMsgList.isEmpty()) {
int len = AddMsgList.size();
logger.debug("收到{}条新消息", len);
for (int i = 0; i < len; i++) {
JSONObject AddMsg = AddMsgList.getJSONObject(i);
processNewMsg(AddMsg);
}
}
} catch (Exception e) {
logger.error("Execute processNewMsg error.", e);
}
}
private void processNewMsg(JSONObject AddMsg) {
try {
ReceivedMsg msg = new ReceivedMsg(AddMsg);
processNewMsg(msg);
} catch (Exception e) {
logger.error("Execute processNewMsg error.", e);
}
}
private void processNewMsg(ReceivedMsg msg) {
try {
if (receivedMsgHandlers == null) {
return;
}
for (ReceivedMsgHandler handler : receivedMsgHandlers) {
if (handler != null) {
processNewMsg(msg, handler);
}
}
} catch (Exception e) {
logger.error("Execute processNewMsg error.", e);
}
}
private void processNewMsg(ReceivedMsg msg, ReceivedMsgHandler handler) {
try {
if (handler != null) {
handler.handleAllType(wechat, msg);
}
} catch (Exception e) {
}
} }
} }

View File

@ -490,14 +490,14 @@ public class WebWeixinApi {
} }
/** /**
* 从服务端拉取新消息 * 从服务端同步新数据
*/ */
public JSONObject pullNewMsg(HttpClient httpClient, public JSONObject webWxSync(HttpClient httpClient,
String passticket, String passticket,
String wxsid, String wxsid,
String skey, String skey,
String wxuin, String wxuin,
JSONObject SyncKey) { JSONObject SyncKey) {
try { try {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url")) String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url"))
.add("skey", skey) .add("skey", skey)
@ -525,7 +525,7 @@ public class WebWeixinApi {
return JSONObject.parseObject(res); return JSONObject.parseObject(res);
} catch (Exception e) { } catch (Exception e) {
logger.error("从服务端拉取新消息异常", e); logger.error("从服务端同步新数据异常", e);
return null; return null;
} }
} }

View File

@ -0,0 +1,29 @@
package com.hotlcc.wechat4j.enums;
public enum RetcodeEnum {
RECODE_0(0, "正常"),
RECODE_1100(1100, "失败/登出微信"),
RECODE_1101(1101, "从其它设备登录微信");
private int code;
private String desc;
RetcodeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public static RetcodeEnum valueOf(int code) {
RetcodeEnum[] es = values();
for (RetcodeEnum e : es) {
if (e.code == code) {
return e;
}
}
return null;
}
}

View File

@ -0,0 +1,30 @@
package com.hotlcc.wechat4j.enums;
public enum SelectorEnum {
SELECTOR_0(0, "正常"),
SELECTOR_2(2, "有新消息"),
SELECTOR_4(4, "目前发现修改了联系人备注会出现"),
SELECTOR_7(7, "手机操作了微信");
private int code;
private String desc;
SelectorEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public static SelectorEnum valueOf(int code) {
SelectorEnum[] es = values();
for (SelectorEnum e : es) {
if (e.code == code) {
return e;
}
}
return null;
}
}

View File

@ -14,26 +14,26 @@ public interface ExitEventHandler {
* @param type * @param type
* @param t * @param t
*/ */
void forAll(Wechat wechat, ExitTypeEnum type, Throwable t); void handleAllType(Wechat wechat, ExitTypeEnum type, Throwable t);
/** /**
* 针对错误导致的退出事件 * 针对错误导致的退出事件
* *
* @param wechat * @param wechat
*/ */
void forError(Wechat wechat); void handleErrorExitEvent(Wechat wechat);
/** /**
* 针对远程人为导致的退出事件 * 针对远程人为导致的退出事件
* *
* @param wechat * @param wechat
*/ */
void forRemote(Wechat wechat); void handleRemoteExitEvent(Wechat wechat);
/** /**
* 针对本地任务导致的退出事件 * 针对本地任务导致的退出事件
* *
* @param wechat * @param wechat
*/ */
void forLocal(Wechat wechat); void handleLocalExitEvent(Wechat wechat);
} }

View File

@ -0,0 +1,17 @@
package com.hotlcc.wechat4j.handler;
import com.hotlcc.wechat4j.Wechat;
import com.hotlcc.wechat4j.model.ReceivedMsg;
/**
* 接收消息处理器
*/
public interface ReceivedMsgHandler {
/**
* 处理所有类型的消息
*
* @param wechat
* @param msg
*/
void handleAllType(Wechat wechat, ReceivedMsg msg);
}

View File

@ -0,0 +1,24 @@
package com.hotlcc.wechat4j.model;
import com.alibaba.fastjson.JSONObject;
public final class AppInfo {
private Integer Type;
private String AppID;
public AppInfo(JSONObject info) {
if (info == null) {
return;
}
this.Type = info.getInteger("Type");
this.AppID = info.getString("AppID");
}
public Integer getType() {
return Type;
}
public String getAppID() {
return AppID;
}
}

View File

@ -0,0 +1,179 @@
package com.hotlcc.wechat4j.model;
import com.alibaba.fastjson.JSONObject;
public final class ReceivedMsg {
public ReceivedMsg(JSONObject msg) {
if (msg == null) {
return;
}
this.SubMsgType = msg.getInteger("SubMsgType");
this.VoiceLength = msg.getLong("VoiceLength");
this.FileName = msg.getString("FileName");
this.ImgHeight = msg.getLong("ImgHeight");
this.ToUserName = msg.getString("ToUserName");
this.HasProductId = msg.getLong("HasProductId");
this.ImgStatus = msg.getInteger("ImgStatus");
this.Url = msg.getString("Url");
this.ImgWidth = msg.getInteger("ImgWidth");
this.ForwardFlag = msg.getInteger("ForwardFlag");
this.Status = msg.getInteger("Status");
this.Ticket = msg.getString("Ticket");
this.RecommendInfo = new RecommendInfo(msg.getJSONObject("RecommendInfo"));
this.CreateTime = msg.getLong("CreateTime");
this.NewMsgId = msg.getLong("NewMsgId");
this.MsgType = msg.getInteger("MsgType");
this.EncryFileName = msg.getString("EncryFileName");
this.MsgId = msg.getString("MsgId");
this.StatusNotifyCode = msg.getInteger("StatusNotifyCode");
this.AppInfo = new AppInfo(msg.getJSONObject("AppInfo"));
this.PlayLength = msg.getLong("PlayLength");
this.MediaId = msg.getString("MediaId");
this.Content = msg.getString("Content");
this.StatusNotifyUserName = msg.getString("StatusNotifyUserName");
this.FromUserName = msg.getString("FromUserName");
this.OriContent = msg.getString("OriContent");
this.FileSize = msg.getString("FileSize");
}
private Integer SubMsgType;
private Long VoiceLength;
private String FileName;
private Long ImgHeight;
private String ToUserName;
private Long HasProductId;
private Integer ImgStatus;
private String Url;
private Integer ImgWidth;
private Integer ForwardFlag;
private Integer Status;
private String Ticket;
private RecommendInfo RecommendInfo;
private Long CreateTime;
private Long NewMsgId;
private Integer MsgType;
private String EncryFileName;
private String MsgId;
private Integer StatusNotifyCode;
private AppInfo AppInfo;
private Integer AppMsgType;
private Long PlayLength;
private String MediaId;
private String Content;
private String StatusNotifyUserName;
private String FromUserName;
private String OriContent;
private String FileSize;
public Integer getSubMsgType() {
return SubMsgType;
}
public Long getVoiceLength() {
return VoiceLength;
}
public String getFileName() {
return FileName;
}
public Long getImgHeight() {
return ImgHeight;
}
public String getToUserName() {
return ToUserName;
}
public Long getHasProductId() {
return HasProductId;
}
public Integer getImgStatus() {
return ImgStatus;
}
public String getUrl() {
return Url;
}
public Integer getImgWidth() {
return ImgWidth;
}
public Integer getForwardFlag() {
return ForwardFlag;
}
public Integer getStatus() {
return Status;
}
public String getTicket() {
return Ticket;
}
public com.hotlcc.wechat4j.model.RecommendInfo getRecommendInfo() {
return RecommendInfo;
}
public Long getCreateTime() {
return CreateTime;
}
public Long getNewMsgId() {
return NewMsgId;
}
public Integer getMsgType() {
return MsgType;
}
public String getEncryFileName() {
return EncryFileName;
}
public String getMsgId() {
return MsgId;
}
public Integer getStatusNotifyCode() {
return StatusNotifyCode;
}
public com.hotlcc.wechat4j.model.AppInfo getAppInfo() {
return AppInfo;
}
public Integer getAppMsgType() {
return AppMsgType;
}
public Long getPlayLength() {
return PlayLength;
}
public String getMediaId() {
return MediaId;
}
public String getContent() {
return Content;
}
public String getStatusNotifyUserName() {
return StatusNotifyUserName;
}
public String getFromUserName() {
return FromUserName;
}
public String getOriContent() {
return OriContent;
}
public String getFileSize() {
return FileSize;
}
}

View File

@ -0,0 +1,96 @@
package com.hotlcc.wechat4j.model;
import com.alibaba.fastjson.JSONObject;
public final class RecommendInfo {
public RecommendInfo(JSONObject info) {
if (info == null) {
return;
}
this.Ticket = info.getString("Ticket");
this.UserName = info.getString("UserName");
this.Sex = info.getInteger("Sex");
this.AttrStatus = info.getInteger("AttrStatus");
this.City = info.getString("City");
this.NickName = info.getString("NickName");
this.Scene = info.getInteger("Scene");
this.Province = info.getString("Province");
this.Content = info.getString("Content");
this.Alias = info.getString("Alias");
this.Signature = info.getString("Signature");
this.OpCode = info.getInteger("OpCode");
this.QQNum = info.getLong("QQNum");
this.VerifyFlag = info.getInteger("VerifyFlag");
}
private String Ticket;
private String UserName;
private Integer Sex;
private Integer AttrStatus;
private String City;
private String NickName;
private Integer Scene;
private String Province;
private String Content;
private String Alias;
private String Signature;
private Integer OpCode;
private Long QQNum;
private Integer VerifyFlag;
public String getTicket() {
return Ticket;
}
public String getUserName() {
return UserName;
}
public Integer getSex() {
return Sex;
}
public Integer getAttrStatus() {
return AttrStatus;
}
public String getCity() {
return City;
}
public String getNickName() {
return NickName;
}
public Integer getScene() {
return Scene;
}
public String getProvince() {
return Province;
}
public String getContent() {
return Content;
}
public String getAlias() {
return Alias;
}
public String getSignature() {
return Signature;
}
public Integer getOpCode() {
return OpCode;
}
public Long getQQNum() {
return QQNum;
}
public Integer getVerifyFlag() {
return VerifyFlag;
}
}

View File

@ -1,35 +0,0 @@
import com.hotlcc.wechat4j.Wechat;
import com.hotlcc.wechat4j.api.WebWeixinApi;
import com.hotlcc.wechat4j.util.QRCodeUtil;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
public class TestClass {
private static Logger logger = LoggerFactory.getLogger(TestClass.class);
public void test03() throws IOException {
BufferedImage image = ImageIO.read(new FileInputStream("D:/2.jpg"));
System.out.println(QRCodeUtil.toCharMatrix(image));
}
public void test04() {
WebWeixinApi api = new WebWeixinApi();
Wechat wechat = new Wechat();
wechat.setWebWeixinApi(api);
wechat.test();
}
@Test
public void test05() {
WebWeixinApi api = new WebWeixinApi();
Wechat wechat = new Wechat();
wechat.setWebWeixinApi(api);
System.out.println(wechat.autoLogin());
}
}