2
0
mirror of https://gitee.com/hotlcc/wechat4j.git synced 2025-12-24 02:49:37 +08:00

init code

This commit is contained in:
hotlcc
2018-07-22 19:00:30 +08:00
parent 0ddb01be72
commit bd6c61b3c3
12 changed files with 1480 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
package com.hotlcc.wechat4j;
import com.hotlcc.wechat4j.api.WebWeixinApi;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 微信客户端
*
* @author Allen
*/
public class Wechat {
private static Logger logger = LoggerFactory.getLogger(Wechat.class);
private CookieStore cookieStore;
private HttpClient httpClient;
private WebWeixinApi webWeixinApi;
public void setWebWeixinApi(WebWeixinApi webWeixinApi) {
this.webWeixinApi = webWeixinApi;
}
public Wechat(CookieStore cookieStore) {
this.cookieStore = cookieStore;
this.httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
}
public Wechat() {
this.cookieStore = new BasicCookieStore();
this.httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
}
/**
* 自动登录
*/
public void autoLogin() {
}
}

View File

@@ -0,0 +1,582 @@
package com.hotlcc.wechat4j.api;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hotlcc.wechat4j.util.PropertiesUtil;
import com.hotlcc.wechat4j.util.StringUtil;
import com.hotlcc.wechat4j.util.WechatUtil;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* web微信接口封装
*
* @author Allen
*/
@SuppressWarnings("Duplicates")
public class WebWeixinApi {
private static Logger logger = LoggerFactory.getLogger(WebWeixinApi.class);
private static Pattern PATTERN_UUID_1 = Pattern.compile("window.QRLogin.code = (\\d+);");
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+?)\";");
/**
* 获取微信uuid
*/
public JSONObject getWxUuid(HttpClient httpClient) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.uuid_url"))
.add("appid", PropertiesUtil.getProperty("webwx.appid"))
.add("_", System.currentTimeMillis())
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
JSONObject result = new JSONObject();
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
Matcher matcher = PATTERN_UUID_1.matcher(res);
if (!matcher.find()) {
throw new RuntimeException("获取登录uuid失败");
}
String code = matcher.group(1);
result.put("code", code);
if (!"200".equals(code)) {
result.put("code", code);
result.put("msg", "获取登录uuid失败请确认appid是否有效");
return result;
}
matcher = PATTERN_UUID_2.matcher(res);
if (!matcher.find()) {
throw new RuntimeException("获取登录uuid失败");
}
String uuid = matcher.group(2);
result.put("uuid", uuid);
if (StringUtil.isEmpty(uuid)) {
throw new RuntimeException("获取登录uuid失败");
}
return result;
} catch (IOException e) {
logger.error("获取登录uuid异常", e);
result.put("code", "-1");
result.put("msg", "获取登录uuid异常");
return result;
}
}
/**
* 获取二维码
*
* @param uuid
*/
public JSONObject getQR(HttpClient httpClient,
String uuid) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.qrcode_url"))
.add("uuid", uuid)
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
JSONObject result = new JSONObject();
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
byte[] data = EntityUtils.toByteArray(entity);
if (data == null || data.length <= 0) {
throw new RuntimeException("获取二维码失败");
}
result.put("code", "200");
result.put("data", data);
return result;
} catch (IOException e) {
logger.error("获取二维码异常", e);
result.put("code", "-1");
result.put("msg", "获取二维码异常");
return result;
}
}
/**
* 获取跳转uri等待扫码认证
*
* @return
*/
public JSONObject getRedirectUri(HttpClient httpClient,
String uuid) {
long millis = System.currentTimeMillis();
String url = new ST(PropertiesUtil.getProperty("webwx-url.redirect_uri"))
.add("uuid", uuid)
.add("r", millis / 1252L)
.add("_", millis)
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
JSONObject result = new JSONObject();
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
Matcher matcher = PATTERN_REDIRECT_URI_1.matcher(res);
if (!matcher.find()) {
throw new RuntimeException("获取跳转uri失败");
}
String code = matcher.group(1);
result.put("code", code);
if ("408".equals(code)) {
result.put("msg", "请扫描二维码");
} else if ("400".equals(code)) {
result.put("msg", "二维码失效");
} else if ("201".equals(code)) {
result.put("msg", "请在手机上点击确认");
} else if ("200".equals(code)) {
matcher = PATTERN_REDIRECT_URI_2.matcher(res);
if (!matcher.find()) {
throw new RuntimeException("获取跳转uri失败");
}
result.put("msg", "手机确认成功");
result.put("redirectUri", matcher.group(2));
} else {
result.put("msg", "扫码失败");
}
return result;
} catch (IOException e) {
logger.error("获取跳转uri异常", e);
result.put("code", "-3");
result.put("msg", "获取跳转uri异常");
return result;
}
}
/**
* 获取登录认证码
* 此方法执行后其它web端微信、pc端都会下线
*/
public JSONObject getLoginCode(HttpClient httpClient,
String redirectUri) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.newlogin_url"))
.add("redirectUri", redirectUri)
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
JSONObject result = new JSONObject();
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
JSONObject json = JSONObject.parseObject(XML.toJSONObject(res).toString()).getJSONObject("error");
result.putAll(json);
result.put("msg", result.getString("message"));
if (result.getIntValue("ret") == 0) {
result.put("code", "200");
}
return result;
} catch (IOException e) {
logger.error("获取登录认证码异常", e);
result.put("code", "-1");
result.put("msg", "获取登录认证码异常");
return result;
}
}
/**
* 退出登录
*/
public void logout(HttpClient httpClient,
String wxsid,
String skey,
String wxuin) {
//type=0
String url = new ST(PropertiesUtil.getProperty("webwx-url.logout_url"))
.add("type", 0)
.add("skey", StringUtil.encodeURL(skey, "UTF-8"))
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_FORM_URLENCODED.toString());
List<NameValuePair> pairList = new ArrayList<>();
pairList.add(new BasicNameValuePair("sid", wxsid));
pairList.add(new BasicNameValuePair("uin", wxuin));
try {
HttpEntity paramEntity = new UrlEncodedFormEntity(pairList);
httpPost.setEntity(paramEntity);
httpClient.execute(httpPost);
} catch (IOException e) {
logger.error("退出登录异常", e);
}
//type=1
String url1 = new ST(PropertiesUtil.getProperty("webwx-url.logout_url"))
.add("type", 1)
.add("skey", StringUtil.encodeURL(skey, "UTF-8"))
.render();
HttpPost httpPost1 = new HttpPost(url1);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_FORM_URLENCODED.toString());
try {
HttpEntity paramEntity = new UrlEncodedFormEntity(pairList);
httpPost.setEntity(paramEntity);
httpClient.execute(httpPost1);
} catch (IOException e) {
logger.error("退出登录异常", e);
}
}
/**
* 数据初始化
*/
public JSONObject webWeixinInit(HttpClient httpClient,
String passticket,
String wxsid,
String skey,
String wxuin) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxinit_url"))
.add("pass_ticket", passticket)
.add("r", System.currentTimeMillis() / 1252L)
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", WechatUtil.createBaseRequest(wxsid, skey, wxuin));
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity, Consts.UTF_8);
return JSONObject.parseObject(res);
} catch (IOException e) {
logger.error("数据初始化异常", e);
return null;
}
}
/**
* 开启消息状态通知
*
* @return
*/
public JSONObject statusNotify(HttpClient httpClient,
String passticket,
String wxsid,
String skey,
String wxuin,
String loginUserName) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.statusnotify_url"))
.add("pass_ticket", passticket)
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", WechatUtil.createBaseRequest(wxsid, skey, wxuin));
paramJson.put("ClientMsgId", System.currentTimeMillis());
paramJson.put("Code", 3);
paramJson.put("FromUserName", loginUserName);
paramJson.put("ToUserName", loginUserName);
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity, Consts.UTF_8);
return JSONObject.parseObject(res);
} catch (IOException e) {
logger.error("开启消息状态通知异常", e);
return null;
}
}
/**
* 服务端状态同步心跳
*/
public JSONObject syncCheck(HttpClient httpClient,
String wxsid,
String skey,
String wxuin,
JSONArray SyncKeyList) {
long millis = System.currentTimeMillis();
String url = new ST(PropertiesUtil.getProperty("webwx-url.synccheck_url"))
.add("r", millis)
.add("skey", StringUtil.encodeURL(skey, "UTF-8"))
.add("sid", wxsid)
.add("uin", wxuin)
.add("deviceid", WechatUtil.createDeviceID())
.add("synckey", StringUtil.encodeURL(WechatUtil.syncKeyListToString(SyncKeyList), "UTF-8"))
.add("_", millis)
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
String regExp = "window.synccheck=\\{retcode:\"(\\d+)\",selector:\"(\\d+)\"}";
Matcher matcher = Pattern.compile(regExp).matcher(res);
if (!matcher.find()) {
throw new RuntimeException("服务端状态同步失败");
}
JSONObject result = new JSONObject();
result.put("retcode", matcher.group(1));
result.put("selector", matcher.group(2));
return result;
} catch (IOException e) {
logger.error("服务端状态同步异常", e);
return null;
}
}
/**
* 获取全部联系人列表
*/
public JSONObject getContact(HttpClient httpClient,
String passticket,
String skey) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.getcontact_url"))
.add("pass_ticket", StringUtil.encodeURL(passticket, "UTF-8"))
.add("r", System.currentTimeMillis())
.add("skey", StringUtil.encodeURL(skey, "UTF-8"))
.render();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
try {
HttpResponse response = httpClient.execute(httpGet);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
return JSONObject.parseObject(res);
} catch (IOException e) {
logger.error("获取全部联系人列表异常", e);
return null;
}
}
/**
* 批量获取指定用户信息
*/
public JSONObject batchGetContact(HttpClient httpClient,
String passticket,
String wxsid,
String skey,
String wxuin,
JSONArray batchContactList) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.batchgetcontact_url"))
.add("pass_ticket", StringUtil.encodeURL(passticket, "UTF-8"))
.add("r", System.currentTimeMillis())
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", WechatUtil.createBaseRequest(wxsid, skey, wxuin));
paramJson.put("Count", batchContactList.size());
paramJson.put("List", batchContactList);
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity);
return JSONObject.parseObject(res);
} catch (IOException e) {
logger.error("批量获取指定联系人信息异常", e);
return null;
}
}
/**
* 从服务端拉取新消息
*/
public JSONObject pullNewMsg(HttpClient httpClient,
String passticket,
String wxsid,
String skey,
String wxuin,
JSONObject SyncKey) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsync_url"))
.add("skey", skey)
.add("sid", wxsid)
.add("pass_ticket", passticket)
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", WechatUtil.createBaseRequest(wxsid, skey, wxuin));
paramJson.put("SyncKey", SyncKey);
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity, Consts.UTF_8);
return JSONObject.parseObject(res);
} catch (IOException e) {
logger.error("开启消息状态通知异常", e);
return null;
}
}
/**
* 发送消息
*/
public JSONObject sendMsg(HttpClient httpClient,
String passticket,
String wxsid,
String skey,
String wxuin,
String Content,
int Type,
String FromUserName,
String ToUserName) {
String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsg_url"))
.add("pass_ticket", passticket)
.render();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("User-Agent", PropertiesUtil.getProperty("wechat4j.userAgent"));
httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString());
JSONObject paramJson = new JSONObject();
paramJson.put("BaseRequest", WechatUtil.createBaseRequest(wxsid, skey, wxuin));
paramJson.put("Msg", WechatUtil.createSendMsg(Content, Type, FromUserName, ToUserName));
paramJson.put("Scene", 0);
HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8);
httpPost.setEntity(paramEntity);
try {
HttpResponse response = httpClient.execute(httpPost);
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
throw new RuntimeException("请求错误");
}
HttpEntity entity = response.getEntity();
String res = EntityUtils.toString(entity, Consts.UTF_8);
JSONObject result = JSONObject.parseObject(res);
return result;
} catch (IOException e) {
logger.error("开启消息状态通知异常", e);
return null;
}
}
}

