From 4eebb0ab1071a42f80765656fe88075ad752b413 Mon Sep 17 00:00:00 2001 From: Allen Date: Fri, 14 Sep 2018 21:48:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81:=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=BD=9C=E5=9C=A8bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hotlcc/wechat4j/api/WebWeixinApi.java | 169 ++++++++++++------ .../hotlcc/wechat4j/enums/ExitTypeEnum.java | 22 ++- .../hotlcc/wechat4j/enums/LoginTipEnum.java | 16 +- .../com/hotlcc/wechat4j/util/QRCodeUtil.java | 73 ++++---- 4 files changed, 181 insertions(+), 99 deletions(-) diff --git a/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java b/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java index 5e9b1e0..b55cb39 100644 --- a/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java +++ b/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java @@ -39,7 +39,7 @@ import java.util.regex.Pattern; * * @author Allen */ -@SuppressWarnings("Duplicates") +@SuppressWarnings({"Duplicates", "unused"}) public class WebWeixinApi { private static Logger logger = LoggerFactory.getLogger(WebWeixinApi.class); @@ -50,7 +50,7 @@ public class WebWeixinApi { private static Pattern PATTERN_UUID_2 = Pattern.compile("window.QRLogin.code = (\\d+); window.QRLogin.uuid = \"(\\S+?)\";"); private static Pattern PATTERN_REDIRECT_URI_1 = Pattern.compile("window.code=(\\d+);"); private static Pattern PATTERN_REDIRECT_URI_2 = Pattern.compile("window.code=(\\d+);\\s*window.redirect_uri=\"(\\S+?)\";"); - private static Pattern PATTERN_REDIRECT_URI_3 = Pattern.compile("http(s*)://wx(\\d*)\\.qq\\.com\\/"); + private static Pattern PATTERN_REDIRECT_URI_3 = Pattern.compile("http(s*)://wx(\\d*)\\.qq\\.com/"); /** * 上传媒体文件分片大小 @@ -59,6 +59,9 @@ public class WebWeixinApi { /** * 获取微信uuid + * + * @param httpClient http客户端 + * @return 返回数据 */ public JSONObject getWxUuid(HttpClient httpClient) { try { @@ -113,7 +116,9 @@ public class WebWeixinApi { /** * 获取二维码 * - * @param uuid + * @param httpClient http客户端 + * @param uuid uuid + * @return 二维码图片字节数据 */ public byte[] getQR(HttpClient httpClient, String uuid) { @@ -147,7 +152,10 @@ public class WebWeixinApi { /** * 获取跳转uri(等待扫码认证) * - * @return + * @param httpClient http客户端 + * @param tip 登录tip + * @param uuid uuid + * @return 返回数据 */ public JSONObject getRedirectUri(HttpClient httpClient, LoginTipEnum tip, @@ -216,6 +224,10 @@ public class WebWeixinApi { /** * 获取登录认证码 * 此方法执行后,其它web端微信、pc端都会下线 + * + * @param httpClient http客户端 + * @param redirectUri 调整uri + * @return 返回数据 */ public JSONObject getLoginCode(HttpClient httpClient, String redirectUri) { @@ -236,9 +248,7 @@ public class WebWeixinApi { HttpEntity entity = response.getEntity(); String res = EntityUtils.toString(entity, Consts.UTF_8); - JSONObject result = JSONObject.parseObject(XML.toJSONObject(res).toString()).getJSONObject("error"); - - return result; + return JSONObject.parseObject(XML.toJSONObject(res).toString()).getJSONObject("error"); } catch (Exception e) { logger.error("获取登录认证码异常", e); return null; @@ -247,21 +257,25 @@ public class WebWeixinApi { /** * 退出登录 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param baseRequest BaseRequest */ public void logout(HttpClient httpClient, String urlVersion, - BaseRequest BaseRequest) { + BaseRequest baseRequest) { try { List pairList = new ArrayList<>(); - pairList.add(new BasicNameValuePair("sid", BaseRequest.getSid())); - pairList.add(new BasicNameValuePair("uin", BaseRequest.getUin())); + pairList.add(new BasicNameValuePair("sid", baseRequest.getSid())); + pairList.add(new BasicNameValuePair("uin", baseRequest.getUin())); //分两步进行 for (int i = 0; i <= 1; i++) { String url = new ST(PropertiesUtil.getProperty("webwx-url.logout_url")) .add("urlVersion", urlVersion) .add("type", i) - .add("skey", StringUtil.encodeURL(BaseRequest.getSkey(), Consts.UTF_8.name())) + .add("skey", StringUtil.encodeURL(baseRequest.getSkey(), Consts.UTF_8.name())) .render(); HttpPost httpPost = new HttpPost(url); @@ -279,12 +293,16 @@ public class WebWeixinApi { /** * push登录 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param wxuin uin + * @return 返回数据 */ public JSONObject pushLogin(HttpClient httpClient, String urlVersion, String wxuin) { try { - long millis = System.currentTimeMillis(); String url = new ST(PropertiesUtil.getProperty("webwx-url.pushlogin_url")) .add("urlVersion", urlVersion) .add("uin", wxuin) @@ -311,11 +329,17 @@ public class WebWeixinApi { /** * 获取初始化数据 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @return 返回数据 */ public JSONObject webWeixinInit(HttpClient httpClient, String urlVersion, String passticket, - BaseRequest BaseRequest) { + BaseRequest baseRequest) { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxinit_url")) .add("urlVersion", urlVersion) @@ -327,7 +351,7 @@ public class WebWeixinApi { httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); JSONObject paramJson = new JSONObject(); - paramJson.put("BaseRequest", BaseRequest); + paramJson.put("BaseRequest", baseRequest); HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8); httpPost.setEntity(paramEntity); @@ -350,12 +374,17 @@ public class WebWeixinApi { /** * 开启消息状态通知 * - * @return + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param loginUserName 当前登录账号用户名 + * @return 返回数据 */ public JSONObject statusNotify(HttpClient httpClient, String urlVersion, String passticket, - BaseRequest BaseRequest, + BaseRequest baseRequest, String loginUserName) { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.statusnotify_url")) @@ -367,7 +396,7 @@ public class WebWeixinApi { httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); JSONObject paramJson = new JSONObject(); - paramJson.put("BaseRequest", BaseRequest); + paramJson.put("BaseRequest", baseRequest); paramJson.put("ClientMsgId", System.currentTimeMillis()); paramJson.put("Code", 3); paramJson.put("FromUserName", loginUserName); @@ -393,21 +422,27 @@ public class WebWeixinApi { /** * 服务端状态同步心跳 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param baseRequest BaseRequest + * @param syncKeyList SyncKeyList + * @return 返回数据 */ public JSONObject syncCheck(HttpClient httpClient, String urlVersion, - BaseRequest BaseRequest, - JSONArray SyncKeyList) { + BaseRequest baseRequest, + JSONArray syncKeyList) { try { long millis = System.currentTimeMillis(); String url = new ST(PropertiesUtil.getProperty("webwx-url.synccheck_url")) .add("urlVersion", urlVersion) .add("r", millis) - .add("skey", StringUtil.encodeURL(BaseRequest.getSkey(), Consts.UTF_8.name())) - .add("sid", BaseRequest.getSid()) - .add("uin", BaseRequest.getUin()) + .add("skey", StringUtil.encodeURL(baseRequest.getSkey(), Consts.UTF_8.name())) + .add("sid", baseRequest.getSid()) + .add("uin", baseRequest.getUin()) .add("deviceid", WechatUtil.createDeviceID()) - .add("synckey", StringUtil.encodeURL(WechatUtil.syncKeyListToString(SyncKeyList), Consts.UTF_8.name())) + .add("synckey", StringUtil.encodeURL(WechatUtil.syncKeyListToString(syncKeyList), Consts.UTF_8.name())) .add("_", millis) .render(); @@ -446,6 +481,12 @@ public class WebWeixinApi { /** * 获取全部联系人列表 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param skey skey + * @return 返回数据 */ public JSONObject getContact(HttpClient httpClient, String urlVersion, @@ -479,11 +520,18 @@ public class WebWeixinApi { /** * 批量获取指定用户信息 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param batchContactList 联系人列表 + * @return 返回数据 */ public JSONObject batchGetContact(HttpClient httpClient, String urlVersion, String passticket, - BaseRequest BaseRequest, + BaseRequest baseRequest, JSONArray batchContactList) { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.batchgetcontact_url")) @@ -496,7 +544,7 @@ public class WebWeixinApi { httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); JSONObject paramJson = new JSONObject(); - paramJson.put("BaseRequest", BaseRequest); + paramJson.put("BaseRequest", baseRequest); paramJson.put("Count", batchContactList.size()); paramJson.put("List", batchContactList); HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8); @@ -520,17 +568,24 @@ public class WebWeixinApi { /** * 从服务端同步新数据 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param syncKey syncKey + * @return 返回数据 */ public JSONObject webWxSync(HttpClient httpClient, String urlVersion, String passticket, - BaseRequest BaseRequest, - JSONObject SyncKey) { + BaseRequest baseRequest, + JSONObject syncKey) { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url")) .add("urlVersion", urlVersion) - .add("skey", BaseRequest.getSkey()) - .add("sid", BaseRequest.getSid()) + .add("skey", baseRequest.getSkey()) + .add("sid", baseRequest.getSid()) .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) .render(); @@ -538,8 +593,8 @@ public class WebWeixinApi { httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); JSONObject paramJson = new JSONObject(); - paramJson.put("BaseRequest", BaseRequest); - paramJson.put("SyncKey", SyncKey); + paramJson.put("BaseRequest", baseRequest); + paramJson.put("SyncKey", syncKey); HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8); httpPost.setEntity(paramEntity); @@ -561,6 +616,13 @@ public class WebWeixinApi { /** * 发送消息 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param message 消息 + * @return 返回数据 */ public JSONObject sendMsg(HttpClient httpClient, String urlVersion, @@ -592,9 +654,7 @@ public class WebWeixinApi { HttpEntity entity = response.getEntity(); String res = EntityUtils.toString(entity, Consts.UTF_8); - JSONObject result = JSONObject.parseObject(res); - - return result; + return JSONObject.parseObject(res); } catch (Exception e) { logger.error("发送消息异常", e); return null; @@ -604,17 +664,17 @@ public class WebWeixinApi { /** * 上传媒体文件(支持大文件自动分片上传) * - * @param httpClient - * @param urlVersion - * @param passticket - * @param baseRequest - * @param fromUserName - * @param toUserName - * @param dataTicket - * @param mediaData - * @param mediaName - * @param contentType - * @return + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param fromUserName 发送者用户名 + * @param toUserName 接受者用户名 + * @param dataTicket dataTicket + * @param mediaData 媒体文件二进制数据 + * @param mediaName 媒体文件名称 + * @param contentType 媒体文件类型 + * @return 返回数据 */ public JSONObject uploadMedia(HttpClient httpClient, String urlVersion, @@ -691,12 +751,12 @@ public class WebWeixinApi { break; } - JSONObject BaseResponse = result.getJSONObject("BaseResponse"); - if (BaseResponse == null) { + JSONObject baseResponse = result.getJSONObject("BaseResponse"); + if (baseResponse == null) { break; } - int Ret = BaseResponse.getIntValue("Ret"); - if (Ret != 0) { + int ret = baseResponse.getIntValue("Ret"); + if (ret != 0) { break; } } @@ -710,6 +770,13 @@ public class WebWeixinApi { /** * 发送图片消息 + * + * @param httpClient http客户端 + * @param urlVersion url版本号 + * @param passticket passticket + * @param baseRequest BaseRequest + * @param message 消息 + * @return 返回数据 */ public JSONObject sendImageMsg(HttpClient httpClient, String urlVersion, @@ -741,9 +808,7 @@ public class WebWeixinApi { HttpEntity entity = response.getEntity(); String res = EntityUtils.toString(entity, Consts.UTF_8); - JSONObject result = JSONObject.parseObject(res); - - return result; + return JSONObject.parseObject(res); } catch (Exception e) { logger.error("发送图片消息异常", e); return null; diff --git a/src/main/java/com/hotlcc/wechat4j/enums/ExitTypeEnum.java b/src/main/java/com/hotlcc/wechat4j/enums/ExitTypeEnum.java index 2657afc..f73e134 100644 --- a/src/main/java/com/hotlcc/wechat4j/enums/ExitTypeEnum.java +++ b/src/main/java/com/hotlcc/wechat4j/enums/ExitTypeEnum.java @@ -2,16 +2,24 @@ package com.hotlcc.wechat4j.enums; /** * 微信退出类型 + * + * @author Allen */ public enum ExitTypeEnum { - ERROR_EXIT("错误导致退出"), - LOCAL_EXIT("本次手动退出"), - REMOTE_EXIT("远程操作退出"); + /** + * 错误导致退出 + */ + ERROR_EXIT, + /** + * 本次手动退出 + */ + LOCAL_EXIT, + /** + * 远程操作退出 + */ + REMOTE_EXIT; - private String desc; - - ExitTypeEnum(String desc) { - this.desc = desc; + ExitTypeEnum() { } } diff --git a/src/main/java/com/hotlcc/wechat4j/enums/LoginTipEnum.java b/src/main/java/com/hotlcc/wechat4j/enums/LoginTipEnum.java index 76acd07..243e800 100644 --- a/src/main/java/com/hotlcc/wechat4j/enums/LoginTipEnum.java +++ b/src/main/java/com/hotlcc/wechat4j/enums/LoginTipEnum.java @@ -3,18 +3,22 @@ package com.hotlcc.wechat4j.enums; /** * 等待确认登录的tip * - * @author https://gitee.com/hotlcc + * @author Allen */ public enum LoginTipEnum { - TIP_0(0, "扫码登录"), - TIP_1(1, "确认登录"); + /** + * 扫码登录 + */ + TIP_0(0), + /** + * 确认登录 + */ + TIP_1(1); private int code; - private String desc; - LoginTipEnum(int code, String desc) { + LoginTipEnum(int code) { this.code = code; - this.desc = desc; } public int getCode() { diff --git a/src/main/java/com/hotlcc/wechat4j/util/QRCodeUtil.java b/src/main/java/com/hotlcc/wechat4j/util/QRCodeUtil.java index c87cc62..26cc1b6 100644 --- a/src/main/java/com/hotlcc/wechat4j/util/QRCodeUtil.java +++ b/src/main/java/com/hotlcc/wechat4j/util/QRCodeUtil.java @@ -22,6 +22,7 @@ import java.io.IOException; * * @author Allen */ +@SuppressWarnings({"unused", "WeakerAccess"}) public final class QRCodeUtil { private static Logger logger = LoggerFactory.getLogger(QRCodeUtil.class); @@ -31,7 +32,7 @@ public final class QRCodeUtil { /** * 从BitMatrix中得到boolean矩阵(不去除周围空白部分) * - * @return + * @return 得到的boolean矩阵 */ private static boolean[][] toBoolMatrix(BitMatrix matrix) { return toBoolMatrix(matrix, false); @@ -40,9 +41,9 @@ public final class QRCodeUtil { /** * 从BitMatrix中得到boolean矩阵 * - * @param matrix + * @param matrix BitMatrix * @param noMargin 是否去除周围空白 - * @return + * @return 得到的boolean矩阵 */ private static boolean[][] toBoolMatrix(BitMatrix matrix, boolean noMargin) { int width = matrix.getWidth(); @@ -57,8 +58,8 @@ public final class QRCodeUtil { right = width - br[1] - 1; } boolean[][] m = new boolean[height - top - bottom][width - left - right]; - for (int h = 0 + top, i = 0; h < height - bottom; h++, i++) { - for (int w = 0 + left, j = 0; w < width - right; w++, j++) { + for (int h = top, i = 0; h < height - bottom; h++, i++) { + for (int w = left, j = 0; w < width - right; w++, j++) { m[i][j] = matrix.get(w, h); } } @@ -68,8 +69,8 @@ public final class QRCodeUtil { /** * 将矩阵逆时针转90度 * - * @param matrix - * @return + * @param matrix 旋转前的矩阵 + * @return 旋转后的矩阵 */ private static boolean[][] reverseMatrix(boolean[][] matrix) { if (matrix == null) { @@ -92,15 +93,14 @@ public final class QRCodeUtil { /** * 从boolMatrix左上角判断二维码定位标记的大小 * - * @param boolMatrix - * @return + * @param boolMatrix bool矩阵 + * @return 定位标记大小 */ private static int getBitCharSize(boolean[][] boolMatrix) { int a = 0, b = 0; out: - for (int i = 0, len = boolMatrix.length; i < len; i++) { + for (boolean[] boolArr : boolMatrix) { boolean find = false; - boolean[] boolArr = boolMatrix[i]; for (int i2 = 0, len2 = boolArr.length; i2 < len2; i2++) { if (!find && boolArr[i2]) { find = true; @@ -119,20 +119,21 @@ public final class QRCodeUtil { /** * 从boolMatrix判断bit-char占位比 * - * @param boolMatrix - * @return + * @param boolMatrix bool矩阵 + * @return 占位比 */ private static int getBitCharRatio(boolean[][] boolMatrix) { + int len = 4; // 找出四个角的占位数 - int[] size = new int[4]; + int[] size = new int[len]; size[0] = getBitCharSize(boolMatrix); - for (int i = 1; i < 4; i++) { + for (int i = 1; i < len; i++) { boolMatrix = reverseMatrix(boolMatrix); size[i] = getBitCharSize(boolMatrix); } // 统计每个占位数出现的次数 - int[] num = new int[4]; - for (int i = 0; i < 4; i++) { + int[] num = new int[len]; + for (int i = 0; i < len; i++) { int n = 0; for (int s : size) { if (s == size[i]) { @@ -143,12 +144,12 @@ public final class QRCodeUtil { } // 找出最多的次数 int maxNum = num[0]; - for (int i = 1; i < 4; i++) { + for (int i = 1; i < len; i++) { maxNum = Math.max(maxNum, num[i]); } // 找出出现次数最多的占位数 int s = 0; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < len; i++) { if (num[i] == maxNum) { s = size[i]; } @@ -160,18 +161,20 @@ public final class QRCodeUtil { /** * 将二维码图片转为字符矩阵 * - * @param image - * @return + * @param image 二维码图片 + * @param onStr 实体字符串 + * @param offStr 空白字符串 + * @return 字符矩阵 */ public static String toCharMatrix(BufferedImage image, String onStr, String offStr) { LuminanceSource source = new BufferedImageLuminanceSource(image); Binarizer binarizer = new HybridBinarizer(source); - BitMatrix matrix = null; + BitMatrix matrix; try { matrix = binarizer.getBlackMatrix(); boolean[][] boolMatrix = toBoolMatrix(matrix, true); int ratio = getBitCharRatio(boolMatrix); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0, len = boolMatrix.length; i < len; i += ratio) { boolean[] boolArr = boolMatrix[i]; for (int i2 = 0, len2 = boolArr.length; i2 < len2; i2 += ratio) { @@ -189,8 +192,8 @@ public final class QRCodeUtil { /** * 将二维码图片转为字符矩阵 * - * @param image - * @return + * @param image 二维码图片 + * @return 字符矩阵 */ public static String toCharMatrix(BufferedImage image) { return toCharMatrix(image, " ", "██"); @@ -199,8 +202,10 @@ public final class QRCodeUtil { /** * 将二维码图片转为字符矩阵 * - * @param data - * @return + * @param data 二维码图片的字节数据 + * @param onStr 实体字符串 + * @param offStr 空白字符串 + * @return 字符矩阵 */ public static String toCharMatrix(byte[] data, String onStr, String offStr) { ByteArrayInputStream bais = null; @@ -225,8 +230,8 @@ public final class QRCodeUtil { /** * 将二维码图片转为字符矩阵 * - * @param data - * @return + * @param data 二维码图片的字节数据 + * @return 字符矩阵 */ public static String toCharMatrix(byte[] data) { return toCharMatrix(data, " ", "██"); @@ -235,8 +240,8 @@ public final class QRCodeUtil { /** * 将二维码图片数据写入到临时文件 * - * @param data - * @return + * @param data 二维码图片的字节数据 + * @return 字符矩阵 */ public static File writeToTempFile(byte[] data) { FileOutputStream fos = null; @@ -263,12 +268,12 @@ public final class QRCodeUtil { /** * 打开二维码图片 * - * @param data + * @param data 二维码图片的字节数据 */ public static void openQRCodeImage(byte[] data) { OperatingSystemEnum os = OperatingSystemEnum.currentOperatingSystem(); - Runtime runtime = null; - File tmp = null; + Runtime runtime; + File tmp; switch (os) { case WINDOWS: runtime = Runtime.getRuntime();