diff --git a/src/main/java/com/hotlcc/wechat4j/Wechat.java b/src/main/java/com/hotlcc/wechat4j/Wechat.java index 95ed37b..e490d41 100644 --- a/src/main/java/com/hotlcc/wechat4j/Wechat.java +++ b/src/main/java/com/hotlcc/wechat4j/Wechat.java @@ -6,10 +6,7 @@ import com.hotlcc.wechat4j.api.WebWeixinApi; import com.hotlcc.wechat4j.enums.*; import com.hotlcc.wechat4j.handler.ExitEventHandler; import com.hotlcc.wechat4j.handler.ReceivedMsgHandler; -import com.hotlcc.wechat4j.model.BaseRequest; -import com.hotlcc.wechat4j.model.ReceivedMsg; -import com.hotlcc.wechat4j.model.UserInfo; -import com.hotlcc.wechat4j.model.WxMessage; +import com.hotlcc.wechat4j.model.*; import com.hotlcc.wechat4j.util.*; import org.apache.http.HttpException; import org.apache.http.HttpRequest; @@ -17,6 +14,7 @@ import org.apache.http.HttpRequestInterceptor; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpClient; import org.apache.http.cookie.Cookie; +import org.apache.http.entity.ContentType; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HttpContext; @@ -1104,9 +1102,11 @@ public class Wechat { /** * 发送文本消息 * + * @param userName + * @param content * @return */ - public JSONObject sendText(String content, String userName) { + public JSONObject sendText(String userName, String content) { BaseRequest baseRequest = new BaseRequest(wxsid, skey, wxuin); String msgId = WechatUtil.createMsgId(); @@ -1131,11 +1131,11 @@ public class Wechat { /** * 发送文本消息(根据昵称) * - * @param content * @param nickName + * @param content * @return */ - public JSONObject sendTextToNickName(String content, String nickName) { + public JSONObject sendTextToNickName(String nickName, String content) { if (StringUtil.isEmpty(nickName)) { return sendText(content, null); } @@ -1156,11 +1156,11 @@ public class Wechat { /** * 发送文本消息(根据备注名) * - * @param content * @param remarkName + * @param content * @return */ - public JSONObject sendTextToRemarkName(String content, String remarkName) { + public JSONObject sendTextToRemarkName(String remarkName, String content) { if (StringUtil.isEmpty(remarkName)) { return sendText(content, null); } @@ -1181,13 +1181,13 @@ public class Wechat { /** * 发送文本消息(根据多种名称) * - * @param content * @param userName * @param nickName * @param remarkName + * @param content * @return */ - public JSONObject sendText(String content, String userName, String nickName, String remarkName) { + public JSONObject sendText(String userName, String nickName, String remarkName, String content) { UserInfo userInfo = null; if (StringUtil.isNotEmpty(userName)) { @@ -1211,15 +1211,196 @@ public class Wechat { return sendText(content, userName); } - //TODO 待完成 - @Deprecated - public JSONObject sendImage(File image, String userName) { + /** + * 发送图片消息 + * + * @param userName + * @param mediaData + * @param mediaName + * @param contentType + * @return + */ + public JSONObject sendImage(String userName, byte[] mediaData, String mediaName, ContentType contentType) { String loginUserName = getLoginUserName(false); String toUserName = StringUtil.isEmpty(userName) ? loginUserName : userName; BaseRequest baseRequest = new BaseRequest(wxsid, skey, wxuin); - String dataTicket = getCookieValue("webwx_data_ticket"); - JSONObject result = webWeixinApi.uploadMedia(httpClient, urlVersion, passTicket, baseRequest, loginUserName, toUserName, dataTicket, image); + // 上传媒体文件 + String dataTicket = getCookieValue("webwx_data_ticket"); + JSONObject result = webWeixinApi.uploadMedia(httpClient, urlVersion, passTicket, baseRequest, loginUserName, toUserName, dataTicket, mediaData, mediaName, contentType); + if (result == null) { + return null; + } + JSONObject BaseResponse = result.getJSONObject("BaseResponse"); + if (BaseResponse == null) { + return result; + } + int Ret = BaseResponse.getIntValue("Ret"); + if (Ret != 0) { + return result; + } + + String MediaId = result.getString("MediaId"); + if (StringUtil.isEmpty(MediaId)) { + return result; + } + + // 发送图片消息 + String msgId = WechatUtil.createMsgId(); + MediaMessage message = new MediaMessage(); + message.setClientMsgId(msgId); + message.setContent(""); + message.setFromUserName(loginUserName); + message.setLocalID(msgId); + message.setMediaId(MediaId); + message.setToUserName(toUserName); + message.setType(MsgTypeEnum.IMAGE_MSG.getCode()); + result = webWeixinApi.sendImageMsg(httpClient, urlVersion, passTicket, baseRequest, message); + return result; } + + /** + * 发送图片消息 + * + * @param userName + * @param image + * @return + */ + public JSONObject sendImage(String userName, File image) { + ContentType contentType = FileUtil.getContentBody(image); + byte[] mediaData = FileUtil.getBytes(image); + return sendImage(userName, mediaData, image.getName(), contentType); + } + + /** + * 发送图片消息(根据昵称) + * + * @param nickName + * @param mediaData + * @param mediaName + * @param contentType + * @return + */ + public JSONObject sendImageToNickName(String nickName, byte[] mediaData, String mediaName, ContentType contentType) { + if (StringUtil.isEmpty(nickName)) { + return sendImage(null, mediaData, mediaName, contentType); + } + + UserInfo userInfo = getContactByNickName(false, nickName); + if (userInfo == null) { + return null; + } + + String userName = userInfo.getUserName(); + if (StringUtil.isEmpty(userName)) { + return null; + } + + return sendImage(userName, mediaData, mediaName, contentType); + } + + /** + * 发送图片消息(根据昵称) + * + * @param nickName + * @param image + * @return + */ + public JSONObject sendImageToNickName(String nickName, File image) { + ContentType contentType = FileUtil.getContentBody(image); + byte[] mediaData = FileUtil.getBytes(image); + return sendImageToNickName(nickName, mediaData, image.getName(), contentType); + } + + /** + * 发送图片消息(根据备注名) + * + * @param remarkName + * @param mediaData + * @param mediaName + * @param contentType + * @return + */ + public JSONObject sendImageToRemarkName(String remarkName, byte[] mediaData, String mediaName, ContentType contentType) { + if (StringUtil.isEmpty(remarkName)) { + return sendImage(null, mediaData, mediaName, contentType); + } + + UserInfo userInfo = getContactByRemarkName(false, remarkName); + if (userInfo == null) { + return null; + } + + String userName = userInfo.getUserName(); + if (StringUtil.isEmpty(userName)) { + return null; + } + + return sendImage(userName, mediaData, mediaName, contentType); + } + + /** + * 发送图片消息(根据备注名) + * + * @param remarkName + * @param image + * @return + */ + public JSONObject sendImageToRemarkName(String remarkName, File image) { + ContentType contentType = FileUtil.getContentBody(image); + byte[] mediaData = FileUtil.getBytes(image); + return sendImageToRemarkName(remarkName, mediaData, image.getName(), contentType); + } + + /** + * 发送图片消息(根据多种名称) + * + * @param userName + * @param nickName + * @param remarkName + * @param mediaData + * @param mediaName + * @param contentType + * @return + */ + public JSONObject sendImage(String userName, String nickName, String remarkName + , byte[] mediaData, String mediaName, ContentType contentType) { + UserInfo userInfo = null; + + if (StringUtil.isNotEmpty(userName)) { + return sendImage(userName, mediaData, mediaName, contentType); + } else if (StringUtil.isNotEmpty(nickName)) { + userInfo = getContactByNickName(false, nickName); + } else if (StringUtil.isNotEmpty(remarkName)) { + userInfo = getContactByRemarkName(false, remarkName); + } else { + String loginUserName = getLoginUserName(false); + return sendImage(loginUserName, mediaData, mediaName, contentType); + } + + if (userInfo == null) { + return null; + } + userName = userInfo.getUserName(); + if (StringUtil.isEmpty(userName)) { + return null; + } + return sendImage(userName, mediaData, mediaName, contentType); + } + + /** + * 发送图片消息(根据多种名称) + * + * @param userName + * @param nickName + * @param remarkName + * @param image + * @return + */ + public JSONObject sendImage(String userName, String nickName, String remarkName, File image) { + ContentType contentType = FileUtil.getContentBody(image); + byte[] mediaData = FileUtil.getBytes(image); + return sendImage(userName, nickName, remarkName, mediaData, image.getName(), contentType); + } } diff --git a/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java b/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java index 4ede037..5e9b1e0 100644 --- a/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java +++ b/src/main/java/com/hotlcc/wechat4j/api/WebWeixinApi.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.hotlcc.wechat4j.enums.LoginTipEnum; import com.hotlcc.wechat4j.model.BaseRequest; +import com.hotlcc.wechat4j.model.MediaMessage; import com.hotlcc.wechat4j.model.WxMessage; import com.hotlcc.wechat4j.util.PropertiesUtil; import com.hotlcc.wechat4j.util.StringUtil; @@ -26,10 +27,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.stringtemplate.v4.ST; -import javax.activation.MimetypesFileTypeMap; -import java.io.File; -import java.io.FileInputStream; +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,13 +43,20 @@ import java.util.regex.Pattern; 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+?)\";"); private static Pattern PATTERN_REDIRECT_URI_3 = Pattern.compile("http(s*)://wx(\\d*)\\.qq\\.com\\/"); + /** + * 上传媒体文件分片大小 + */ + private static final int UPLOAD_MEDIA_FILE_CHUNK_SIZE = 524288; + /** * 获取微信uuid */ @@ -312,7 +319,7 @@ public class WebWeixinApi { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxinit_url")) .add("urlVersion", urlVersion) - .add("pass_ticket", passticket) + .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) .add("r", System.currentTimeMillis() / 1252L) .render(); @@ -353,7 +360,7 @@ public class WebWeixinApi { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.statusnotify_url")) .add("urlVersion", urlVersion) - .add("pass_ticket", passticket) + .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) .render(); HttpPost httpPost = new HttpPost(url); @@ -524,7 +531,7 @@ public class WebWeixinApi { .add("urlVersion", urlVersion) .add("skey", BaseRequest.getSkey()) .add("sid", BaseRequest.getSid()) - .add("pass_ticket", passticket) + .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) .render(); HttpPost httpPost = new HttpPost(url); @@ -563,7 +570,7 @@ public class WebWeixinApi { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsg_url")) .add("urlVersion", urlVersion) - .add("pass_ticket", passticket) + .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) .render(); HttpPost httpPost = new HttpPost(url); @@ -595,78 +602,18 @@ public class WebWeixinApi { } /** - * 上传媒体文件 - * - * @return - */ - public JSONObject uploadMedia(HttpClient httpClient, - String urlVersion, - String passticket, - BaseRequest BaseRequest, - String FromUserName, - String ToUserName, - String dataTicket, - byte[] data, - String fileName, - ContentType contentType) { - try { - String url = new ST(PropertiesUtil.getProperty("webwx-url.uploadmedia_url")) - .add("urlVersion", urlVersion) - .render(); - - HttpPost httpPost = new HttpPost(url); - httpPost.setHeader("Content-type", ContentType.MULTIPART_FORM_DATA.toString()); - - long millis = System.currentTimeMillis(); - - JSONObject uploadmediarequest = new JSONObject(); - uploadmediarequest.put("UploadType", 2); - uploadmediarequest.put("BaseRequest", BaseRequest); - uploadmediarequest.put("ClientMediaId", millis); - uploadmediarequest.put("TotalLen", data.length); - uploadmediarequest.put("StartPos", 0); - uploadmediarequest.put("DataLen", data.length); - uploadmediarequest.put("MediaType", 4); - uploadmediarequest.put("FromUserName", FromUserName); - uploadmediarequest.put("ToUserName", ToUserName); - uploadmediarequest.put("FileMd5", DigestUtils.md5(data)); - - HttpEntity paramEntity = MultipartEntityBuilder.create() - .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addTextBody("id", StringUtil.getUuid(), ContentType.TEXT_PLAIN) - .addTextBody("name", fileName, ContentType.TEXT_PLAIN) - .addTextBody("type", contentType.getMimeType(), ContentType.TEXT_PLAIN) - .addTextBody("lastModifieDate", millis + "", ContentType.TEXT_PLAIN) - .addTextBody("size", data.length + "", ContentType.TEXT_PLAIN) - .addTextBody("mediatype", WechatUtil.getMediatype(contentType.getMimeType()), ContentType.TEXT_PLAIN) - .addTextBody("uploadmediarequest", uploadmediarequest.toJSONString(), ContentType.TEXT_PLAIN) - .addTextBody("webwx_data_ticket", dataTicket, ContentType.TEXT_PLAIN) - .addTextBody("pass_ticket", passticket, ContentType.TEXT_PLAIN) - .addBinaryBody("filename", data, contentType, fileName) - .build(); - httpPost.setEntity(paramEntity); - - HttpResponse response = httpClient.execute(httpPost); - int statusCode = response.getStatusLine().getStatusCode(); - if (HttpStatus.SC_OK != statusCode) { - throw new RuntimeException("响应失败(" + statusCode + ")"); - } - - HttpEntity entity = response.getEntity(); - String res = EntityUtils.toString(entity, Consts.UTF_8); - - JSONObject result = JSONObject.parseObject(res); - - return result; - } catch (Exception e) { - logger.error("上传媒体文件异常", e); - return null; - } - } - - /** - * 上传媒体文件 + * 上传媒体文件(支持大文件自动分片上传) * + * @param httpClient + * @param urlVersion + * @param passticket + * @param baseRequest + * @param fromUserName + * @param toUserName + * @param dataTicket + * @param mediaData + * @param mediaName + * @param contentType * @return */ public JSONObject uploadMedia(HttpClient httpClient, @@ -676,44 +623,113 @@ public class WebWeixinApi { String fromUserName, String toUserName, String dataTicket, - File file) { + byte[] mediaData, + String mediaName, + ContentType contentType) { try { String url = new ST(PropertiesUtil.getProperty("webwx-url.uploadmedia_url")) .add("urlVersion", urlVersion) .render(); + long millis = System.currentTimeMillis(); + int mediaLength = mediaData.length; + // String mimeType = contentType.getMimeType(); + HttpPost httpPost = new HttpPost(url); httpPost.setHeader("Content-type", ContentType.MULTIPART_FORM_DATA.toString()); - long millis = System.currentTimeMillis(); - String contentTypeStr = new MimetypesFileTypeMap().getContentType(file); - ContentType contentType = ContentType.parse(contentTypeStr); - JSONObject uploadmediarequest = new JSONObject(); uploadmediarequest.put("UploadType", 2); uploadmediarequest.put("BaseRequest", baseRequest); uploadmediarequest.put("ClientMediaId", millis); - uploadmediarequest.put("TotalLen", file.length()); + uploadmediarequest.put("TotalLen", mediaLength); uploadmediarequest.put("StartPos", 0); - uploadmediarequest.put("DataLen", file.length()); + uploadmediarequest.put("DataLen", mediaLength); uploadmediarequest.put("MediaType", 4); uploadmediarequest.put("FromUserName", fromUserName); uploadmediarequest.put("ToUserName", toUserName); - uploadmediarequest.put("FileMd5", DigestUtils.md5(new FileInputStream(file))); + uploadmediarequest.put("FileMd5", DigestUtils.md5Hex(mediaData)); - HttpEntity paramEntity = MultipartEntityBuilder.create() - .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addTextBody("id", StringUtil.getUuid(), ContentType.TEXT_PLAIN) - .addTextBody("name", file.getName(), ContentType.TEXT_PLAIN) - .addTextBody("type", contentTypeStr, ContentType.TEXT_PLAIN) - .addTextBody("lastModifieDate", millis + "", ContentType.TEXT_PLAIN) - .addTextBody("size", file.length() + "", ContentType.TEXT_PLAIN) - .addTextBody("mediatype", WechatUtil.getMediatype(contentType.getMimeType()), ContentType.TEXT_PLAIN) - .addTextBody("uploadmediarequest", uploadmediarequest.toJSONString(), ContentType.TEXT_PLAIN) - .addTextBody("webwx_data_ticket", dataTicket, ContentType.TEXT_PLAIN) - .addTextBody("pass_ticket", passticket, ContentType.TEXT_PLAIN) - .addBinaryBody("filename", file, contentType, file.getName()) - .build(); + // 分片数量 + int chunks = new BigDecimal(mediaLength).divide(new BigDecimal(UPLOAD_MEDIA_FILE_CHUNK_SIZE), 0, BigDecimal.ROUND_UP).intValue(); + + JSONObject result = null; + for (int chunk = 0; chunk < chunks; chunk++) { + int from = chunk * UPLOAD_MEDIA_FILE_CHUNK_SIZE; + int to = (chunk + 1) * UPLOAD_MEDIA_FILE_CHUNK_SIZE; + to = Math.min(to, mediaLength); + byte[] temp = Arrays.copyOfRange(mediaData, from, to); + + HttpEntity paramEntity = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + // .addTextBody("id", StringUtil.getUuid(), ContentType.TEXT_PLAIN) + // .addTextBody("name", mediaName, ContentType.TEXT_PLAIN) + // .addTextBody("type", mimeType, ContentType.TEXT_PLAIN) + // .addTextBody("lastModifieDate", String.valueOf(millis), ContentType.TEXT_PLAIN) + // .addTextBody("size", String.valueOf(mediaLength), ContentType.TEXT_PLAIN) + .addTextBody("chunks", String.valueOf(chunks)) + .addTextBody("chunk", String.valueOf(chunk)) + // .addTextBody("mediatype", WechatUtil.getMediatype(mimeType), ContentType.TEXT_PLAIN) + .addTextBody("uploadmediarequest", uploadmediarequest.toJSONString(), ContentType.TEXT_PLAIN) + .addTextBody("webwx_data_ticket", dataTicket, ContentType.TEXT_PLAIN) + .addTextBody("pass_ticket", passticket, ContentType.TEXT_PLAIN) + .addBinaryBody("filename", temp, contentType, mediaName) + .build(); + httpPost.setEntity(paramEntity); + + HttpResponse response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (HttpStatus.SC_OK != statusCode) { + throw new RuntimeException("响应失败(" + statusCode + ")"); + } + + HttpEntity entity = response.getEntity(); + String res = EntityUtils.toString(entity, Consts.UTF_8); + + result = JSONObject.parseObject(res); + if (result == null) { + break; + } + + JSONObject BaseResponse = result.getJSONObject("BaseResponse"); + if (BaseResponse == null) { + break; + } + int Ret = BaseResponse.getIntValue("Ret"); + if (Ret != 0) { + break; + } + } + + return result; + } catch (Exception e) { + logger.error("上传媒体文件异常", e); + return null; + } + } + + /** + * 发送图片消息 + */ + public JSONObject sendImageMsg(HttpClient httpClient, + String urlVersion, + String passticket, + BaseRequest baseRequest, + MediaMessage message) { + try { + String url = new ST(PropertiesUtil.getProperty("webwx-url.webwxsendmsgimg_url")) + .add("urlVersion", urlVersion) + .add("pass_ticket", StringUtil.encodeURL(passticket, Consts.UTF_8.name())) + .render(); + + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); + + JSONObject paramJson = new JSONObject(); + paramJson.put("BaseRequest", baseRequest); + paramJson.put("Msg", message); + paramJson.put("Scene", 0); + HttpEntity paramEntity = new StringEntity(paramJson.toJSONString(), Consts.UTF_8); httpPost.setEntity(paramEntity); HttpResponse response = httpClient.execute(httpPost); @@ -729,7 +745,7 @@ public class WebWeixinApi { return result; } catch (Exception e) { - logger.error("上传媒体文件异常", e); + logger.error("发送图片消息异常", e); return null; } } diff --git a/src/main/java/com/hotlcc/wechat4j/model/AppInfo.java b/src/main/java/com/hotlcc/wechat4j/model/AppInfo.java index 780f828..40f17b3 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/AppInfo.java +++ b/src/main/java/com/hotlcc/wechat4j/model/AppInfo.java @@ -5,11 +5,14 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import lombok.Getter; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Getter -public final class AppInfo { +public final class AppInfo implements Serializable { + private static final long serialVersionUID = 1L; + private AppInfo() { } diff --git a/src/main/java/com/hotlcc/wechat4j/model/BaseRequest.java b/src/main/java/com/hotlcc/wechat4j/model/BaseRequest.java index 9f77c74..be0883e 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/BaseRequest.java +++ b/src/main/java/com/hotlcc/wechat4j/model/BaseRequest.java @@ -5,12 +5,16 @@ import com.hotlcc.wechat4j.util.WechatUtil; import lombok.Getter; import lombok.Setter; +import java.io.Serializable; + /** * 基本请求模型 */ @Getter @Setter -public class BaseRequest { +public class BaseRequest implements Serializable { + private static final long serialVersionUID = 1L; + public BaseRequest() { } diff --git a/src/main/java/com/hotlcc/wechat4j/model/MediaMessage.java b/src/main/java/com/hotlcc/wechat4j/model/MediaMessage.java new file mode 100644 index 0000000..b925401 --- /dev/null +++ b/src/main/java/com/hotlcc/wechat4j/model/MediaMessage.java @@ -0,0 +1,15 @@ +package com.hotlcc.wechat4j.model; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Getter; +import lombok.Setter; + +/** + * 媒体消息 + */ +@Getter +@Setter +public class MediaMessage extends WxMessage { + @JSONField(name = "MediaId") + private String mediaId; +} diff --git a/src/main/java/com/hotlcc/wechat4j/model/ReceivedMsg.java b/src/main/java/com/hotlcc/wechat4j/model/ReceivedMsg.java index d5d56be..93a905d 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/ReceivedMsg.java +++ b/src/main/java/com/hotlcc/wechat4j/model/ReceivedMsg.java @@ -5,11 +5,14 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import lombok.Getter; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Getter -public final class ReceivedMsg { +public final class ReceivedMsg implements Serializable { + private static final long serialVersionUID = 1L; + private ReceivedMsg() { } diff --git a/src/main/java/com/hotlcc/wechat4j/model/RecommendInfo.java b/src/main/java/com/hotlcc/wechat4j/model/RecommendInfo.java index bbc177d..269cfc5 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/RecommendInfo.java +++ b/src/main/java/com/hotlcc/wechat4j/model/RecommendInfo.java @@ -5,11 +5,14 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import lombok.Getter; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Getter -public final class RecommendInfo { +public final class RecommendInfo implements Serializable { + private static final long serialVersionUID = 1L; + private RecommendInfo() { } diff --git a/src/main/java/com/hotlcc/wechat4j/model/UserInfo.java b/src/main/java/com/hotlcc/wechat4j/model/UserInfo.java index 6eba56a..d7dcced 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/UserInfo.java +++ b/src/main/java/com/hotlcc/wechat4j/model/UserInfo.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import lombok.Getter; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -12,7 +13,9 @@ import java.util.List; * 微信用户信息 */ @Getter -public final class UserInfo { +public final class UserInfo implements Serializable { + private static final long serialVersionUID = 1L; + private UserInfo() { } diff --git a/src/main/java/com/hotlcc/wechat4j/model/WxMessage.java b/src/main/java/com/hotlcc/wechat4j/model/WxMessage.java index 05db641..f6ffb89 100644 --- a/src/main/java/com/hotlcc/wechat4j/model/WxMessage.java +++ b/src/main/java/com/hotlcc/wechat4j/model/WxMessage.java @@ -4,12 +4,16 @@ import com.alibaba.fastjson.annotation.JSONField; import lombok.Getter; import lombok.Setter; +import java.io.Serializable; + /** * 要发送的消息 */ @Getter @Setter -public class WxMessage { +public class WxMessage implements Serializable { + private static final long serialVersionUID = 1L; + @JSONField(name = "ClientMsgId") private String clientMsgId; @JSONField(name = "Content") diff --git a/src/main/java/com/hotlcc/wechat4j/util/FileUtil.java b/src/main/java/com/hotlcc/wechat4j/util/FileUtil.java new file mode 100644 index 0000000..f9cb3a0 --- /dev/null +++ b/src/main/java/com/hotlcc/wechat4j/util/FileUtil.java @@ -0,0 +1,70 @@ +package com.hotlcc.wechat4j.util; + +import org.apache.http.entity.ContentType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.activation.MimetypesFileTypeMap; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * 文件工具类 + */ +public final class FileUtil { + private static Logger logger = LoggerFactory.getLogger(FileUtil.class); + + private FileUtil() { + } + + public static byte[] getBytes(File file) { + if (file == null) { + throw new IllegalArgumentException("参数file不能为null"); + } + + FileInputStream fis = null; + ByteArrayOutputStream baos = null; + try { + fis = new FileInputStream(file); + baos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + int len; + + while ((len = fis.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + + baos.flush(); + baos.close(); + fis.close(); + + return baos.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (baos != null) { + try { + baos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public static ContentType getContentBody(File file) { + String mimeType = new MimetypesFileTypeMap().getContentType(file); + ContentType contentType = ContentType.parse(mimeType); + return contentType; + } +} diff --git a/src/main/resources/META-INF/wechat4j/webwx-url.properties b/src/main/resources/META-INF/wechat4j/webwx-url.properties index f3176ac..cce8015 100644 --- a/src/main/resources/META-INF/wechat4j/webwx-url.properties +++ b/src/main/resources/META-INF/wechat4j/webwx-url.properties @@ -29,4 +29,6 @@ webwx-url.webwxsync_url=https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxs ## 4.2、发送消息 webwx-url.webwxsendmsg_url=https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket= ## 4.3、上传媒体文件 -webwx-url.uploadmedia_url=https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json \ No newline at end of file +webwx-url.uploadmedia_url=https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json +## 4.4、发送图片消息 +webwx-url.webwxsendmsgimg_url=https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket= \ No newline at end of file diff --git a/src/test/java/TestClass.java b/src/test/java/TestClass.java index 707b815..0a0cf5b 100644 --- a/src/test/java/TestClass.java +++ b/src/test/java/TestClass.java @@ -1,14 +1,22 @@ +import com.alibaba.fastjson.JSONObject; import com.hotlcc.wechat4j.Wechat; import com.hotlcc.wechat4j.api.WebWeixinApi; import com.hotlcc.wechat4j.handler.ReceivedMsgHandler; import com.hotlcc.wechat4j.model.ReceivedMsg; import com.hotlcc.wechat4j.model.UserInfo; import com.hotlcc.wechat4j.util.StringUtil; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; public class TestClass { - public static void main(String[] args) { + private Wechat wechat; + + @Before + public void initAndLogin() { + wechat = new Wechat(); WebWeixinApi api = new WebWeixinApi(); - Wechat wechat = new Wechat(); wechat.setWebWeixinApi(api); wechat.addReceivedMsgHandler(new ReceivedMsgHandler() { @Override @@ -18,6 +26,15 @@ public class TestClass { System.out.println(name + ": " + msg.getContent()); } }); + wechat.autoLogin(); } + + @Test + public void testSendImage() { + File file = new File("D:\\Downloads\\images\\6600e90b8b0ce2037a5291a7147ffd2b.jpeg"); + + JSONObject result = wechat.sendImage(null, file); + System.out.println(result); + } }