View File

@@ -0,0 +1,56 @@
package com.hotlcc.wechat4j.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public final class PropertiesUtil {
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private PropertiesUtil() {
}
private static final Properties prop = new Properties();
static {
loadProperties(new String[]{
"config/app.properties",
"config/webwx-url.properties"
});
}
private static void loadProperties(String[] paths) {
if (paths == null) {
return;
}
for (String path : paths) {
InputStream is = null;
try {
is = PropertiesUtil.class.getClassLoader().getResourceAsStream(path);
prop.load(is);
} catch (Exception e) {
logger.error("Loading properties file \"" + path + "\" error.", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static String getProperty(String key) {
return prop.getProperty(key);
}
public static String getProperty(String key, String defaultValue) {
return prop.getProperty(key, defaultValue);
}
}

View File

@@ -0,0 +1,230 @@
package com.hotlcc.wechat4j.util;
import com.google.zxing.Binarizer;
import com.google.zxing.LuminanceSource;
import com.google.zxing.NotFoundException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 二维码工具类
*
* @author Allen
*/
public final class QRCodeUtil {
private QRCodeUtil() {
}
/**
* 从BitMatrix中得到boolean矩阵不去除周围空白部分
*
* @return
*/
private static boolean[][] toBoolMatrix(BitMatrix matrix) {
return toBoolMatrix(matrix, false);
}
/**
* 从BitMatrix中得到boolean矩阵
*
* @param matrix
* @param noMargin 是否去除周围空白
* @return
*/
private static boolean[][] toBoolMatrix(BitMatrix matrix, boolean noMargin) {
int width = matrix.getWidth();
int height = matrix.getHeight();
int top = 0, left = 0, bottom = 0, right = 0;
if (noMargin) {
int[] tl = matrix.getTopLeftOnBit();
top = tl[0];
left = tl[1];
int[] br = matrix.getBottomRightOnBit();
bottom = height - br[0] - 1;
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++) {
m[i][j] = matrix.get(w, h);
}
}
return m;
}
/**
* 将矩阵逆时针转90度
*
* @param matrix
* @return
*/
private static boolean[][] reverseMatrix(boolean[][] matrix) {
if (matrix == null) {
return null;
}
int height = matrix.length;
int width = matrix[0].length;
boolean[][] matrix2 = new boolean[width][height];
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
matrix2[width - 1 - w][h] = matrix[h][w];
}
}
return matrix2;
}
/**
* 从boolMatrix左上角判断二维码定位标记的大小
*
* @param boolMatrix
* @return
*/
private static int getBitCharSize(boolean[][] boolMatrix) {
int a = 0, b = 0;
out:
for (int i = 0, len = boolMatrix.length; i < len; i++) {
boolean find = false;
boolean[] boolArr = boolMatrix[i];
for (int i2 = 0, len2 = boolArr.length; i2 < len2; i2++) {
if (!find && boolArr[i2]) {
find = true;
a = i2;
}
if (find && !boolArr[i2]) {
b = i2;
break out;
}
}
}
return (b - a);
}
/**
* 从boolMatrix判断bit-char占位比
*
* @param boolMatrix
* @return
*/
private static int getBitCharRatio(boolean[][] boolMatrix) {
int[] size = new int[4];
size[0] = getBitCharSize(boolMatrix);
for (int i = 1; i < 4; i++) {
boolMatrix = reverseMatrix(boolMatrix);
size[i] = getBitCharSize(boolMatrix);
}
Map<Integer, Integer> map = new HashMap<>();
for (int s : size) {
Integer count = map.get(s);
if (count == null) {
map.put(s, 1);
} else {
map.put(s, count + 1);
}
}
Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
Integer k = null, v = null;
int flag = 0;
for (Map.Entry<Integer, Integer> entry : entrySet) {
if (flag++ == 0) {
k = entry.getKey();
v = entry.getValue();
continue;
}
if (entry.getValue() > v) {
k = entry.getKey();
v = entry.getValue();
}
}
return k.intValue() / 7;
}
/**
* 将二维码图片转为字符矩阵
*
* @param image
* @return
*/
public static String toCharMatrix(BufferedImage image, String onStr, String offStr) {
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BitMatrix matrix = null;
try {
matrix = binarizer.getBlackMatrix();
boolean[][] boolMatrix = toBoolMatrix(matrix, true);
int ratio = getBitCharRatio(boolMatrix);
StringBuffer sb = new StringBuffer();
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) {
sb.append(boolArr[i2] ? onStr : offStr);
}
sb.append("\n");
}
return sb.toString();
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
}
/**
* 将二维码图片转为字符矩阵
*
* @param image
* @return
*/
public static String toCharMatrix(BufferedImage image) {
return toCharMatrix(image, " ", "██");
}
/**
* 将二维码图片转为字符矩阵
*
* @param data
* @return
*/
public static String toCharMatrix(byte[] data, String onStr, String offStr) {
ByteArrayInputStream bais = null;
try {
bais = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(bais);
return QRCodeUtil.toCharMatrix(image, onStr, offStr);
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (bais != null) {
try {
bais.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 将二维码图片转为字符矩阵
*
* @param data
* @return
*/
public static String toCharMatrix(byte[] data) {
return toCharMatrix(data, " ", "██");
}
}

View File

@@ -0,0 +1,34 @@
package com.hotlcc.wechat4j.util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
public final class StringUtil {
private StringUtil() {
}
public static boolean isEmpty(String str) {
return str == null || "".equals(str);
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
public static String encodeURL(String str, String enc) {
try {
return URLEncoder.encode(str, enc);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static String decodeURL(String str, String enc) {
try {
return URLDecoder.decode(str, enc);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,94 @@
package com.hotlcc.wechat4j.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.RandomStringUtils;
public final class WechatUtil {
private WechatUtil() {
}
private static String STRING_CHARS_1 = "123456789";
private static String STRING_CHARS_2 = "1234567890";
/**
* 创建一个设备ID
*
* @return
*/
public static String createDeviceID() {
return "e" + RandomStringUtils.random(15, STRING_CHARS_1);
}
/**
* 创建一个消息ID
*
* @return
*/
public static String createMsgId() {
return System.currentTimeMillis() + RandomStringUtils.random(4, STRING_CHARS_2);
}
/**
* 创建BaseRequest
*
* @return
*/
public static JSONObject createBaseRequest(String DeviceID, String wxsid, String skey, String wxuin) {
JSONObject BaseRequest = new JSONObject();
BaseRequest.put("DeviceID", DeviceID);
BaseRequest.put("Sid", wxsid);
BaseRequest.put("Skey", skey);
BaseRequest.put("Uin", wxuin);
return BaseRequest;
}
/**
* 创建BaseRequest
*
* @return
*/
public static JSONObject createBaseRequest(String wxsid, String skey, String wxuin) {
return createBaseRequest(createDeviceID(), wxsid, skey, wxuin);
}
/**
* 把SyncKeyList转为字符串格式
*
* @param SyncKeyList
* @return
*/
public static String syncKeyListToString(JSONArray SyncKeyList) {
if (SyncKeyList == null) {
return null;
}
StringBuffer synckey = new StringBuffer();
for (int i = 0, len = SyncKeyList.size(); i < len; i++) {
JSONObject json = SyncKeyList.getJSONObject(i);
if (i > 0) {
synckey.append("|");
}
synckey.append(json.getString("Key"))
.append("_")
.append(json.getString("Val"));
}
return synckey.toString();
}
/**
* 创建要发送的Msg
*
* @return
*/
public static JSONObject createSendMsg(String Content, int Type, String FromUserName, String ToUserName) {
JSONObject Msg = new JSONObject();
String msgId = WechatUtil.createMsgId();
Msg.put("ClientMsgId", msgId);
Msg.put("Content", Content);
Msg.put("FromUserName", FromUserName);
Msg.put("LocalID", msgId);
Msg.put("ToUserName", ToUserName);
Msg.put("Type", Type);
return Msg;
}
}