@@ -6,7 +6,7 @@ | |||||
<modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>2.8.0</version> | |||||
<version>2.9.0</version> | |||||
<packaging>pom</packaging> | <packaging>pom</packaging> | ||||
<name>WeiXin Java Tools - Parent</name> | <name>WeiXin Java Tools - Parent</name> | ||||
<description>微信公众号、企业号上级POM</description> | <description>微信公众号、企业号上级POM</description> | ||||
@@ -80,6 +80,11 @@ | |||||
<email>crskyp@gmail.com</email> | <email>crskyp@gmail.com</email> | ||||
<url>https://github.com/crskyp</url> | <url>https://github.com/crskyp</url> | ||||
</developer> | </developer> | ||||
<developer> | |||||
<name>007</name> | |||||
<email>007gzs@gmail.com</email> | |||||
<url>https://github.com/007gzs</url> | |||||
</developer> | |||||
</developers> | </developers> | ||||
<scm> | <scm> | ||||
@@ -94,6 +99,7 @@ | |||||
<module>weixin-java-mp</module> | <module>weixin-java-mp</module> | ||||
<module>weixin-java-pay</module> | <module>weixin-java-pay</module> | ||||
<module>weixin-java-miniapp</module> | <module>weixin-java-miniapp</module> | ||||
<module>weixin-java-open</module> | |||||
<!--module>weixin-java-osgi</module--> | <!--module>weixin-java-osgi</module--> | ||||
</modules> | </modules> | ||||
@@ -225,6 +231,12 @@ | |||||
<version>2.9.0</version> | <version>2.9.0</version> | ||||
<scope>provided</scope> | <scope>provided</scope> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
<version>1.16.18</version> | |||||
<scope>compile</scope> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</dependencyManagement> | </dependencyManagement> | ||||
@@ -40,7 +40,7 @@ | |||||
<property name="allowNonPrintableEscapes" value="true"/> | <property name="allowNonPrintableEscapes" value="true"/> | ||||
</module> | </module> | ||||
<module name="LineLength"> | <module name="LineLength"> | ||||
<property name="max" value="100"/> | |||||
<property name="max" value="120"/> | |||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> | <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> | ||||
</module> | </module> | ||||
<module name="AvoidStarImport"/> | <module name="AvoidStarImport"/> | ||||
@@ -52,7 +52,7 @@ | |||||
</module> | </module> | ||||
<module name="NeedBraces"/> | <module name="NeedBraces"/> | ||||
<module name="LeftCurly"> | <module name="LeftCurly"> | ||||
<property name="maxLineLength" value="100"/> | |||||
<property name="maxLineLength" value="120"/> | |||||
</module> | </module> | ||||
<module name="RightCurly"> | <module name="RightCurly"> | ||||
<property name="id" value="RightCurlySame"/> | <property name="id" value="RightCurlySame"/> | ||||
@@ -163,9 +163,12 @@ | |||||
<module name="OverloadMethodsDeclarationOrder"/> | <module name="OverloadMethodsDeclarationOrder"/> | ||||
<module name="VariableDeclarationUsageDistance"/> | <module name="VariableDeclarationUsageDistance"/> | ||||
<module name="CustomImportOrder"> | <module name="CustomImportOrder"> | ||||
<property name="customImportOrderRules" | |||||
value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/> | |||||
<property name="specialImportsRegExp" value="^javax\."/> | |||||
<property name="standardPackageRegExp" value="^java\."/> | |||||
<property name="sortImportsInGroupAlphabetically" value="true"/> | <property name="sortImportsInGroupAlphabetically" value="true"/> | ||||
<property name="separateLineBetweenGroups" value="true"/> | |||||
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/> | |||||
<property name="separateLineBetweenGroups" value="false"/> | |||||
</module> | </module> | ||||
<module name="MethodParamPad"/> | <module name="MethodParamPad"/> | ||||
<module name="ParenPad"/> | <module name="ParenPad"/> | ||||
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>2.8.0</version> | |||||
<version>2.9.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-common</artifactId> | <artifactId>weixin-java-common</artifactId> | ||||
@@ -74,6 +74,10 @@ | |||||
<groupId>com.google.guava</groupId> | <groupId>com.google.guava</groupId> | ||||
<artifactId>guava</artifactId> | <artifactId>guava</artifactId> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.projectlombok</groupId> | |||||
<artifactId>lombok</artifactId> | |||||
</dependency> | |||||
<dependency> | <dependency> | ||||
<groupId>ch.qos.logback</groupId> | <groupId>ch.qos.logback</groupId> | ||||
@@ -3,187 +3,248 @@ package me.chanjar.weixin.common.api; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
/** | |||||
* 微信开发所使用到的常量类. | |||||
* | |||||
* @author chanjarster & binarywang | |||||
*/ | |||||
public class WxConsts { | public class WxConsts { | ||||
/////////////////////// | |||||
// 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型 | |||||
/////////////////////// | |||||
public static final String XML_MSG_TEXT = "text"; | |||||
public static final String XML_MSG_IMAGE = "image"; | |||||
public static final String XML_MSG_VOICE = "voice"; | |||||
public static final String XML_MSG_SHORTVIDEO = "shortvideo"; | |||||
public static final String XML_MSG_VIDEO = "video"; | |||||
public static final String XML_MSG_NEWS = "news"; | |||||
public static final String XML_MSG_MUSIC = "music"; | |||||
public static final String XML_MSG_LOCATION = "location"; | |||||
public static final String XML_MSG_LINK = "link"; | |||||
public static final String XML_MSG_EVENT = "event"; | |||||
public static final String XML_MSG_DEVICE_TEXT = "device_text"; | |||||
public static final String XML_MSG_DEVICE_EVENT = "device_event"; | |||||
public static final String XML_MSG_DEVICE_STATUS = "device_status"; | |||||
public static final String XML_MSG_HARDWARE = "hardware"; | |||||
public static final String XML_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | |||||
/////////////////////// | |||||
// 主动发送消息(即客服消息)的消息类型 | |||||
/////////////////////// | |||||
public static final String CUSTOM_MSG_TEXT = "text";//文本消息 | |||||
public static final String CUSTOM_MSG_IMAGE = "image";//图片消息 | |||||
public static final String CUSTOM_MSG_VOICE = "voice";//语音消息 | |||||
public static final String CUSTOM_MSG_VIDEO = "video";//视频消息 | |||||
public static final String CUSTOM_MSG_MUSIC = "music";//音乐消息 | |||||
public static final String CUSTOM_MSG_NEWS = "news";//图文消息(点击跳转到外链) | |||||
public static final String CUSTOM_MSG_MPNEWS = "mpnews";//图文消息(点击跳转到图文消息页面) | |||||
public static final String CUSTOM_MSG_FILE = "file";//发送文件(CP专用) | |||||
public static final String CUSTOM_MSG_TEXTCARD = "textcard";//文本卡片消息(CP专用) | |||||
public static final String CUSTOM_MSG_WXCARD = "wxcard";//卡券消息 | |||||
public static final String CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | |||||
public static final String CUSTOM_MSG_SAFE_NO = "0"; | |||||
public static final String CUSTOM_MSG_SAFE_YES = "1"; | |||||
/////////////////////// | |||||
// 群发消息的消息类型 | |||||
/////////////////////// | |||||
public static final String MASS_MSG_NEWS = "mpnews"; | |||||
public static final String MASS_MSG_TEXT = "text"; | |||||
public static final String MASS_MSG_VOICE = "voice"; | |||||
public static final String MASS_MSG_IMAGE = "image"; | |||||
public static final String MASS_MSG_VIDEO = "mpvideo"; | |||||
/////////////////////// | |||||
// 群发消息后微信端推送给服务器的反馈消息 | |||||
/////////////////////// | |||||
public static final String MASS_ST_SUCCESS = "send success"; | |||||
public static final String MASS_ST_FAIL = "send fail"; | |||||
public static final String MASS_ST_10001 = "err(10001)"; | |||||
public static final String MASS_ST_20001 = "err(20001)"; | |||||
public static final String MASS_ST_20004 = "err(20004)"; | |||||
public static final String MASS_ST_20002 = "err(20002)"; | |||||
public static final String MASS_ST_20006 = "err(20006)"; | |||||
public static final String MASS_ST_20008 = "err(20008)"; | |||||
public static final String MASS_ST_20013 = "err(20013)"; | |||||
public static final String MASS_ST_22000 = "err(22000)"; | |||||
public static final String MASS_ST_21000 = "err(21000)"; | |||||
/** | /** | ||||
* 群发反馈消息代码所对应的文字描述 | |||||
* 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型. | |||||
*/ | */ | ||||
public static final Map<String, String> MASS_ST_2_DESC = new HashMap<>(); | |||||
/////////////////////// | |||||
// 微信端推送过来的事件类型 | |||||
/////////////////////// | |||||
public static final String EVT_SUBSCRIBE = "subscribe"; | |||||
public static final String EVT_UNSUBSCRIBE = "unsubscribe"; | |||||
public static final String EVT_SCAN = "SCAN"; | |||||
public static final String EVT_LOCATION = "LOCATION"; | |||||
public static final String EVT_CLICK = "CLICK"; | |||||
public static final String EVT_VIEW = "VIEW"; | |||||
public static final String EVT_MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH"; | |||||
public static final String EVT_SCANCODE_PUSH = "scancode_push"; | |||||
public static final String EVT_SCANCODE_WAITMSG = "scancode_waitmsg"; | |||||
public static final String EVT_PIC_SYSPHOTO = "pic_sysphoto"; | |||||
public static final String EVT_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | |||||
public static final String EVT_PIC_WEIXIN = "pic_weixin"; | |||||
public static final String EVT_LOCATION_SELECT = "location_select"; | |||||
public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH"; | |||||
public static final String EVT_ENTER_AGENT = "enter_agent"; | |||||
/////////////////////// | |||||
// 上传多媒体文件的类型 | |||||
/////////////////////// | |||||
public static final String MEDIA_IMAGE = "image"; | |||||
public static final String MEDIA_VOICE = "voice"; | |||||
public static final String MEDIA_VIDEO = "video"; | |||||
public static final String MEDIA_THUMB = "thumb"; | |||||
public static final String MEDIA_FILE = "file"; | |||||
public static class XmlMsgType { | |||||
public static final String TEXT = "text"; | |||||
public static final String IMAGE = "image"; | |||||
public static final String VOICE = "voice"; | |||||
public static final String SHORTVIDEO = "shortvideo"; | |||||
public static final String VIDEO = "video"; | |||||
public static final String NEWS = "news"; | |||||
public static final String MUSIC = "music"; | |||||
public static final String LOCATION = "location"; | |||||
public static final String LINK = "link"; | |||||
public static final String EVENT = "event"; | |||||
public static final String DEVICE_TEXT = "device_text"; | |||||
public static final String DEVICE_EVENT = "device_event"; | |||||
public static final String DEVICE_STATUS = "device_status"; | |||||
public static final String HARDWARE = "hardware"; | |||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | |||||
} | |||||
/////////////////////// | |||||
// 自定义菜单的按钮类型 | |||||
/////////////////////// | |||||
/** | |||||
* 点击推事件 | |||||
*/ | |||||
public static final String BUTTON_CLICK = "click"; | |||||
/** | |||||
* 跳转URL | |||||
*/ | |||||
public static final String BUTTON_VIEW = "view"; | |||||
/** | |||||
* 跳转到小程序 | |||||
*/ | |||||
public static final String BUTTON_MINIPROGRAM = "miniprogram"; | |||||
/** | |||||
* 扫码推事件 | |||||
*/ | |||||
public static final String BUTTON_SCANCODE_PUSH = "scancode_push"; | |||||
/** | /** | ||||
* 扫码推事件且弹出“消息接收中”提示框 | |||||
* 主动发送消息(即客服消息)的消息类型. | |||||
*/ | */ | ||||
public static final String BUTTON_SCANCODE_WAITMSG = "scancode_waitmsg"; | |||||
public static class KefuMsgType { | |||||
/** | |||||
* 文本消息. | |||||
*/ | |||||
public static final String TEXT = "text"; | |||||
/** | |||||
* 图片消息. | |||||
*/ | |||||
public static final String IMAGE = "image"; | |||||
/** | |||||
* 语音消息. | |||||
*/ | |||||
public static final String VOICE = "voice"; | |||||
/** | |||||
* 视频消息. | |||||
*/ | |||||
public static final String VIDEO = "video"; | |||||
/** | |||||
* 音乐消息. | |||||
*/ | |||||
public static final String MUSIC = "music"; | |||||
/** | |||||
* 图文消息(点击跳转到外链). | |||||
*/ | |||||
public static final String NEWS = "news"; | |||||
/** | |||||
* 图文消息(点击跳转到图文消息页面). | |||||
*/ | |||||
public static final String MPNEWS = "mpnews"; | |||||
/** | |||||
* 发送文件(CP专用). | |||||
*/ | |||||
public static final String FILE = "file"; | |||||
/** | |||||
* 文本卡片消息(CP专用). | |||||
*/ | |||||
public static final String TEXTCARD = "textcard"; | |||||
/** | |||||
* 卡券消息. | |||||
*/ | |||||
public static final String WXCARD = "wxcard"; | |||||
/** | |||||
* 转发到客服的消息. | |||||
*/ | |||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; | |||||
} | |||||
/** | /** | ||||
* 弹出系统拍照发图 | |||||
* 表示是否是保密消息,0表示否,1表示是,默认0. | |||||
*/ | */ | ||||
public static final String BUTTON_PIC_SYSPHOTO = "pic_sysphoto"; | |||||
public static class KefuMsgSafe { | |||||
public static final String NO = "0"; | |||||
public static final String YES = "1"; | |||||
} | |||||
/** | /** | ||||
* 弹出拍照或者相册发图 | |||||
* 群发消息的消息类型. | |||||
*/ | */ | ||||
public static final String BUTTON_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | |||||
public static class MassMsgType { | |||||
public static final String MPNEWS = "mpnews"; | |||||
public static final String TEXT = "text"; | |||||
public static final String VOICE = "voice"; | |||||
public static final String IMAGE = "image"; | |||||
public static final String MPVIDEO = "mpvideo"; | |||||
} | |||||
/** | /** | ||||
* 弹出微信相册发图器 | |||||
* 群发消息后微信端推送给服务器的反馈消息. | |||||
*/ | */ | ||||
public static final String BUTTON_PIC_WEIXIN = "pic_weixin"; | |||||
public static class MassMsgStatus { | |||||
public static final String SEND_SUCCESS = "send success"; | |||||
public static final String SEND_FAIL = "send fail"; | |||||
public static final String ERR_10001 = "err(10001)"; | |||||
public static final String ERR_20001 = "err(20001)"; | |||||
public static final String ERR_20004 = "err(20004)"; | |||||
public static final String ERR_20002 = "err(20002)"; | |||||
public static final String ERR_20006 = "err(20006)"; | |||||
public static final String ERR_20008 = "err(20008)"; | |||||
public static final String ERR_20013 = "err(20013)"; | |||||
public static final String ERR_22000 = "err(22000)"; | |||||
public static final String ERR_21000 = "err(21000)"; | |||||
/** | |||||
* 群发反馈消息代码所对应的文字描述. | |||||
*/ | |||||
public static final Map<String, String> STATUS_DESC = new HashMap<>(); | |||||
static { | |||||
STATUS_DESC.put(SEND_SUCCESS, "发送成功"); | |||||
STATUS_DESC.put(SEND_FAIL, "发送失败"); | |||||
STATUS_DESC.put(ERR_10001, "涉嫌广告"); | |||||
STATUS_DESC.put(ERR_20001, "涉嫌政治"); | |||||
STATUS_DESC.put(ERR_20004, "涉嫌社会"); | |||||
STATUS_DESC.put(ERR_20002, "涉嫌色情"); | |||||
STATUS_DESC.put(ERR_20006, "涉嫌违法犯罪"); | |||||
STATUS_DESC.put(ERR_20008, "涉嫌欺诈"); | |||||
STATUS_DESC.put(ERR_20013, "涉嫌版权"); | |||||
STATUS_DESC.put(ERR_22000, "涉嫌互推_互相宣传"); | |||||
STATUS_DESC.put(ERR_21000, "涉嫌其他"); | |||||
} | |||||
} | |||||
/** | /** | ||||
* 弹出地理位置选择器 | |||||
* 微信端推送过来的事件类型. | |||||
*/ | */ | ||||
public static final String BUTTON_LOCATION_SELECT = "location_select"; | |||||
public static class EventType { | |||||
public static final String SUBSCRIBE = "subscribe"; | |||||
public static final String UNSUBSCRIBE = "unsubscribe"; | |||||
public static final String SCAN = "SCAN"; | |||||
public static final String LOCATION = "LOCATION"; | |||||
public static final String CLICK = "CLICK"; | |||||
public static final String VIEW = "VIEW"; | |||||
public static final String MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH"; | |||||
public static final String SCANCODE_PUSH = "scancode_push"; | |||||
public static final String SCANCODE_WAITMSG = "scancode_waitmsg"; | |||||
public static final String PIC_SYSPHOTO = "pic_sysphoto"; | |||||
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | |||||
public static final String PIC_WEIXIN = "pic_weixin"; | |||||
public static final String LOCATION_SELECT = "location_select"; | |||||
public static final String TEMPLATE_SEND_JOB_FINISH = "TEMPLATESENDJOBFINISH"; | |||||
public static final String ENTER_AGENT = "enter_agent"; | |||||
} | |||||
/** | /** | ||||
* 下发消息(除文本消息) | |||||
* 上传多媒体(临时素材)文件的类型. | |||||
*/ | */ | ||||
public static final String BUTTON_MEDIA_ID = "media_id"; | |||||
public static class MediaFileType { | |||||
public static final String IMAGE = "image"; | |||||
public static final String VOICE = "voice"; | |||||
public static final String VIDEO = "video"; | |||||
public static final String THUMB = "thumb"; | |||||
public static final String FILE = "file"; | |||||
} | |||||
/** | /** | ||||
* 跳转图文消息URL | |||||
* 自定义菜单的按钮类型. | |||||
*/ | */ | ||||
public static final String BUTTON_VIEW_LIMITED = "view_limited"; | |||||
public static class MenuButtonType { | |||||
/** | |||||
* 点击推事件. | |||||
*/ | |||||
public static final String CLICK = "click"; | |||||
/** | |||||
* 跳转URL. | |||||
*/ | |||||
public static final String VIEW = "view"; | |||||
/** | |||||
* 跳转到小程序. | |||||
*/ | |||||
public static final String MINIPROGRAM = "miniprogram"; | |||||
/** | |||||
* 扫码推事件. | |||||
*/ | |||||
public static final String SCANCODE_PUSH = "scancode_push"; | |||||
/** | |||||
* 扫码推事件且弹出“消息接收中”提示框. | |||||
*/ | |||||
public static final String SCANCODE_WAITMSG = "scancode_waitmsg"; | |||||
/** | |||||
* 弹出系统拍照发图. | |||||
*/ | |||||
public static final String PIC_SYSPHOTO = "pic_sysphoto"; | |||||
/** | |||||
* 弹出拍照或者相册发图. | |||||
*/ | |||||
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; | |||||
/** | |||||
* 弹出微信相册发图器. | |||||
*/ | |||||
public static final String PIC_WEIXIN = "pic_weixin"; | |||||
/** | |||||
* 弹出地理位置选择器. | |||||
*/ | |||||
public static final String LOCATION_SELECT = "location_select"; | |||||
/** | |||||
* 下发消息(除文本消息). | |||||
*/ | |||||
public static final String MEDIA_ID = "media_id"; | |||||
/** | |||||
* 跳转图文消息URL. | |||||
*/ | |||||
public static final String VIEW_LIMITED = "view_limited"; | |||||
} | |||||
/** | /** | ||||
* 不弹出授权页面,直接跳转,只能获取用户openid | |||||
* oauth2网页授权的scope. | |||||
*/ | */ | ||||
public static final String OAUTH2_SCOPE_BASE = "snsapi_base"; | |||||
public static class OAuth2Scope { | |||||
/** | |||||
* 不弹出授权页面,直接跳转,只能获取用户openid. | |||||
*/ | |||||
public static final String SNSAPI_BASE = "snsapi_base"; | |||||
/** | |||||
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息. | |||||
*/ | |||||
public static final String SNSAPI_USERINFO = "snsapi_userinfo"; | |||||
} | |||||
/////////////////////// | |||||
// oauth2网页授权的scope | |||||
/////////////////////// | |||||
/** | /** | ||||
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 | |||||
* 网页应用登录授权作用域. | |||||
*/ | */ | ||||
public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo"; | |||||
public static class QrConnectScope { | |||||
public static final String SNSAPI_LOGIN = "snsapi_login"; | |||||
} | |||||
/** | /** | ||||
* 网页应用登录授权作用域 snsapi_login | |||||
* 永久素材类型. | |||||
*/ | */ | ||||
public static final String QRCONNECT_SCOPE_SNSAPI_LOGIN = "snsapi_login"; | |||||
/////////////////////// | |||||
// 永久素材类型 | |||||
/////////////////////// | |||||
public static final String MATERIAL_NEWS = "news"; | |||||
public static final String MATERIAL_VOICE = "voice"; | |||||
public static final String MATERIAL_IMAGE = "image"; | |||||
public static final String MATERIAL_VIDEO = "video"; | |||||
static { | |||||
MASS_ST_2_DESC.put(MASS_ST_SUCCESS, "发送成功"); | |||||
MASS_ST_2_DESC.put(MASS_ST_FAIL, "发送失败"); | |||||
MASS_ST_2_DESC.put(MASS_ST_10001, "涉嫌广告"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20001, "涉嫌政治"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20004, "涉嫌社会"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20002, "涉嫌色情"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20006, "涉嫌违法犯罪"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20008, "涉嫌欺诈"); | |||||
MASS_ST_2_DESC.put(MASS_ST_20013, "涉嫌版权"); | |||||
MASS_ST_2_DESC.put(MASS_ST_22000, "涉嫌互推_互相宣传"); | |||||
MASS_ST_2_DESC.put(MASS_ST_21000, "涉嫌其他"); | |||||
public static class MaterialType { | |||||
public static final String NEWS = "news"; | |||||
public static final String VOICE = "voice"; | |||||
public static final String IMAGE = "image"; | |||||
public static final String VIDEO = "video"; | |||||
} | } | ||||
} | } |
@@ -3,7 +3,7 @@ package me.chanjar.weixin.common.api; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
/** | /** | ||||
* WxErrorException处理器 | |||||
* WxErrorException处理器. | |||||
*/ | */ | ||||
public interface WxErrorExceptionHandler { | public interface WxErrorExceptionHandler { | ||||
@@ -2,22 +2,21 @@ package me.chanjar.weixin.common.api; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 消息重复检查器 | |||||
* 消息重复检查器. | |||||
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 | * 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public interface WxMessageDuplicateChecker { | public interface WxMessageDuplicateChecker { | ||||
/** | /** | ||||
* 判断消息是否重复. | |||||
* <h2>公众号的排重方式</h2> | * <h2>公众号的排重方式</h2> | ||||
* <p> | |||||
* | |||||
* <p>普通消息:关于重试的消息排重,推荐使用msgid排重。<a href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html">文档参考</a>。</p> | * <p>普通消息:关于重试的消息排重,推荐使用msgid排重。<a href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html">文档参考</a>。</p> | ||||
* <p>事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。<a href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html">文档参考</a></p> | * <p>事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。<a href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html">文档参考</a></p> | ||||
* <p> | |||||
* | |||||
* <h2>企业号的排重方式</h2> | * <h2>企业号的排重方式</h2> | ||||
* <p> | |||||
* 官方文档完全没有写,参照公众号的方式排重。 | |||||
* <p> | |||||
* <p>官方文档完全没有写,参照公众号的方式排重。</p> | |||||
* <p>或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重</p> | * <p>或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重</p> | ||||
* | * | ||||
* @param messageId messageId需要根据上面讲的方式构造 | * @param messageId messageId需要根据上面讲的方式构造 | ||||
@@ -6,46 +6,46 @@ import java.util.concurrent.atomic.AtomicBoolean; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 默认消息重复检查器 | |||||
* 默认消息重复检查器. | |||||
* 将每个消息id保存在内存里,每隔5秒清理已经过期的消息id,每个消息id的过期时间是15秒 | * 将每个消息id保存在内存里,每隔5秒清理已经过期的消息id,每个消息id的过期时间是15秒 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChecker { | public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChecker { | ||||
/** | /** | ||||
* 一个消息ID在内存的过期时间:15秒 | |||||
* 一个消息ID在内存的过期时间:15秒. | |||||
*/ | */ | ||||
private final Long timeToLive; | private final Long timeToLive; | ||||
/** | /** | ||||
* 每隔多少周期检查消息ID是否过期:5秒 | |||||
* 每隔多少周期检查消息ID是否过期:5秒. | |||||
*/ | */ | ||||
private final Long clearPeriod; | private final Long clearPeriod; | ||||
/** | /** | ||||
* 消息id->消息时间戳的map | |||||
* 消息id->消息时间戳的map. | |||||
*/ | */ | ||||
private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<>(); | private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<>(); | ||||
/** | /** | ||||
* 后台清理线程是否已经开启 | |||||
* 后台清理线程是否已经开启. | |||||
*/ | */ | ||||
private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false); | private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false); | ||||
/** | /** | ||||
* WxMsgIdInMemoryDuplicateChecker构造函数 | |||||
* 无参构造方法. | |||||
* <pre> | * <pre> | ||||
* 一个消息ID在内存的过期时间:15秒 | * 一个消息ID在内存的过期时间:15秒 | ||||
* 每隔多少周期检查消息ID是否过期:5秒 | * 每隔多少周期检查消息ID是否过期:5秒 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public WxMessageInMemoryDuplicateChecker() { | public WxMessageInMemoryDuplicateChecker() { | ||||
this.timeToLive = 15 * 1000l; | |||||
this.clearPeriod = 5 * 1000l; | |||||
this.timeToLive = 15 * 1000L; | |||||
this.clearPeriod = 5 * 1000L; | |||||
} | } | ||||
/** | /** | ||||
* WxMsgIdInMemoryDuplicateChecker构造函数 | |||||
* 构造方法. | |||||
* | * | ||||
* @param timeToLive 一个消息ID在内存的过期时间:毫秒 | * @param timeToLive 一个消息ID在内存的过期时间:毫秒 | ||||
* @param clearPeriod 每隔多少周期检查消息ID是否过期:毫秒 | * @param clearPeriod 每隔多少周期检查消息ID是否过期:毫秒 | ||||
@@ -66,7 +66,8 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec | |||||
while (true) { | while (true) { | ||||
Thread.sleep(WxMessageInMemoryDuplicateChecker.this.clearPeriod); | Thread.sleep(WxMessageInMemoryDuplicateChecker.this.clearPeriod); | ||||
Long now = System.currentTimeMillis(); | Long now = System.currentTimeMillis(); | ||||
for (Map.Entry<String, Long> entry : WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) { | |||||
for (Map.Entry<String, Long> entry : | |||||
WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) { | |||||
if (now - entry.getValue() > WxMessageInMemoryDuplicateChecker.this.timeToLive) { | if (now - entry.getValue() > WxMessageInMemoryDuplicateChecker.this.timeToLive) { | ||||
WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet().remove(entry); | WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet().remove(entry); | ||||
} | } | ||||
@@ -1,9 +1,11 @@ | |||||
package me.chanjar.weixin.common.bean; | package me.chanjar.weixin.common.bean; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@Data | |||||
public class WxAccessToken implements Serializable { | public class WxAccessToken implements Serializable { | ||||
private static final long serialVersionUID = 8709719312922168909L; | private static final long serialVersionUID = 8709719312922168909L; | ||||
@@ -15,20 +17,4 @@ public class WxAccessToken implements Serializable { | |||||
return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); | return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); | ||||
} | } | ||||
public String getAccessToken() { | |||||
return this.accessToken; | |||||
} | |||||
public void setAccessToken(String accessToken) { | |||||
this.accessToken = accessToken; | |||||
} | |||||
public int getExpiresIn() { | |||||
return this.expiresIn; | |||||
} | |||||
public void setExpiresIn(int expiresIn) { | |||||
this.expiresIn = expiresIn; | |||||
} | |||||
} | } |
@@ -1,17 +1,18 @@ | |||||
package me.chanjar.weixin.common.bean; | package me.chanjar.weixin.common.bean; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* 卡券Api签名 | |||||
* 卡券Api签名. | |||||
* | * | ||||
* @author YuJian | * @author YuJian | ||||
* @version 15/11/8 | * @version 15/11/8 | ||||
*/ | */ | ||||
@Data | |||||
public class WxCardApiSignature implements Serializable { | public class WxCardApiSignature implements Serializable { | ||||
private static final long serialVersionUID = 158176707226975979L; | private static final long serialVersionUID = 158176707226975979L; | ||||
private String appId; | private String appId; | ||||
@@ -37,75 +38,4 @@ public class WxCardApiSignature implements Serializable { | |||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
} | } | ||||
public String getAppId() { | |||||
return this.appId; | |||||
} | |||||
public void setAppId(String appId) { | |||||
this.appId = appId; | |||||
} | |||||
public String getCardId() { | |||||
return this.cardId; | |||||
} | |||||
public void setCardId(String cardId) { | |||||
this.cardId = cardId; | |||||
} | |||||
public String getCardType() { | |||||
return this.cardType; | |||||
} | |||||
public void setCardType(String cardType) { | |||||
this.cardType = cardType; | |||||
} | |||||
public String getLocationId() { | |||||
return this.locationId; | |||||
} | |||||
public void setLocationId(String locationId) { | |||||
this.locationId = locationId; | |||||
} | |||||
public String getCode() { | |||||
return this.code; | |||||
} | |||||
public void setCode(String code) { | |||||
this.code = code; | |||||
} | |||||
public String getOpenId() { | |||||
return this.openId; | |||||
} | |||||
public void setOpenId(String openId) { | |||||
this.openId = openId; | |||||
} | |||||
public Long getTimestamp() { | |||||
return this.timestamp; | |||||
} | |||||
public void setTimestamp(Long timestamp) { | |||||
this.timestamp = timestamp; | |||||
} | |||||
public String getNonceStr() { | |||||
return this.nonceStr; | |||||
} | |||||
public void setNonceStr(String nonceStr) { | |||||
this.nonceStr = nonceStr; | |||||
} | |||||
public String getSignature() { | |||||
return this.signature; | |||||
} | |||||
public void setSignature(String signature) { | |||||
this.signature = signature; | |||||
} | |||||
} | } |
@@ -1,10 +1,13 @@ | |||||
package me.chanjar.weixin.common.bean; | package me.chanjar.weixin.common.bean; | ||||
import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* jspai signature | |||||
* jspai signature. | |||||
*/ | */ | ||||
@Data | |||||
public class WxJsapiSignature implements Serializable { | public class WxJsapiSignature implements Serializable { | ||||
private static final long serialVersionUID = -1116808193154384804L; | private static final long serialVersionUID = -1116808193154384804L; | ||||
@@ -18,43 +21,4 @@ public class WxJsapiSignature implements Serializable { | |||||
private String signature; | private String signature; | ||||
public String getSignature() { | |||||
return this.signature; | |||||
} | |||||
public void setSignature(String signature) { | |||||
this.signature = signature; | |||||
} | |||||
public String getNonceStr() { | |||||
return nonceStr; | |||||
} | |||||
public void setNonceStr(String nonceStr) { | |||||
this.nonceStr = nonceStr; | |||||
} | |||||
public long getTimestamp() { | |||||
return this.timestamp; | |||||
} | |||||
public void setTimestamp(long timestamp) { | |||||
this.timestamp = timestamp; | |||||
} | |||||
public String getUrl() { | |||||
return this.url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.url = url; | |||||
} | |||||
public String getAppId() { | |||||
return appId; | |||||
} | |||||
public void setAppId(String appId) { | |||||
this.appId = appId; | |||||
} | |||||
} | } |
@@ -1,5 +1,6 @@ | |||||
package me.chanjar.weixin.common.bean.menu; | package me.chanjar.weixin.common.bean.menu; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
@@ -11,12 +12,12 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* 菜单(公众号和企业号共用的) | |||||
* 菜单(公众号和企业号共用的). | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Data | |||||
public class WxMenu implements Serializable { | public class WxMenu implements Serializable { | ||||
private static final long serialVersionUID = -7083914585539687746L; | private static final long serialVersionUID = -7083914585539687746L; | ||||
private List<WxMenuButton> buttons = new ArrayList<>(); | private List<WxMenuButton> buttons = new ArrayList<>(); | ||||
@@ -36,23 +37,8 @@ public class WxMenu implements Serializable { | |||||
* 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu | * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu | ||||
*/ | */ | ||||
public static WxMenu fromJson(InputStream is) { | public static WxMenu fromJson(InputStream is) { | ||||
return WxGsonBuilder.create().fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); | |||||
} | |||||
public List<WxMenuButton> getButtons() { | |||||
return this.buttons; | |||||
} | |||||
public void setButtons(List<WxMenuButton> buttons) { | |||||
this.buttons = buttons; | |||||
} | |||||
public WxMenuRule getMatchRule() { | |||||
return this.matchRule; | |||||
} | |||||
public void setMatchRule(WxMenuRule matchRule) { | |||||
this.matchRule = matchRule; | |||||
return WxGsonBuilder.create() | |||||
.fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); | |||||
} | } | ||||
public String toJson() { | public String toJson() { | ||||
@@ -1,18 +1,20 @@ | |||||
package me.chanjar.weixin.common.bean.menu; | package me.chanjar.weixin.common.bean.menu; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
@Data | |||||
public class WxMenuButton implements Serializable { | public class WxMenuButton implements Serializable { | ||||
private static final long serialVersionUID = -1070939403109776555L; | private static final long serialVersionUID = -1070939403109776555L; | ||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 菜单的响应动作类型: | |||||
* 菜单的响应动作类型. | |||||
* view表示网页类型, | * view表示网页类型, | ||||
* click表示点击类型, | * click表示点击类型, | ||||
* miniprogram表示小程序类型 | * miniprogram表示小程序类型 | ||||
@@ -21,13 +23,13 @@ public class WxMenuButton implements Serializable { | |||||
private String type; | private String type; | ||||
/** | /** | ||||
* 菜单标题,不超过16个字节,子菜单不超过60个字节 | |||||
* 菜单标题,不超过16个字节,子菜单不超过60个字节. | |||||
*/ | */ | ||||
private String name; | private String name; | ||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 菜单KEY值,用于消息接口推送,不超过128字节 | |||||
* 菜单KEY值,用于消息接口推送,不超过128字节. | |||||
* click等点击类型必须 | * click等点击类型必须 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@@ -35,7 +37,8 @@ public class WxMenuButton implements Serializable { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。 | |||||
* 网页链接. | |||||
* 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。 | |||||
* view、miniprogram类型必须 | * view、miniprogram类型必须 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@@ -43,7 +46,7 @@ public class WxMenuButton implements Serializable { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 调用新增永久素材接口返回的合法media_id | |||||
* 调用新增永久素材接口返回的合法media_id. | |||||
* media_id类型和view_limited类型必须 | * media_id类型和view_limited类型必须 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@@ -52,7 +55,7 @@ public class WxMenuButton implements Serializable { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 小程序的appid | |||||
* 小程序的appid. | |||||
* miniprogram类型必须 | * miniprogram类型必须 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@@ -61,7 +64,7 @@ public class WxMenuButton implements Serializable { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 小程序的页面路径 | |||||
* 小程序的页面路径. | |||||
* miniprogram类型必须 | * miniprogram类型必须 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
@@ -76,67 +79,4 @@ public class WxMenuButton implements Serializable { | |||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
} | } | ||||
public String getType() { | |||||
return this.type; | |||||
} | |||||
public void setType(String type) { | |||||
this.type = type; | |||||
} | |||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getKey() { | |||||
return this.key; | |||||
} | |||||
public void setKey(String key) { | |||||
this.key = key; | |||||
} | |||||
public String getUrl() { | |||||
return this.url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.url = url; | |||||
} | |||||
public List<WxMenuButton> getSubButtons() { | |||||
return this.subButtons; | |||||
} | |||||
public void setSubButtons(List<WxMenuButton> subButtons) { | |||||
this.subButtons = subButtons; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getAppId() { | |||||
return appId; | |||||
} | |||||
public void setAppId(String appId) { | |||||
this.appId = appId; | |||||
} | |||||
public String getPagePath() { | |||||
return pagePath; | |||||
} | |||||
public void setPagePath(String pagePath) { | |||||
this.pagePath = pagePath; | |||||
} | |||||
} | } |
@@ -1,12 +1,19 @@ | |||||
package me.chanjar.weixin.common.bean.menu; | package me.chanjar.weixin.common.bean.menu; | ||||
import com.google.gson.annotations.SerializedName; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@Data | |||||
public class WxMenuRule implements Serializable { | public class WxMenuRule implements Serializable { | ||||
private static final long serialVersionUID = -4587181819499286670L; | private static final long serialVersionUID = -4587181819499286670L; | ||||
/** | |||||
* 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. | |||||
*/ | |||||
@SerializedName(value = "tag_id", alternate = "group_id") | |||||
private String tagId; | private String tagId; | ||||
private String sex; | private String sex; | ||||
private String country; | private String country; | ||||
@@ -15,62 +22,6 @@ public class WxMenuRule implements Serializable { | |||||
private String clientPlatformType; | private String clientPlatformType; | ||||
private String language; | private String language; | ||||
public String getTagId() { | |||||
return this.tagId; | |||||
} | |||||
public void setTagId(String tagId) { | |||||
this.tagId = tagId; | |||||
} | |||||
public String getSex() { | |||||
return this.sex; | |||||
} | |||||
public void setSex(String sex) { | |||||
this.sex = sex; | |||||
} | |||||
public String getCountry() { | |||||
return this.country; | |||||
} | |||||
public void setCountry(String country) { | |||||
this.country = country; | |||||
} | |||||
public String getProvince() { | |||||
return this.province; | |||||
} | |||||
public void setProvince(String province) { | |||||
this.province = province; | |||||
} | |||||
public String getCity() { | |||||
return this.city; | |||||
} | |||||
public void setCity(String city) { | |||||
this.city = city; | |||||
} | |||||
public String getClientPlatformType() { | |||||
return this.clientPlatformType; | |||||
} | |||||
public void setClientPlatformType(String clientPlatformType) { | |||||
this.clientPlatformType = clientPlatformType; | |||||
} | |||||
public String getLanguage() { | |||||
return this.language; | |||||
} | |||||
public void setLanguage(String language) { | |||||
this.language = language; | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
@@ -1,14 +1,18 @@ | |||||
package me.chanjar.weixin.common.bean.result; | package me.chanjar.weixin.common.bean.result; | ||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* 微信错误码说明,请阅读: <a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a> | |||||
* 微信错误码说明,请阅读: <a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a>. | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Data | |||||
@Builder | |||||
public class WxError implements Serializable { | public class WxError implements Serializable { | ||||
private static final long serialVersionUID = 7869786563361406291L; | private static final long serialVersionUID = 7869786563361406291L; | ||||
@@ -23,34 +27,6 @@ public class WxError implements Serializable { | |||||
return WxGsonBuilder.create().fromJson(json, WxError.class); | return WxGsonBuilder.create().fromJson(json, WxError.class); | ||||
} | } | ||||
public static Builder newBuilder() { | |||||
return new Builder(); | |||||
} | |||||
public int getErrorCode() { | |||||
return this.errorCode; | |||||
} | |||||
public void setErrorCode(int errorCode) { | |||||
this.errorCode = errorCode; | |||||
} | |||||
public String getErrorMsg() { | |||||
return this.errorMsg; | |||||
} | |||||
public void setErrorMsg(String errorMsg) { | |||||
this.errorMsg = errorMsg; | |||||
} | |||||
public String getJson() { | |||||
return this.json; | |||||
} | |||||
public void setJson(String json) { | |||||
this.json = json; | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
if (this.json != null) { | if (this.json != null) { | ||||
@@ -59,26 +35,4 @@ public class WxError implements Serializable { | |||||
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; | return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; | ||||
} | } | ||||
public static class Builder { | |||||
private int errorCode; | |||||
private String errorMsg; | |||||
public Builder setErrorCode(int errorCode) { | |||||
this.errorCode = errorCode; | |||||
return this; | |||||
} | |||||
public Builder setErrorMsg(String errorMsg) { | |||||
this.errorMsg = errorMsg; | |||||
return this; | |||||
} | |||||
public WxError build() { | |||||
WxError wxError = new WxError(); | |||||
wxError.setErrorCode(this.errorCode); | |||||
wxError.setErrorMsg(this.errorMsg); | |||||
return wxError; | |||||
} | |||||
} | |||||
} | } |
@@ -1,11 +1,12 @@ | |||||
package me.chanjar.weixin.common.bean.result; | package me.chanjar.weixin.common.bean.result; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | |||||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||||
import org.apache.commons.lang3.builder.ToStringStyle; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@Data | |||||
public class WxMediaUploadResult implements Serializable { | public class WxMediaUploadResult implements Serializable { | ||||
private static final long serialVersionUID = 330834334738622341L; | private static final long serialVersionUID = 330834334738622341L; | ||||
@@ -18,41 +19,9 @@ public class WxMediaUploadResult implements Serializable { | |||||
return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); | return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); | ||||
} | } | ||||
public String getType() { | |||||
return this.type; | |||||
} | |||||
public void setType(String type) { | |||||
this.type = type; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public long getCreatedAt() { | |||||
return this.createdAt; | |||||
} | |||||
public void setCreatedAt(long createdAt) { | |||||
this.createdAt = createdAt; | |||||
} | |||||
public String getThumbMediaId() { | |||||
return this.thumbMediaId; | |||||
} | |||||
public void setThumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | } | ||||
} | } |
@@ -11,6 +11,7 @@ import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||
import java.lang.reflect.Modifier; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -20,8 +21,9 @@ import java.util.Map; | |||||
* <pre> | * <pre> | ||||
* bean操作的一些工具类 | * bean操作的一些工具类 | ||||
* Created by Binary Wang on 2016-10-21. | * Created by Binary Wang on 2016-10-21. | ||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
* </pre> | * </pre> | ||||
* | |||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
*/ | */ | ||||
public class BeanUtils { | public class BeanUtils { | ||||
private static Logger log = LoggerFactory.getLogger(BeanUtils.class); | private static Logger log = LoggerFactory.getLogger(BeanUtils.class); | ||||
@@ -42,22 +44,27 @@ public class BeanUtils { | |||||
boolean isAccessible = field.isAccessible(); | boolean isAccessible = field.isAccessible(); | ||||
field.setAccessible(true); | field.setAccessible(true); | ||||
if (field.isAnnotationPresent(Required.class)) { | if (field.isAnnotationPresent(Required.class)) { | ||||
if (field.get(bean) == null || (field.get(bean) instanceof String && StringUtils.isBlank(field.get(bean).toString()))) { | |||||
//两种情况,一种是值为null,另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 | |||||
// 两种情况,一种是值为null, | |||||
// 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 | |||||
boolean isRequiredMissing = field.get(bean) == null | |||||
|| (field.get(bean) instanceof String | |||||
&& StringUtils.isBlank(field.get(bean).toString()) | |||||
); | |||||
if (isRequiredMissing) { | |||||
requiredFields.add(field.getName()); | requiredFields.add(field.getName()); | ||||
} | } | ||||
} | } | ||||
field.setAccessible(isAccessible); | field.setAccessible(isAccessible); | ||||
} catch (SecurityException | IllegalArgumentException | } catch (SecurityException | IllegalArgumentException | ||||
| IllegalAccessException e) { | | IllegalAccessException e) { | ||||
e.printStackTrace(); | |||||
log.error(e.getMessage(), e); | |||||
} | } | ||||
} | } | ||||
if (!requiredFields.isEmpty()) { | if (!requiredFields.isEmpty()) { | ||||
String msg = "必填字段 " + requiredFields + " 必须提供值"; | String msg = "必填字段 " + requiredFields + " 必须提供值"; | ||||
log.debug(msg); | log.debug(msg); | ||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg(msg).build()); | |||||
} | } | ||||
} | } | ||||
@@ -82,11 +89,14 @@ public class BeanUtils { | |||||
if (field.isAnnotationPresent(XStreamAlias.class)) { | if (field.isAnnotationPresent(XStreamAlias.class)) { | ||||
result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); | result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); | ||||
} else if (!Modifier.isStatic(field.getModifiers())) { | |||||
//忽略掉静态成员变量 | |||||
result.put(field.getName(), field.get(bean).toString()); | |||||
} | } | ||||
field.setAccessible(isAccessible); | field.setAccessible(isAccessible); | ||||
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { | } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { | ||||
e.printStackTrace(); | |||||
log.error(e.getMessage(), e); | |||||
} | } | ||||
} | } | ||||
@@ -8,8 +8,9 @@ import org.apache.commons.lang3.builder.ToStringStyle; | |||||
* <pre> | * <pre> | ||||
* 自定义的ToString方法,用于产生去掉空值属性的字符串 | * 自定义的ToString方法,用于产生去掉空值属性的字符串 | ||||
* Created by Binary Wang on 2016-10-27. | * Created by Binary Wang on 2016-10-27. | ||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
* </pre> | * </pre> | ||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | */ | ||||
public class ToStringUtils { | public class ToStringUtils { | ||||
public static final ToStringStyle THE_STYLE = new SimpleMultiLineToStringStyle(); | public static final ToStringStyle THE_STYLE = new SimpleMultiLineToStringStyle(); | ||||
@@ -1,26 +1,26 @@ | |||||
package me.chanjar.weixin.common.util.crypto; | |||||
import java.util.ArrayList; | |||||
public class ByteGroup { | |||||
ArrayList<Byte> byteContainer = new ArrayList<>(); | |||||
public byte[] toBytes() { | |||||
byte[] bytes = new byte[this.byteContainer.size()]; | |||||
for (int i = 0; i < this.byteContainer.size(); i++) { | |||||
bytes[i] = this.byteContainer.get(i); | |||||
} | |||||
return bytes; | |||||
} | |||||
public ByteGroup addBytes(byte[] bytes) { | |||||
for (byte b : bytes) { | |||||
this.byteContainer.add(b); | |||||
} | |||||
return this; | |||||
} | |||||
public int size() { | |||||
return this.byteContainer.size(); | |||||
} | |||||
} | |||||
package me.chanjar.weixin.common.util.crypto; | |||||
import java.util.ArrayList; | |||||
public class ByteGroup { | |||||
ArrayList<Byte> byteContainer = new ArrayList<>(); | |||||
public byte[] toBytes() { | |||||
byte[] bytes = new byte[this.byteContainer.size()]; | |||||
for (int i = 0; i < this.byteContainer.size(); i++) { | |||||
bytes[i] = this.byteContainer.get(i); | |||||
} | |||||
return bytes; | |||||
} | |||||
public ByteGroup addBytes(byte[] bytes) { | |||||
for (byte b : bytes) { | |||||
this.byteContainer.add(b); | |||||
} | |||||
return this; | |||||
} | |||||
public int size() { | |||||
return this.byteContainer.size(); | |||||
} | |||||
} |
@@ -1,68 +1,68 @@ | |||||
/** | |||||
* 对公众平台发送给公众账号的消息加解密示例代码. | |||||
* | |||||
* @copyright Copyright (c) 1998-2014 Tencent Inc. | |||||
*/ | |||||
// ------------------------------------------------------------------------ | |||||
package me.chanjar.weixin.common.util.crypto; | |||||
import java.nio.charset.Charset; | |||||
import java.util.Arrays; | |||||
/** | |||||
* 提供基于PKCS7算法的加解 | |||||
*/ | |||||
public class PKCS7Encoder { | |||||
private static final Charset CHARSET = Charset.forName("utf-8"); | |||||
private static final int BLOCK_SIZE = 32; | |||||
/** | |||||
* 获得对明文进行补位填充的字节. | |||||
* | |||||
* @param count 需要进行填充补位操作的明文字节个数 | |||||
* @return 补齐用的字节数组 | |||||
*/ | |||||
public static byte[] encode(int count) { | |||||
// 计算需要填充的位数 | |||||
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); | |||||
if (amountToPad == 0) { | |||||
amountToPad = BLOCK_SIZE; | |||||
} | |||||
// 获得补位所用的字符 | |||||
char padChr = chr(amountToPad); | |||||
String tmp = new String(); | |||||
for (int index = 0; index < amountToPad; index++) { | |||||
tmp += padChr; | |||||
} | |||||
return tmp.getBytes(CHARSET); | |||||
} | |||||
/** | |||||
* 删除解密后明文的补位字符 | |||||
* | |||||
* @param decrypted 解密后的明文 | |||||
* @return 删除补位字符后的明文 | |||||
*/ | |||||
public static byte[] decode(byte[] decrypted) { | |||||
int pad = decrypted[decrypted.length - 1]; | |||||
if (pad < 1 || pad > 32) { | |||||
pad = 0; | |||||
} | |||||
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); | |||||
} | |||||
/** | |||||
* 将数字转化成ASCII码对应的字符,用于对明文进行补码 | |||||
* | |||||
* @param a 需要转化的数字 | |||||
* @return 转化得到的字符 | |||||
*/ | |||||
public static char chr(int a) { | |||||
byte target = (byte) (a & 0xFF); | |||||
return (char) target; | |||||
} | |||||
} | |||||
/** | |||||
* 对公众平台发送给公众账号的消息加解密示例代码. | |||||
* | |||||
* @copyright Copyright (c) 1998-2014 Tencent Inc. | |||||
*/ | |||||
// ------------------------------------------------------------------------ | |||||
package me.chanjar.weixin.common.util.crypto; | |||||
import java.nio.charset.Charset; | |||||
import java.util.Arrays; | |||||
/** | |||||
* 提供基于PKCS7算法的加解 | |||||
*/ | |||||
public class PKCS7Encoder { | |||||
private static final Charset CHARSET = Charset.forName("utf-8"); | |||||
private static final int BLOCK_SIZE = 32; | |||||
/** | |||||
* 获得对明文进行补位填充的字节. | |||||
* | |||||
* @param count 需要进行填充补位操作的明文字节个数 | |||||
* @return 补齐用的字节数组 | |||||
*/ | |||||
public static byte[] encode(int count) { | |||||
// 计算需要填充的位数 | |||||
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); | |||||
if (amountToPad == 0) { | |||||
amountToPad = BLOCK_SIZE; | |||||
} | |||||
// 获得补位所用的字符 | |||||
char padChr = chr(amountToPad); | |||||
String tmp = new String(); | |||||
for (int index = 0; index < amountToPad; index++) { | |||||
tmp += padChr; | |||||
} | |||||
return tmp.getBytes(CHARSET); | |||||
} | |||||
/** | |||||
* 删除解密后明文的补位字符 | |||||
* | |||||
* @param decrypted 解密后的明文 | |||||
* @return 删除补位字符后的明文 | |||||
*/ | |||||
public static byte[] decode(byte[] decrypted) { | |||||
int pad = decrypted[decrypted.length - 1]; | |||||
if (pad < 1 || pad > 32) { | |||||
pad = 0; | |||||
} | |||||
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); | |||||
} | |||||
/** | |||||
* 将数字转化成ASCII码对应的字符,用于对明文进行补码 | |||||
* | |||||
* @param a 需要转化的数字 | |||||
* @return 转化得到的字符 | |||||
*/ | |||||
public static char chr(int a) { | |||||
byte target = (byte) (a & 0xFF); | |||||
return (char) target; | |||||
} | |||||
} |
@@ -1,52 +1,37 @@ | |||||
package me.chanjar.weixin.common.util.fs; | package me.chanjar.weixin.common.util.fs; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.FileOutputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.nio.file.Files; | |||||
public class FileUtils { | public class FileUtils { | ||||
/** | /** | ||||
* 创建临时文件 | * 创建临时文件 | ||||
* | * | ||||
* @param inputStream | |||||
* @param inputStream 输入文件流 | |||||
* @param name 文件名 | * @param name 文件名 | ||||
* @param ext 扩展名 | * @param ext 扩展名 | ||||
* @param tmpDirFile 临时文件夹目录 | * @param tmpDirFile 临时文件夹目录 | ||||
*/ | */ | ||||
public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException { | public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException { | ||||
File tmpFile; | |||||
if (tmpDirFile == null) { | |||||
tmpFile = File.createTempFile(name, '.' + ext); | |||||
} else { | |||||
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile); | |||||
} | |||||
tmpFile.deleteOnExit(); | |||||
try (FileOutputStream fos = new FileOutputStream(tmpFile)) { | |||||
int read = 0; | |||||
byte[] bytes = new byte[1024 * 100]; | |||||
while ((read = inputStream.read(bytes)) != -1) { | |||||
fos.write(bytes, 0, read); | |||||
} | |||||
File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile); | |||||
fos.flush(); | |||||
return tmpFile; | |||||
} | |||||
resultFile.deleteOnExit(); | |||||
org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, resultFile); | |||||
return resultFile; | |||||
} | } | ||||
/** | /** | ||||
* 创建临时文件 | * 创建临时文件 | ||||
* | * | ||||
* @param inputStream | |||||
* @param inputStream 输入文件流 | |||||
* @param name 文件名 | * @param name 文件名 | ||||
* @param ext 扩展名 | * @param ext 扩展名 | ||||
*/ | */ | ||||
public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException { | public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException { | ||||
return createTmpFile(inputStream, name, ext, null); | |||||
return createTmpFile(inputStream, name, ext, Files.createTempDirectory("weixin-java-tools-temp").toFile()); | |||||
} | } | ||||
} | } |
@@ -12,11 +12,11 @@ import java.io.File; | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
public abstract class MediaDownloadRequestExecutor<H, P> implements RequestExecutor<File, String> { | |||||
public abstract class BaseMediaDownloadRequestExecutor<H, P> implements RequestExecutor<File, String> { | |||||
protected RequestHttp<H, P> requestHttp; | protected RequestHttp<H, P> requestHttp; | ||||
protected File tmpDirFile; | protected File tmpDirFile; | ||||
public MediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | |||||
public BaseMediaDownloadRequestExecutor(RequestHttp<H, P> requestHttp, File tmpDirFile) { | |||||
this.requestHttp = requestHttp; | this.requestHttp = requestHttp; | ||||
this.tmpDirFile = tmpDirFile; | this.tmpDirFile = tmpDirFile; | ||||
} | } |
@@ -19,6 +19,8 @@ import java.util.regex.Pattern; | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class HttpResponseProxy { | public class HttpResponseProxy { | ||||
private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); | |||||
private CloseableHttpResponse apacheHttpResponse; | private CloseableHttpResponse apacheHttpResponse; | ||||
private HttpResponse joddHttpResponse; | private HttpResponse joddHttpResponse; | ||||
private Response okHttpResponse; | private Response okHttpResponse; | ||||
@@ -56,7 +58,7 @@ public class HttpResponseProxy { | |||||
private String getFileName(CloseableHttpResponse response) throws WxErrorException { | private String getFileName(CloseableHttpResponse response) throws WxErrorException { | ||||
Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | ||||
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { | if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { | ||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); | |||||
} | } | ||||
return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); | return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); | ||||
@@ -74,15 +76,15 @@ public class HttpResponseProxy { | |||||
private String extractFileNameFromContentString(String content) throws WxErrorException { | private String extractFileNameFromContentString(String content) throws WxErrorException { | ||||
if (content == null || content.length() == 0) { | if (content == null || content.length() == 0) { | ||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); | |||||
} | } | ||||
Pattern p = Pattern.compile(".*filename=\"(.*)\""); | |||||
Matcher m = p.matcher(content); | |||||
Matcher m = PATTERN.matcher(content); | |||||
if (m.matches()) { | if (m.matches()) { | ||||
return m.group(1); | return m.group(1); | ||||
} | } | ||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); | |||||
} | } | ||||
} | } |
@@ -4,51 +4,41 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
/** | /** | ||||
* httpclient build interface | |||||
* httpclient build interface. | |||||
* | * | ||||
* @author kakotor | * @author kakotor | ||||
*/ | */ | ||||
public interface ApacheHttpClientBuilder { | public interface ApacheHttpClientBuilder { | ||||
/** | /** | ||||
* 构建httpclient实例 | |||||
* 构建httpclient实例. | |||||
* | * | ||||
* @return new instance of CloseableHttpClient | * @return new instance of CloseableHttpClient | ||||
*/ | */ | ||||
CloseableHttpClient build(); | CloseableHttpClient build(); | ||||
/** | /** | ||||
* 代理服务器地址 | |||||
* | |||||
* @param httpProxyHost | |||||
* 代理服务器地址. | |||||
*/ | */ | ||||
ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); | ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); | ||||
/** | /** | ||||
* 代理服务器端口 | |||||
* | |||||
* @param httpProxyPort | |||||
* 代理服务器端口. | |||||
*/ | */ | ||||
ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); | ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); | ||||
/** | /** | ||||
* 代理服务器用户名 | |||||
* | |||||
* @param httpProxyUsername | |||||
* 代理服务器用户名. | |||||
*/ | */ | ||||
ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); | ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); | ||||
/** | /** | ||||
* 代理服务器密码 | |||||
* | |||||
* @param httpProxyPassword | |||||
* 代理服务器密码. | |||||
*/ | */ | ||||
ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); | ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); | ||||
/** | /** | ||||
* ssl连接socket工厂 | |||||
* | |||||
* @param sslConnectionSocketFactory | |||||
* ssl连接socket工厂. | |||||
*/ | */ | ||||
ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); | ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); | ||||
} | } |
@@ -29,9 +29,8 @@ import java.util.concurrent.TimeUnit; | |||||
import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||
/** | /** | ||||
* httpclient 连接管理器 自带DNS解析 | |||||
* <p> | |||||
* 大部分代码拷贝自:DefaultApacheHttpClientBuilder | |||||
* httpclient 连接管理器 自带DNS解析. | |||||
* <p>大部分代码拷贝自:DefaultApacheHttpClientBuilder</p> | |||||
* | * | ||||
* @author Andy.Huo | * @author Andy.Huo | ||||
*/ | */ | ||||
@@ -64,7 +63,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
private String httpProxyPassword; | private String httpProxyPassword; | ||||
/** | /** | ||||
* 闲置连接监控线程 | |||||
* 闲置连接监控线程. | |||||
*/ | */ | ||||
private IdleConnectionMonitorThread idleConnectionMonitorThread; | private IdleConnectionMonitorThread idleConnectionMonitorThread; | ||||
private HttpClientBuilder httpClientBuilder; | private HttpClientBuilder httpClientBuilder; | ||||
@@ -162,7 +161,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
} | } | ||||
/** | /** | ||||
* 每路的最大链接数,默认10 | |||||
* 每路的最大链接数,默认10. | |||||
* | * | ||||
* @param maxConnPerHost 每路的最大链接数,默认10 | * @param maxConnPerHost 每路的最大链接数,默认10 | ||||
*/ | */ | ||||
@@ -171,7 +170,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
} | } | ||||
/** | /** | ||||
* 最大总连接数,默认50 | |||||
* 最大总连接数,默认50. | |||||
* | * | ||||
* @param maxTotalConn 最大总连接数,默认50 | * @param maxTotalConn 最大总连接数,默认50 | ||||
*/ | */ | ||||
@@ -180,7 +179,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
} | } | ||||
/** | /** | ||||
* 自定义httpclient的User Agent | |||||
* 自定义httpclient的User Agent. | |||||
* | * | ||||
* @param userAgent User Agent | * @param userAgent User Agent | ||||
*/ | */ | ||||
@@ -196,9 +195,12 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
if (prepared.get()) { | if (prepared.get()) { | ||||
return; | return; | ||||
} | } | ||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() | |||||
.register("http", this.plainConnectionSocketFactory).register("https", this.sslConnectionSocketFactory) | |||||
.build(); | |||||
Registry<ConnectionSocketFactory> registry = | |||||
RegistryBuilder.<ConnectionSocketFactory>create() | |||||
.register("http", this.plainConnectionSocketFactory) | |||||
.register("https", this.sslConnectionSocketFactory) | |||||
.build(); | |||||
@SuppressWarnings("resource") | @SuppressWarnings("resource") | ||||
PoolingHttpClientConnectionManager connectionManager; | PoolingHttpClientConnectionManager connectionManager; | ||||
@@ -219,8 +221,8 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
connectionManager | connectionManager | ||||
.setDefaultSocketConfig(SocketConfig.copy(SocketConfig.DEFAULT).setSoTimeout(this.soTimeout).build()); | .setDefaultSocketConfig(SocketConfig.copy(SocketConfig.DEFAULT).setSoTimeout(this.soTimeout).build()); | ||||
this.idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, this.idleConnTimeout, | |||||
this.checkWaitTime); | |||||
this.idleConnectionMonitorThread = new IdleConnectionMonitorThread( | |||||
connectionManager, this.idleConnTimeout, this.checkWaitTime); | |||||
this.idleConnectionMonitorThread.setDaemon(true); | this.idleConnectionMonitorThread.setDaemon(true); | ||||
this.idleConnectionMonitorThread.start(); | this.idleConnectionMonitorThread.start(); | ||||
@@ -234,8 +236,8 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
if (StringUtils.isNotBlank(this.httpProxyHost) && StringUtils.isNotBlank(this.httpProxyUsername)) { | if (StringUtils.isNotBlank(this.httpProxyHost) && StringUtils.isNotBlank(this.httpProxyUsername)) { | ||||
// 使用代理服务器 需要用户认证的代理服务器 | // 使用代理服务器 需要用户认证的代理服务器 | ||||
CredentialsProvider provider = new BasicCredentialsProvider(); | CredentialsProvider provider = new BasicCredentialsProvider(); | ||||
provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort), | |||||
new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword)); | |||||
provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort) | |||||
, new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword)); | |||||
this.httpClientBuilder.setDefaultCredentialsProvider(provider); | this.httpClientBuilder.setDefaultCredentialsProvider(provider); | ||||
} | } | ||||
@@ -267,8 +269,10 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
private final int checkWaitTime; | private final int checkWaitTime; | ||||
private volatile boolean shutdown; | private volatile boolean shutdown; | ||||
public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, | |||||
int checkWaitTime) { | |||||
/** | |||||
* 构造方法. | |||||
*/ | |||||
public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, int checkWaitTime) { | |||||
super("IdleConnectionMonitorThread"); | super("IdleConnectionMonitorThread"); | ||||
this.connMgr = connMgr; | this.connMgr = connMgr; | ||||
this.idleConnTimeout = idleConnTimeout; | this.idleConnTimeout = idleConnTimeout; | ||||
@@ -289,12 +293,18 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 触发. | |||||
*/ | |||||
public void trigger() { | public void trigger() { | ||||
synchronized (this) { | synchronized (this) { | ||||
notifyAll(); | notifyAll(); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* 关闭. | |||||
*/ | |||||
public void shutdown() { | public void shutdown() { | ||||
this.shutdown = true; | this.shutdown = true; | ||||
synchronized (this) { | synchronized (this) { | ||||
@@ -4,7 +4,7 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | import me.chanjar.weixin.common.util.http.HttpResponseProxy; | ||||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import org.apache.commons.io.FilenameUtils; | import org.apache.commons.io.FilenameUtils; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -23,7 +23,7 @@ import java.io.InputStream; | |||||
/** | /** | ||||
* Created by ecoolper on 2017/5/5. | * Created by ecoolper on 2017/5/5. | ||||
*/ | */ | ||||
public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> { | |||||
public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> { | |||||
public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | ||||
super(requestHttp, tmpDirFile); | super(requestHttp, tmpDirFile); | ||||
@@ -39,9 +39,7 @@ public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<C | |||||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { | try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { | ||||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
if (responseContent.isEmpty()) { | if (responseContent.isEmpty()) { | ||||
throw new WxErrorException( | |||||
WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
.build()); | |||||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); | |||||
} | } | ||||
if (responseContent.startsWith("<xml>")) { | if (responseContent.startsWith("<xml>")) { | ||||
@@ -9,7 +9,7 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | import me.chanjar.weixin.common.util.http.HttpResponseProxy; | ||||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import org.apache.commons.io.FilenameUtils; | import org.apache.commons.io.FilenameUtils; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
@@ -22,7 +22,7 @@ import java.io.InputStream; | |||||
/** | /** | ||||
* Created by ecoolper on 2017/5/5. | * Created by ecoolper on 2017/5/5. | ||||
*/ | */ | ||||
public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||||
public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||||
public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | ||||
super(requestHttp, tmpDirFile); | super(requestHttp, tmpDirFile); | ||||
@@ -5,7 +5,6 @@ import jodd.http.HttpRequest; | |||||
import jodd.http.HttpResponse; | import jodd.http.HttpResponse; | ||||
import jodd.http.ProxyInfo; | import jodd.http.ProxyInfo; | ||||
import jodd.util.StringPool; | import jodd.util.StringPool; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
@@ -40,9 +39,8 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor | |||||
String responseContent = response.bodyText(); | String responseContent = response.bodyText(); | ||||
if (responseContent.isEmpty()) { | if (responseContent.isEmpty()) { | ||||
throw new WxErrorException( | |||||
WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
.build()); | |||||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") | |||||
.build()); | |||||
} | } | ||||
if (responseContent.startsWith("<xml>")) { | if (responseContent.startsWith("<xml>")) { | ||||
@@ -2,8 +2,8 @@ package me.chanjar.weixin.common.util.http.okhttp; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | import me.chanjar.weixin.common.util.http.HttpResponseProxy; | ||||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
import okhttp3.OkHttpClient; | import okhttp3.OkHttpClient; | ||||
import okhttp3.Request; | import okhttp3.Request; | ||||
@@ -21,7 +21,7 @@ import java.io.IOException; | |||||
/** | /** | ||||
* Created by ecoolper on 2017/5/5. | * Created by ecoolper on 2017/5/5. | ||||
*/ | */ | ||||
public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||||
public class OkHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | ||||
@@ -14,23 +14,26 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||||
import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
/** | /** | ||||
* @author Daniel Qian | |||||
* @author Daniel Qian. | |||||
*/ | */ | ||||
public class WxErrorAdapter implements JsonDeserializer<WxError> { | public class WxErrorAdapter implements JsonDeserializer<WxError> { | ||||
@Override | @Override | ||||
public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||||
WxError wxError = new WxError(); | |||||
public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | |||||
throws JsonParseException { | |||||
WxError.WxErrorBuilder errorBuilder = WxError.builder(); | |||||
JsonObject wxErrorJsonObject = json.getAsJsonObject(); | JsonObject wxErrorJsonObject = json.getAsJsonObject(); | ||||
if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { | if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { | ||||
wxError.setErrorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); | |||||
errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); | |||||
} | } | ||||
if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { | if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { | ||||
wxError.setErrorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); | |||||
errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); | |||||
} | } | ||||
wxError.setJson(json.toString()); | |||||
return wxError; | |||||
errorBuilder.json(json.toString()); | |||||
return errorBuilder.build(); | |||||
} | } | ||||
} | } |
@@ -70,6 +70,7 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ | |||||
return matchRule; | return matchRule; | ||||
} | } | ||||
@Deprecated | |||||
private WxMenuRule convertToRule(JsonObject json) { | private WxMenuRule convertToRule(JsonObject json) { | ||||
WxMenuRule menuRule = new WxMenuRule(); | WxMenuRule menuRule = new WxMenuRule(); | ||||
//变态的微信接口,这里居然反人类的使用和序列化时不一样的名字 | //变态的微信接口,这里居然反人类的使用和序列化时不一样的名字 | ||||
@@ -8,7 +8,6 @@ import org.testng.annotations.*; | |||||
public class WxErrorTest { | public class WxErrorTest { | ||||
public void testFromJson() { | public void testFromJson() { | ||||
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; | String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; | ||||
WxError wxError = WxError.fromJson(json); | WxError wxError = WxError.fromJson(json); | ||||
Assert.assertTrue(wxError.getErrorCode() == 40003); | Assert.assertTrue(wxError.getErrorCode() == 40003); | ||||
@@ -10,7 +10,7 @@ import static org.testng.Assert.assertNotNull; | |||||
* Created by BinaryWang on 2017/6/10. | * Created by BinaryWang on 2017/6/10. | ||||
* </pre> | * </pre> | ||||
* | * | ||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | */ | ||||
public class SHA1Test { | public class SHA1Test { | ||||
@Test | @Test | ||||
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>2.8.0</version> | |||||
<version>2.9.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-cp</artifactId> | <artifactId>weixin-java-cp</artifactId> | ||||
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.api.impl; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.cp.api.WxCpMediaService; | import me.chanjar.weixin.cp.api.WxCpMediaService; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
@@ -43,7 +43,7 @@ public class WxCpMediaServiceImpl implements WxCpMediaService { | |||||
public File download(String mediaId) throws WxErrorException { | public File download(String mediaId) throws WxErrorException { | ||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; | String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; | ||||
return this.mainService.execute( | return this.mainService.execute( | ||||
MediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(), | |||||
BaseMediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(), | |||||
this.mainService.getWxCpConfigStorage().getTmpDirFile()), | this.mainService.getWxCpConfigStorage().getTmpDirFile()), | ||||
url, "media_id=" + mediaId); | url, "media_id=" + mediaId); | ||||
} | } | ||||
@@ -381,7 +381,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ | |||||
throw new RuntimeException("微信服务端异常,超出重试次数"); | throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||
} | } | ||||
protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
if (uri.contains("access_token=")) { | if (uri.contains("access_token=")) { | ||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | ||||
} | } | ||||
@@ -4,8 +4,9 @@ package me.chanjar.weixin.cp.api.impl; | |||||
* <pre> | * <pre> | ||||
* 默认接口实现类,使用apache httpclient实现 | * 默认接口实现类,使用apache httpclient实现 | ||||
* Created by Binary Wang on 2017-5-27. | * Created by Binary Wang on 2017-5-27. | ||||
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
* </pre> | * </pre> | ||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
*/ | */ | ||||
public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { | public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { | ||||
} | } |
@@ -7,14 +7,10 @@ import me.chanjar.weixin.common.util.http.HttpType; | |||||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; | import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import okhttp3.*; | import okhttp3.*; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, OkHttpProxyInfo> { | public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, OkHttpProxyInfo> { | ||||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
protected OkHttpClient httpClient; | protected OkHttpClient httpClient; | ||||
protected OkHttpProxyInfo httpProxy; | protected OkHttpProxyInfo httpProxy; | ||||
@@ -36,7 +32,7 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, | |||||
@Override | @Override | ||||
public String getAccessToken(boolean forceRefresh) throws WxErrorException { | public String getAccessToken(boolean forceRefresh) throws WxErrorException { | ||||
logger.debug("WxCpServiceOkHttpImpl is running"); | |||||
this.log.debug("WxCpServiceOkHttpImpl is running"); | |||||
if (this.configStorage.isAccessTokenExpired() || forceRefresh) { | if (this.configStorage.isAccessTokenExpired() || forceRefresh) { | ||||
synchronized (this.globalAccessTokenRefreshLock) { | synchronized (this.globalAccessTokenRefreshLock) { | ||||
if (this.configStorage.isAccessTokenExpired()) { | if (this.configStorage.isAccessTokenExpired()) { | ||||
@@ -47,18 +43,14 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, | |||||
OkHttpClient client = getRequestHttpClient(); | OkHttpClient client = getRequestHttpClient(); | ||||
//请求的request | //请求的request | ||||
Request request = new Request.Builder().url(url).get().build(); | Request request = new Request.Builder().url(url).get().build(); | ||||
Response response = null; | |||||
try { | |||||
response = client.newCall(request).execute(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
String resultContent = null; | String resultContent = null; | ||||
try { | try { | ||||
Response response = client.newCall(request).execute(); | |||||
resultContent = response.body().string(); | resultContent = response.body().string(); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
e.printStackTrace(); | |||||
this.log.error(e.getMessage(), e); | |||||
} | } | ||||
WxError error = WxError.fromJson(resultContent); | WxError error = WxError.fromJson(resultContent); | ||||
if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
throw new WxErrorException(error); | throw new WxErrorException(error); | ||||
@@ -74,9 +66,16 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, | |||||
@Override | @Override | ||||
public void initHttp() { | public void initHttp() { | ||||
logger.debug("WxCpServiceOkHttpImpl initHttp"); | |||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); | |||||
this.log.debug("WxCpServiceOkHttpImpl initHttp"); | |||||
//设置代理 | //设置代理 | ||||
if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { | |||||
httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), | |||||
configStorage.getHttpProxyPort(), | |||||
configStorage.getHttpProxyUsername(), | |||||
configStorage.getHttpProxyPassword()); | |||||
} | |||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); | |||||
if (httpProxy != null) { | if (httpProxy != null) { | ||||
clientBuilder.proxy(getRequestHttpProxy().getProxy()); | clientBuilder.proxy(getRequestHttpProxy().getProxy()); | ||||
@@ -1,69 +1,30 @@ | |||||
package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* 微信部门 | |||||
* 微信部门. | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Data | |||||
public class WxCpDepart implements Serializable { | public class WxCpDepart implements Serializable { | ||||
private static final long serialVersionUID = -5028321625140879571L; | private static final long serialVersionUID = -5028321625140879571L; | ||||
private Integer id; | private Integer id; | ||||
private String name; | private String name; | ||||
private Integer parentId; | private Integer parentId; | ||||
private Integer order; | |||||
private Long order; | |||||
public static WxCpDepart fromJson(String json) { | public static WxCpDepart fromJson(String json) { | ||||
return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); | ||||
} | } | ||||
public Integer getId() { | |||||
return this.id; | |||||
} | |||||
public void setId(Integer id) { | |||||
this.id = id; | |||||
} | |||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public Integer getParentId() { | |||||
return this.parentId; | |||||
} | |||||
public void setParentId(Integer parentId) { | |||||
this.parentId = parentId; | |||||
} | |||||
public Integer getOrder() { | |||||
return this.order; | |||||
} | |||||
public void setOrder(Integer order) { | |||||
this.order = order; | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxCpGsonBuilder.create().toJson(this); | return WxCpGsonBuilder.create().toJson(this); | ||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return "WxCpDepart{" + | |||||
"id=" + this.id + | |||||
", name='" + this.name + '\'' + | |||||
", parentId=" + this.parentId + | |||||
", order=" + this.order + | |||||
'}'; | |||||
} | |||||
} | } |
@@ -1,5 +1,7 @@ | |||||
package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | |||||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
import me.chanjar.weixin.cp.bean.article.NewArticle; | import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
import me.chanjar.weixin.cp.bean.messagebuilder.*; | import me.chanjar.weixin.cp.bean.messagebuilder.*; | ||||
@@ -10,13 +12,14 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* 消息 | |||||
* 消息. | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Data | |||||
public class WxCpMessage implements Serializable { | public class WxCpMessage implements Serializable { | ||||
private static final long serialVersionUID = -2082278303476631708L; | private static final long serialVersionUID = -2082278303476631708L; | ||||
private String toUser; | private String toUser; | ||||
private String toParty; | private String toParty; | ||||
private String toTag; | private String toTag; | ||||
@@ -35,115 +38,72 @@ public class WxCpMessage implements Serializable { | |||||
private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | ||||
/** | /** | ||||
* 获得文本消息builder | |||||
* 获得文本消息builder. | |||||
*/ | */ | ||||
public static TextBuilder TEXT() { | public static TextBuilder TEXT() { | ||||
return new TextBuilder(); | return new TextBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得文本卡片消息builder | |||||
* 获得文本卡片消息builder. | |||||
*/ | */ | ||||
public static TextCardBuilder TEXTCARD() { | public static TextCardBuilder TEXTCARD() { | ||||
return new TextCardBuilder(); | return new TextCardBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得图片消息builder | |||||
* 获得图片消息builder. | |||||
*/ | */ | ||||
public static ImageBuilder IMAGE() { | public static ImageBuilder IMAGE() { | ||||
return new ImageBuilder(); | return new ImageBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得语音消息builder | |||||
* 获得语音消息builder. | |||||
*/ | */ | ||||
public static VoiceBuilder VOICE() { | public static VoiceBuilder VOICE() { | ||||
return new VoiceBuilder(); | return new VoiceBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得视频消息builder | |||||
* 获得视频消息builder. | |||||
*/ | */ | ||||
public static VideoBuilder VIDEO() { | public static VideoBuilder VIDEO() { | ||||
return new VideoBuilder(); | return new VideoBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得图文消息builder | |||||
* 获得图文消息builder. | |||||
*/ | */ | ||||
public static NewsBuilder NEWS() { | public static NewsBuilder NEWS() { | ||||
return new NewsBuilder(); | return new NewsBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得mpnews图文消息builder | |||||
* 获得mpnews图文消息builder. | |||||
*/ | */ | ||||
public static MpnewsBuilder MPNEWS() { | public static MpnewsBuilder MPNEWS() { | ||||
return new MpnewsBuilder(); | return new MpnewsBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得文件消息builder | |||||
* 获得文件消息builder. | |||||
*/ | */ | ||||
public static FileBuilder FILE() { | public static FileBuilder FILE() { | ||||
return new FileBuilder(); | return new FileBuilder(); | ||||
} | } | ||||
public List<MpnewsArticle> getMpnewsArticles() { | |||||
return mpnewsArticles; | |||||
} | |||||
public void setMpnewsArticles(List<MpnewsArticle> mpnewsArticles) { | |||||
this.mpnewsArticles = mpnewsArticles; | |||||
} | |||||
public String getToUser() { | |||||
return this.toUser; | |||||
} | |||||
public void setToUser(String toUser) { | |||||
this.toUser = toUser; | |||||
} | |||||
public String getToParty() { | |||||
return this.toParty; | |||||
} | |||||
public void setToParty(String toParty) { | |||||
this.toParty = toParty; | |||||
} | |||||
public String getToTag() { | |||||
return this.toTag; | |||||
} | |||||
public void setToTag(String toTag) { | |||||
this.toTag = toTag; | |||||
} | |||||
public Integer getAgentId() { | |||||
return this.agentId; | |||||
} | |||||
public void setAgentId(Integer agentId) { | |||||
this.agentId = agentId; | |||||
} | |||||
public String getMsgType() { | |||||
return this.msgType; | |||||
} | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 请使用 | * 请使用 | ||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_TEXT} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_IMAGE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VOICE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS} | |||||
* {@link WxConsts.KefuMsgType#TEXT} | |||||
* {@link WxConsts.KefuMsgType#IMAGE} | |||||
* {@link WxConsts.KefuMsgType#VOICE} | |||||
* {@link WxConsts.KefuMsgType#MUSIC} | |||||
* {@link WxConsts.KefuMsgType#VIDEO} | |||||
* {@link WxConsts.KefuMsgType#NEWS} | |||||
* {@link WxConsts.KefuMsgType#MPNEWS} | |||||
* </pre> | * </pre> | ||||
* | * | ||||
* @param msgType 消息类型 | * @param msgType 消息类型 | ||||
@@ -152,87 +112,8 @@ public class WxCpMessage implements Serializable { | |||||
this.msgType = msgType; | this.msgType = msgType; | ||||
} | } | ||||
public String getSafe() { | |||||
return this.safe; | |||||
} | |||||
public void setSafe(String safe) { | |||||
this.safe = safe; | |||||
} | |||||
public String getContent() { | |||||
return this.content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getThumbMediaId() { | |||||
return this.thumbMediaId; | |||||
} | |||||
public void setThumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
} | |||||
public String getTitle() { | |||||
return this.title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.description = description; | |||||
} | |||||
public String getMusicUrl() { | |||||
return this.musicUrl; | |||||
} | |||||
public void setMusicUrl(String musicUrl) { | |||||
this.musicUrl = musicUrl; | |||||
} | |||||
public String getHqMusicUrl() { | |||||
return this.hqMusicUrl; | |||||
} | |||||
public void setHqMusicUrl(String hqMusicUrl) { | |||||
this.hqMusicUrl = hqMusicUrl; | |||||
} | |||||
public List<NewArticle> getArticles() { | |||||
return this.articles; | |||||
} | |||||
public void setArticles(List<NewArticle> articles) { | |||||
this.articles = articles; | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxCpGsonBuilder.INSTANCE.create().toJson(this); | return WxCpGsonBuilder.INSTANCE.create().toJson(this); | ||||
} | } | ||||
public String getUrl() { | |||||
return this.url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.url = url; | |||||
} | |||||
} | } |
@@ -2,21 +2,25 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.google.common.base.Splitter; | import com.google.common.base.Splitter; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.io.Serializable; | |||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* <pre> | |||||
* 消息发送结果对象类 | |||||
* 消息发送结果对象类. | |||||
* Created by Binary Wang on 2017-6-22. | * Created by Binary Wang on 2017-6-22. | ||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
* </pre> | |||||
*/ | */ | ||||
public class WxCpMessageSendResult { | |||||
@Data | |||||
public class WxCpMessageSendResult implements Serializable { | |||||
private static final long serialVersionUID = 916455987193190004L; | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
@@ -41,52 +45,13 @@ public class WxCpMessageSendResult { | |||||
@SerializedName("invalidtag") | @SerializedName("invalidtag") | ||||
private String invalidTag; | private String invalidTag; | ||||
public Integer getErrCode() { | |||||
return this.errCode; | |||||
} | |||||
public void setErrCode(Integer errCode) { | |||||
this.errCode = errCode; | |||||
} | |||||
public String getErrMsg() { | |||||
return this.errMsg; | |||||
} | |||||
public void setErrMsg(String errMsg) { | |||||
this.errMsg = errMsg; | |||||
} | |||||
public String getInvalidUser() { | |||||
return this.invalidUser; | |||||
} | |||||
public void setInvalidUser(String invalidUser) { | |||||
this.invalidUser = invalidUser; | |||||
} | |||||
public String getInvalidParty() { | |||||
return this.invalidParty; | |||||
} | |||||
public void setInvalidParty(String invalidParty) { | |||||
this.invalidParty = invalidParty; | |||||
} | |||||
public String getInvalidTag() { | |||||
return this.invalidTag; | |||||
} | |||||
public void setInvalidTag(String invalidTag) { | |||||
this.invalidTag = invalidTag; | |||||
} | |||||
public List<String> getInvalidUserList() { | public List<String> getInvalidUserList() { | ||||
return this.content2List(this.invalidUser); | return this.content2List(this.invalidUser); | ||||
} | } | ||||
private List<String> content2List(String content) { | private List<String> content2List(String content) { | ||||
if(StringUtils.isBlank(content)){ | |||||
if (StringUtils.isBlank(content)) { | |||||
return Collections.emptyList(); | return Collections.emptyList(); | ||||
} | } | ||||
@@ -1,50 +1,30 @@ | |||||
package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* Created by Daniel Qian | |||||
* Created by Daniel Qian. | |||||
*/ | */ | ||||
@Data | |||||
@AllArgsConstructor | |||||
@NoArgsConstructor | |||||
public class WxCpTag implements Serializable { | public class WxCpTag implements Serializable { | ||||
private static final long serialVersionUID = -7243320279646928402L; | private static final long serialVersionUID = -7243320279646928402L; | ||||
private String id; | private String id; | ||||
private String name; | private String name; | ||||
public WxCpTag() { | |||||
super(); | |||||
} | |||||
public WxCpTag(String id, String name) { | |||||
super(); | |||||
this.id = id; | |||||
this.name = name; | |||||
} | |||||
public static WxCpTag fromJson(String json) { | public static WxCpTag fromJson(String json) { | ||||
return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); | return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); | ||||
} | } | ||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getId() { | |||||
return this.id; | |||||
} | |||||
public void setId(String id) { | |||||
this.id = id; | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxCpGsonBuilder.create().toJson(this); | return WxCpGsonBuilder.create().toJson(this); | ||||
} | } | ||||
@@ -2,21 +2,25 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.google.common.base.Splitter; | import com.google.common.base.Splitter; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import java.io.Serializable; | |||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* <pre> | |||||
* 为标签添加或移除用户结果对象类 | |||||
* 为标签添加或移除用户结果对象类. | |||||
* Created by Binary Wang on 2017-6-22. | * Created by Binary Wang on 2017-6-22. | ||||
* | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
* </pre> | |||||
*/ | */ | ||||
public class WxCpTagAddOrRemoveUsersResult { | |||||
@Data | |||||
public class WxCpTagAddOrRemoveUsersResult implements Serializable { | |||||
private static final long serialVersionUID = 1420065684270213578L; | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return ToStringUtils.toSimpleString(this); | return ToStringUtils.toSimpleString(this); | ||||
@@ -38,44 +42,12 @@ public class WxCpTagAddOrRemoveUsersResult { | |||||
@SerializedName("invalidparty") | @SerializedName("invalidparty") | ||||
private String[] invalidParty; | private String[] invalidParty; | ||||
public Integer getErrCode() { | |||||
return this.errCode; | |||||
} | |||||
public void setErrCode(Integer errCode) { | |||||
this.errCode = errCode; | |||||
} | |||||
public String getErrMsg() { | |||||
return this.errMsg; | |||||
} | |||||
public void setErrMsg(String errMsg) { | |||||
this.errMsg = errMsg; | |||||
} | |||||
public String getInvalidUser() { | |||||
return this.invalidUsers; | |||||
} | |||||
public void setInvalidUser(String invalidUser) { | |||||
this.invalidUsers = invalidUser; | |||||
} | |||||
public String[] getInvalidParty() { | |||||
return this.invalidParty; | |||||
} | |||||
public void setInvalidParty(String[] invalidParty) { | |||||
this.invalidParty = invalidParty; | |||||
} | |||||
public List<String> getInvalidUserList() { | public List<String> getInvalidUserList() { | ||||
return this.content2List(this.invalidUsers); | return this.content2List(this.invalidUsers); | ||||
} | } | ||||
private List<String> content2List(String content) { | private List<String> content2List(String content) { | ||||
if(StringUtils.isBlank(content)){ | |||||
if (StringUtils.isBlank(content)) { | |||||
return Collections.emptyList(); | return Collections.emptyList(); | ||||
} | } | ||||
@@ -1,5 +1,7 @@ | |||||
package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -7,12 +9,12 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
/** | /** | ||||
* 微信用户信息 | |||||
* 微信用户信息. | |||||
* | * | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@Data | |||||
public class WxCpUser implements Serializable { | public class WxCpUser implements Serializable { | ||||
public enum Gender { | public enum Gender { | ||||
MALE("男", "1"), | MALE("男", "1"), | ||||
FEMAIL("女", "2"); | FEMAIL("女", "2"); | ||||
@@ -62,159 +64,23 @@ public class WxCpUser implements Serializable { | |||||
private String englishName; | private String englishName; | ||||
private String telephone; | private String telephone; | ||||
public static WxCpUser fromJson(String json) { | |||||
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); | |||||
} | |||||
public String getUserId() { | |||||
return this.userId; | |||||
} | |||||
public void setUserId(String userId) { | |||||
this.userId = userId; | |||||
} | |||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public Integer[] getDepartIds() { | |||||
return this.departIds; | |||||
} | |||||
public void setDepartIds(Integer[] departIds) { | |||||
this.departIds = departIds; | |||||
} | |||||
public Gender getGender() { | |||||
return this.gender; | |||||
} | |||||
public void setGender(Gender gender) { | |||||
this.gender = gender; | |||||
} | |||||
public String getPosition() { | |||||
return this.position; | |||||
} | |||||
public void setPosition(String position) { | |||||
this.position = position; | |||||
} | |||||
public String getMobile() { | |||||
return this.mobile; | |||||
} | |||||
public void setMobile(String mobile) { | |||||
this.mobile = mobile; | |||||
} | |||||
public String getTelephone() { | |||||
return this.telephone; | |||||
} | |||||
public void setTelephone(String telephone) { | |||||
this.telephone = telephone; | |||||
} | |||||
public String getEmail() { | |||||
return this.email; | |||||
} | |||||
public void setEmail(String email) { | |||||
this.email = email; | |||||
} | |||||
public String getAvatar() { | |||||
return this.avatar; | |||||
} | |||||
public void setAvatar(String avatar) { | |||||
this.avatar = avatar; | |||||
} | |||||
public Integer getStatus() { | |||||
return this.status; | |||||
} | |||||
public void setStatus(Integer status) { | |||||
this.status = status; | |||||
} | |||||
public Integer getEnable() { | |||||
return this.enable; | |||||
} | |||||
public void setEnable(Integer enable) { | |||||
this.enable = enable; | |||||
} | |||||
public void addExtAttr(String name, String value) { | public void addExtAttr(String name, String value) { | ||||
this.extAttrs.add(new Attr(name, value)); | this.extAttrs.add(new Attr(name, value)); | ||||
} | } | ||||
public List<Attr> getExtAttrs() { | |||||
return this.extAttrs; | |||||
} | |||||
public Integer getIsLeader() { | |||||
return isLeader; | |||||
} | |||||
public void setIsLeader(Integer isLeader) { | |||||
this.isLeader = isLeader; | |||||
} | |||||
public Integer getHideMobile() { | |||||
return hideMobile; | |||||
} | |||||
public void setHideMobile(Integer hideMobile) { | |||||
this.hideMobile = hideMobile; | |||||
} | |||||
public String getEnglishName() { | |||||
return englishName; | |||||
} | |||||
public void setEnglishName(String englishName) { | |||||
this.englishName = englishName; | |||||
public static WxCpUser fromJson(String json) { | |||||
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); | |||||
} | } | ||||
public String toJson() { | public String toJson() { | ||||
return WxCpGsonBuilder.INSTANCE.create().toJson(this); | return WxCpGsonBuilder.INSTANCE.create().toJson(this); | ||||
} | } | ||||
@Data | |||||
@AllArgsConstructor | |||||
public static class Attr { | public static class Attr { | ||||
private String name; | private String name; | ||||
private String value; | private String value; | ||||
public Attr(String name, String value) { | |||||
this.name = name; | |||||
this.value = value; | |||||
} | |||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getValue() { | |||||
return this.value; | |||||
} | |||||
public void setValue(String value) { | |||||
this.value = value; | |||||
} | |||||
} | } | ||||
} | } |
@@ -2,6 +2,9 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | |||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | ||||
@@ -26,6 +29,7 @@ import java.util.List; | |||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlMessage implements Serializable { | public class WxCpXmlMessage implements Serializable { | ||||
private static final long serialVersionUID = -1042994982179476410L; | private static final long serialVersionUID = -1042994982179476410L; | ||||
@@ -128,28 +132,29 @@ public class WxCpXmlMessage implements Serializable { | |||||
// 群发消息返回的结果 | // 群发消息返回的结果 | ||||
/////////////////////////////////////// | /////////////////////////////////////// | ||||
/** | /** | ||||
* 群发的结果 | |||||
* 群发的结果. | |||||
*/ | */ | ||||
@XStreamAlias("Status") | @XStreamAlias("Status") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String status; | private String status; | ||||
/** | /** | ||||
* group_id下粉丝数;或者openid_list中的粉丝数 | |||||
* group_id下粉丝数;或者openid_list中的粉丝数. | |||||
*/ | */ | ||||
@XStreamAlias("TotalCount") | @XStreamAlias("TotalCount") | ||||
private Integer totalCount; | private Integer totalCount; | ||||
/** | /** | ||||
* 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount | |||||
* 过滤. | |||||
* (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount | |||||
*/ | */ | ||||
@XStreamAlias("FilterCount") | @XStreamAlias("FilterCount") | ||||
private Integer filterCount; | private Integer filterCount; | ||||
/** | /** | ||||
* 发送成功的粉丝数 | |||||
* 发送成功的粉丝数. | |||||
*/ | */ | ||||
@XStreamAlias("SentCount") | @XStreamAlias("SentCount") | ||||
private Integer sentCount; | private Integer sentCount; | ||||
/** | /** | ||||
* 发送失败的粉丝数 | |||||
* 发送失败的粉丝数. | |||||
*/ | */ | ||||
@XStreamAlias("ErrorCount") | @XStreamAlias("ErrorCount") | ||||
private Integer errorCount; | private Integer errorCount; | ||||
@@ -174,13 +179,7 @@ public class WxCpXmlMessage implements Serializable { | |||||
} | } | ||||
/** | /** | ||||
* 从加密字符串转换 | |||||
* | |||||
* @param encryptedXml | |||||
* @param wxCpConfigStorage | |||||
* @param timestamp | |||||
* @param nonce | |||||
* @param msgSignature | |||||
* 从加密字符串转换. | |||||
*/ | */ | ||||
public static WxCpXmlMessage fromEncryptedXml( | public static WxCpXmlMessage fromEncryptedXml( | ||||
String encryptedXml, | String encryptedXml, | ||||
@@ -202,40 +201,16 @@ public class WxCpXmlMessage implements Serializable { | |||||
} | } | ||||
} | } | ||||
public Integer getAgentId() { | |||||
return this.agentId; | |||||
} | |||||
public void setAgentId(Integer agentId) { | |||||
this.agentId = agentId; | |||||
} | |||||
public String getToUserName() { | |||||
return this.toUserName; | |||||
} | |||||
public void setToUserName(String toUserName) { | |||||
this.toUserName = toUserName; | |||||
} | |||||
public Long getCreateTime() { | |||||
return this.createTime; | |||||
} | |||||
public void setCreateTime(Long createTime) { | |||||
this.createTime = createTime; | |||||
} | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 当接受用户消息时,可能会获得以下值: | * 当接受用户消息时,可能会获得以下值: | ||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LOCATION} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT} | |||||
* {@link WxConsts.XmlMsgType#TEXT} | |||||
* {@link WxConsts.XmlMsgType#IMAGE} | |||||
* {@link WxConsts.XmlMsgType#VOICE} | |||||
* {@link WxConsts.XmlMsgType#VIDEO} | |||||
* {@link WxConsts.XmlMsgType#LOCATION} | |||||
* {@link WxConsts.XmlMsgType#LINK} | |||||
* {@link WxConsts.XmlMsgType#EVENT} | |||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
public String getMsgType() { | public String getMsgType() { | ||||
@@ -245,363 +220,60 @@ public class WxCpXmlMessage implements Serializable { | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 当发送消息的时候使用: | * 当发送消息的时候使用: | ||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO} | |||||
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_NEWS} | |||||
* {@link WxConsts.XmlMsgType#TEXT} | |||||
* {@link WxConsts.XmlMsgType#IMAGE} | |||||
* {@link WxConsts.XmlMsgType#VOICE} | |||||
* {@link WxConsts.XmlMsgType#VIDEO} | |||||
* {@link WxConsts.XmlMsgType#NEWS} | |||||
* </pre> | * </pre> | ||||
* | |||||
* @param msgType | |||||
*/ | */ | ||||
public void setMsgType(String msgType) { | public void setMsgType(String msgType) { | ||||
this.msgType = msgType; | this.msgType = msgType; | ||||
} | } | ||||
public String getContent() { | |||||
return this.content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public Long getMsgId() { | |||||
return this.msgId; | |||||
} | |||||
public void setMsgId(Long msgId) { | |||||
this.msgId = msgId; | |||||
} | |||||
public String getPicUrl() { | |||||
return this.picUrl; | |||||
} | |||||
public void setPicUrl(String picUrl) { | |||||
this.picUrl = picUrl; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getFormat() { | |||||
return this.format; | |||||
} | |||||
public void setFormat(String format) { | |||||
this.format = format; | |||||
} | |||||
public String getThumbMediaId() { | |||||
return this.thumbMediaId; | |||||
} | |||||
public void setThumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
} | |||||
public Double getLocationX() { | |||||
return this.locationX; | |||||
} | |||||
public void setLocationX(Double locationX) { | |||||
this.locationX = locationX; | |||||
} | |||||
public Double getLocationY() { | |||||
return this.locationY; | |||||
} | |||||
public void setLocationY(Double locationY) { | |||||
this.locationY = locationY; | |||||
} | |||||
public Double getScale() { | |||||
return this.scale; | |||||
} | |||||
public void setScale(Double scale) { | |||||
this.scale = scale; | |||||
} | |||||
public String getLabel() { | |||||
return this.label; | |||||
} | |||||
public void setLabel(String label) { | |||||
this.label = label; | |||||
} | |||||
public String getTitle() { | |||||
return this.title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.description = description; | |||||
} | |||||
public String getUrl() { | |||||
return this.url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.url = url; | |||||
} | |||||
public String getEvent() { | |||||
return this.event; | |||||
} | |||||
public void setEvent(String event) { | |||||
this.event = event; | |||||
} | |||||
public String getEventKey() { | |||||
return this.eventKey; | |||||
} | |||||
public void setEventKey(String eventKey) { | |||||
this.eventKey = eventKey; | |||||
} | |||||
public String getTicket() { | |||||
return this.ticket; | |||||
} | |||||
public void setTicket(String ticket) { | |||||
this.ticket = ticket; | |||||
} | |||||
public Double getLatitude() { | |||||
return this.latitude; | |||||
} | |||||
public void setLatitude(Double latitude) { | |||||
this.latitude = latitude; | |||||
} | |||||
public Double getLongitude() { | |||||
return this.longitude; | |||||
} | |||||
public void setLongitude(Double longitude) { | |||||
this.longitude = longitude; | |||||
} | |||||
public Double getPrecision() { | |||||
return this.precision; | |||||
} | |||||
public void setPrecision(Double precision) { | |||||
this.precision = precision; | |||||
} | |||||
public String getRecognition() { | |||||
return this.recognition; | |||||
} | |||||
public void setRecognition(String recognition) { | |||||
this.recognition = recognition; | |||||
} | |||||
public String getFromUserName() { | |||||
return this.fromUserName; | |||||
} | |||||
public void setFromUserName(String fromUserName) { | |||||
this.fromUserName = fromUserName; | |||||
} | |||||
public String getStatus() { | |||||
return this.status; | |||||
} | |||||
public void setStatus(String status) { | |||||
this.status = status; | |||||
} | |||||
public Integer getTotalCount() { | |||||
return this.totalCount; | |||||
} | |||||
public void setTotalCount(Integer totalCount) { | |||||
this.totalCount = totalCount; | |||||
} | |||||
public Integer getFilterCount() { | |||||
return this.filterCount; | |||||
} | |||||
public void setFilterCount(Integer filterCount) { | |||||
this.filterCount = filterCount; | |||||
} | |||||
public Integer getSentCount() { | |||||
return this.sentCount; | |||||
} | |||||
public void setSentCount(Integer sentCount) { | |||||
this.sentCount = sentCount; | |||||
} | |||||
public Integer getErrorCount() { | |||||
return this.errorCount; | |||||
} | |||||
public void setErrorCount(Integer errorCount) { | |||||
this.errorCount = errorCount; | |||||
} | |||||
public WxCpXmlMessage.ScanCodeInfo getScanCodeInfo() { | |||||
return this.scanCodeInfo; | |||||
} | |||||
public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) { | |||||
this.scanCodeInfo = scanCodeInfo; | |||||
} | |||||
public WxCpXmlMessage.SendPicsInfo getSendPicsInfo() { | |||||
return this.sendPicsInfo; | |||||
} | |||||
public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) { | |||||
this.sendPicsInfo = sendPicsInfo; | |||||
} | |||||
public WxCpXmlMessage.SendLocationInfo getSendLocationInfo() { | |||||
return this.sendLocationInfo; | |||||
} | |||||
public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) { | |||||
this.sendLocationInfo = sendLocationInfo; | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return "WxCpXmlMessage{" + | |||||
"agentId=" + this.agentId + | |||||
", toUserName='" + this.toUserName + '\'' + | |||||
", fromUserName='" + this.fromUserName + '\'' + | |||||
", createTime=" + this.createTime + | |||||
", msgType='" + this.msgType + '\'' + | |||||
", content='" + this.content + '\'' + | |||||
", msgId=" + this.msgId + | |||||
", picUrl='" + this.picUrl + '\'' + | |||||
", mediaId='" + this.mediaId + '\'' + | |||||
", format='" + this.format + '\'' + | |||||
", thumbMediaId='" + this.thumbMediaId + '\'' + | |||||
", locationX=" + this.locationX + | |||||
", locationY=" + this.locationY + | |||||
", scale=" + this.scale + | |||||
", label='" + this.label + '\'' + | |||||
", title='" + this.title + '\'' + | |||||
", description='" + this.description + '\'' + | |||||
", url='" + this.url + '\'' + | |||||
", event='" + this.event + '\'' + | |||||
", eventKey='" + this.eventKey + '\'' + | |||||
", ticket='" + this.ticket + '\'' + | |||||
", latitude=" + this.latitude + | |||||
", longitude=" + this.longitude + | |||||
", precision=" + this.precision + | |||||
", recognition='" + this.recognition + '\'' + | |||||
", status='" + this.status + '\'' + | |||||
", totalCount=" + this.totalCount + | |||||
", filterCount=" + this.filterCount + | |||||
", sentCount=" + this.sentCount + | |||||
", errorCount=" + this.errorCount + | |||||
", scanCodeInfo=" + this.scanCodeInfo + | |||||
", sendPicsInfo=" + this.sendPicsInfo + | |||||
", sendLocationInfo=" + this.sendLocationInfo + | |||||
'}'; | |||||
return ToStringUtils.toSimpleString(this); | |||||
} | } | ||||
@Data | |||||
@XStreamAlias("ScanCodeInfo") | @XStreamAlias("ScanCodeInfo") | ||||
public static class ScanCodeInfo { | public static class ScanCodeInfo { | ||||
/** | |||||
* 扫描类型,一般是qrcode. | |||||
*/ | |||||
@XStreamAlias("ScanType") | @XStreamAlias("ScanType") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String scanType; | private String scanType; | ||||
/** | |||||
* 扫描结果,即二维码对应的字符串信息. | |||||
*/ | |||||
@XStreamAlias("ScanResult") | @XStreamAlias("ScanResult") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String scanResult; | private String scanResult; | ||||
/** | |||||
* 扫描类型,一般是qrcode | |||||
*/ | |||||
public String getScanType() { | |||||
return this.scanType; | |||||
} | |||||
public void setScanType(String scanType) { | |||||
this.scanType = scanType; | |||||
} | |||||
/** | |||||
* 扫描结果,即二维码对应的字符串信息 | |||||
*/ | |||||
public String getScanResult() { | |||||
return this.scanResult; | |||||
} | |||||
public void setScanResult(String scanResult) { | |||||
this.scanResult = scanResult; | |||||
} | |||||
} | } | ||||
@Data | |||||
@XStreamAlias("SendPicsInfo") | @XStreamAlias("SendPicsInfo") | ||||
public static class SendPicsInfo { | public static class SendPicsInfo { | ||||
@XStreamAlias("PicList") | @XStreamAlias("PicList") | ||||
protected final List<Item> picList = new ArrayList<>(); | protected final List<Item> picList = new ArrayList<>(); | ||||
@XStreamAlias("Count") | @XStreamAlias("Count") | ||||
private Long count; | private Long count; | ||||
public Long getCount() { | |||||
return this.count; | |||||
} | |||||
public void setCount(Long count) { | |||||
this.count = count; | |||||
} | |||||
public List<Item> getPicList() { | |||||
return this.picList; | |||||
} | |||||
@XStreamAlias("item") | @XStreamAlias("item") | ||||
@Data | |||||
public static class Item { | public static class Item { | ||||
@XStreamAlias("PicMd5Sum") | @XStreamAlias("PicMd5Sum") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String PicMd5Sum; | |||||
public String getPicMd5Sum() { | |||||
return this.PicMd5Sum; | |||||
} | |||||
public void setPicMd5Sum(String picMd5Sum) { | |||||
this.PicMd5Sum = picMd5Sum; | |||||
} | |||||
private String picMd5Sum; | |||||
} | } | ||||
} | } | ||||
@Data | |||||
@XStreamAlias("SendLocationInfo") | @XStreamAlias("SendLocationInfo") | ||||
public static class SendLocationInfo { | public static class SendLocationInfo { | ||||
@@ -623,47 +295,8 @@ public class WxCpXmlMessage implements Serializable { | |||||
@XStreamAlias("Poiname") | @XStreamAlias("Poiname") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String poiname; | |||||
public String getLocationX() { | |||||
return this.locationX; | |||||
} | |||||
public void setLocationX(String locationX) { | |||||
this.locationX = locationX; | |||||
} | |||||
public String getLocationY() { | |||||
return this.locationY; | |||||
} | |||||
public void setLocationY(String locationY) { | |||||
this.locationY = locationY; | |||||
} | |||||
private String poiName; | |||||
public String getScale() { | |||||
return this.scale; | |||||
} | |||||
public void setScale(String scale) { | |||||
this.scale = scale; | |||||
} | |||||
public String getLabel() { | |||||
return this.label; | |||||
} | |||||
public void setLabel(String label) { | |||||
this.label = label; | |||||
} | |||||
public String getPoiname() { | |||||
return this.poiname; | |||||
} | |||||
public void setPoiname(String poiname) { | |||||
this.poiname = poiname; | |||||
} | |||||
} | } | ||||
} | } |
@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = -1099446240667237313L; | private static final long serialVersionUID = -1099446240667237313L; | ||||
@@ -14,15 +16,7 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { | |||||
private String mediaId; | private String mediaId; | ||||
public WxCpXmlOutImageMessage() { | public WxCpXmlOutImageMessage() { | ||||
this.msgType = WxConsts.XML_MSG_IMAGE; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
this.msgType = WxConsts.XmlMsgType.IMAGE; | |||||
} | } | ||||
} | } |
@@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
import me.chanjar.weixin.cp.bean.outxmlbuilder.*; | import me.chanjar.weixin.cp.bean.outxmlbuilder.*; | ||||
@@ -11,8 +12,8 @@ import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public abstract class WxCpXmlOutMessage implements Serializable { | public abstract class WxCpXmlOutMessage implements Serializable { | ||||
private static final long serialVersionUID = 1418629839964153110L; | private static final long serialVersionUID = 1418629839964153110L; | ||||
@XStreamAlias("ToUserName") | @XStreamAlias("ToUserName") | ||||
@@ -31,78 +32,46 @@ public abstract class WxCpXmlOutMessage implements Serializable { | |||||
protected String msgType; | protected String msgType; | ||||
/** | /** | ||||
* 获得文本消息builder | |||||
* 获得文本消息builder. | |||||
*/ | */ | ||||
public static TextBuilder TEXT() { | public static TextBuilder TEXT() { | ||||
return new TextBuilder(); | return new TextBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得图片消息builder | |||||
* 获得图片消息builder. | |||||
*/ | */ | ||||
public static ImageBuilder IMAGE() { | public static ImageBuilder IMAGE() { | ||||
return new ImageBuilder(); | return new ImageBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得语音消息builder | |||||
* 获得语音消息builder. | |||||
*/ | */ | ||||
public static VoiceBuilder VOICE() { | public static VoiceBuilder VOICE() { | ||||
return new VoiceBuilder(); | return new VoiceBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得视频消息builder | |||||
* 获得视频消息builder. | |||||
*/ | */ | ||||
public static VideoBuilder VIDEO() { | public static VideoBuilder VIDEO() { | ||||
return new VideoBuilder(); | return new VideoBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得图文消息builder | |||||
* 获得图文消息builder. | |||||
*/ | */ | ||||
public static NewsBuilder NEWS() { | public static NewsBuilder NEWS() { | ||||
return new NewsBuilder(); | return new NewsBuilder(); | ||||
} | } | ||||
public String getToUserName() { | |||||
return this.toUserName; | |||||
} | |||||
public void setToUserName(String toUserName) { | |||||
this.toUserName = toUserName; | |||||
} | |||||
public String getFromUserName() { | |||||
return this.fromUserName; | |||||
} | |||||
public void setFromUserName(String fromUserName) { | |||||
this.fromUserName = fromUserName; | |||||
} | |||||
public Long getCreateTime() { | |||||
return this.createTime; | |||||
} | |||||
public void setCreateTime(Long createTime) { | |||||
this.createTime = createTime; | |||||
} | |||||
public String getMsgType() { | |||||
return this.msgType; | |||||
} | |||||
public void setMsgType(String msgType) { | |||||
this.msgType = msgType; | |||||
} | |||||
protected String toXml() { | protected String toXml() { | ||||
return XStreamTransformer.toXml((Class) this.getClass(), this); | return XStreamTransformer.toXml((Class) this.getClass(), this); | ||||
} | } | ||||
/** | /** | ||||
* 转换成加密的xml格式 | |||||
* 转换成加密的xml格式. | |||||
*/ | */ | ||||
public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { | public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { | ||||
String plainXml = toXml(); | String plainXml = toXml(); | ||||
@@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
@@ -9,84 +10,46 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = -5796178637883178826L; | private static final long serialVersionUID = -5796178637883178826L; | ||||
@XStreamAlias("Articles") | @XStreamAlias("Articles") | ||||
protected final List<Item> articles = new ArrayList<>(); | protected final List<Item> articles = new ArrayList<>(); | ||||
@XStreamAlias("ArticleCount") | @XStreamAlias("ArticleCount") | ||||
protected int articleCount; | protected int articleCount; | ||||
public WxCpXmlOutNewsMessage() { | public WxCpXmlOutNewsMessage() { | ||||
this.msgType = WxConsts.XML_MSG_NEWS; | |||||
this.msgType = WxConsts.XmlMsgType.NEWS; | |||||
} | } | ||||
public int getArticleCount() { | |||||
return this.articleCount; | |||||
} | |||||
public void addArticle(Item item) { | public void addArticle(Item item) { | ||||
this.articles.add(item); | this.articles.add(item); | ||||
this.articleCount = this.articles.size(); | this.articleCount = this.articles.size(); | ||||
} | } | ||||
public List<Item> getArticles() { | |||||
return this.articles; | |||||
} | |||||
@XStreamAlias("item") | @XStreamAlias("item") | ||||
@Data | |||||
public static class Item { | public static class Item { | ||||
@XStreamAlias("Title") | @XStreamAlias("Title") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String Title; | |||||
private String title; | |||||
@XStreamAlias("Description") | @XStreamAlias("Description") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String Description; | |||||
private String description; | |||||
@XStreamAlias("PicUrl") | @XStreamAlias("PicUrl") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String PicUrl; | |||||
private String picUrl; | |||||
@XStreamAlias("Url") | @XStreamAlias("Url") | ||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String Url; | |||||
public String getTitle() { | |||||
return this.Title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.Title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.Description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.Description = description; | |||||
} | |||||
public String getPicUrl() { | |||||
return this.PicUrl; | |||||
} | |||||
public void setPicUrl(String picUrl) { | |||||
this.PicUrl = picUrl; | |||||
} | |||||
public String getUrl() { | |||||
return this.Url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.Url = url; | |||||
} | |||||
private String url; | |||||
} | } | ||||
} | } |
@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = 2569239617185930232L; | private static final long serialVersionUID = 2569239617185930232L; | ||||
@@ -14,16 +16,7 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { | |||||
private String content; | private String content; | ||||
public WxCpXmlOutTextMessage() { | public WxCpXmlOutTextMessage() { | ||||
this.msgType = WxConsts.XML_MSG_TEXT; | |||||
this.msgType = WxConsts.XmlMsgType.TEXT; | |||||
} | } | ||||
public String getContent() { | |||||
return this.content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
} | } |
@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = -8672761162722733622L; | private static final long serialVersionUID = -8672761162722733622L; | ||||
@@ -13,7 +15,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||||
protected final Video video = new Video(); | protected final Video video = new Video(); | ||||
public WxCpXmlOutVideoMessage() { | public WxCpXmlOutVideoMessage() { | ||||
this.msgType = WxConsts.XML_MSG_VIDEO; | |||||
this.msgType = WxConsts.XmlMsgType.VIDEO; | |||||
} | } | ||||
public String getMediaId() { | public String getMediaId() { | ||||
@@ -40,7 +42,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||||
this.video.setDescription(description); | this.video.setDescription(description); | ||||
} | } | ||||
@Data | |||||
@XStreamAlias("Video") | @XStreamAlias("Video") | ||||
public static class Video { | public static class Video { | ||||
@@ -56,30 +58,6 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { | |||||
@XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
private String description; | private String description; | ||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getTitle() { | |||||
return this.title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.description = description; | |||||
} | |||||
} | } | ||||
} | } |
@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean; | |||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | ||||
private static final long serialVersionUID = -7947384031546099340L; | private static final long serialVersionUID = -7947384031546099340L; | ||||
@@ -14,15 +16,7 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { | |||||
private String mediaId; | private String mediaId; | ||||
public WxCpXmlOutVoiceMessage() { | public WxCpXmlOutVoiceMessage() { | ||||
this.msgType = WxConsts.XML_MSG_VOICE; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
this.msgType = WxConsts.XmlMsgType.VOICE; | |||||
} | } | ||||
} | } |
@@ -1,5 +1,8 @@ | |||||
package me.chanjar.weixin.cp.bean.article; | package me.chanjar.weixin.cp.bean.article; | ||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
@@ -9,6 +12,8 @@ import java.io.Serializable; | |||||
* | * | ||||
* @author Binary Wang | * @author Binary Wang | ||||
*/ | */ | ||||
@Data | |||||
@Builder(builderMethodName = "newBuilder") | |||||
public class MpnewsArticle implements Serializable { | public class MpnewsArticle implements Serializable { | ||||
private static final long serialVersionUID = 6985871812170756481L; | private static final long serialVersionUID = 6985871812170756481L; | ||||
@@ -20,125 +25,4 @@ public class MpnewsArticle implements Serializable { | |||||
private String digest; | private String digest; | ||||
private String showCoverPic; | private String showCoverPic; | ||||
private MpnewsArticle(Builder builder) { | |||||
setTitle(builder.title); | |||||
setThumbMediaId(builder.thumbMediaId); | |||||
setAuthor(builder.author); | |||||
setContentSourceUrl(builder.contentSourceUrl); | |||||
setContent(builder.content); | |||||
setDigest(builder.digest); | |||||
setShowCoverPic(builder.showCoverPic); | |||||
} | |||||
public static Builder newBuilder() { | |||||
return new Builder(); | |||||
} | |||||
public String getTitle() { | |||||
return title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getThumbMediaId() { | |||||
return thumbMediaId; | |||||
} | |||||
public void setThumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
} | |||||
public String getAuthor() { | |||||
return author; | |||||
} | |||||
public void setAuthor(String author) { | |||||
this.author = author; | |||||
} | |||||
public String getContentSourceUrl() { | |||||
return contentSourceUrl; | |||||
} | |||||
public void setContentSourceUrl(String contentSourceUrl) { | |||||
this.contentSourceUrl = contentSourceUrl; | |||||
} | |||||
public String getContent() { | |||||
return content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public String getDigest() { | |||||
return digest; | |||||
} | |||||
public void setDigest(String digest) { | |||||
this.digest = digest; | |||||
} | |||||
public String getShowCoverPic() { | |||||
return showCoverPic; | |||||
} | |||||
public void setShowCoverPic(String showCoverPic) { | |||||
this.showCoverPic = showCoverPic; | |||||
} | |||||
public static final class Builder { | |||||
private String title; | |||||
private String thumbMediaId; | |||||
private String author; | |||||
private String contentSourceUrl; | |||||
private String content; | |||||
private String digest; | |||||
private String showCoverPic; | |||||
private Builder() { | |||||
} | |||||
public Builder title(String title) { | |||||
this.title = title; | |||||
return this; | |||||
} | |||||
public Builder thumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
return this; | |||||
} | |||||
public Builder author(String author) { | |||||
this.author = author; | |||||
return this; | |||||
} | |||||
public Builder contentSourceUrl(String contentSourceUrl) { | |||||
this.contentSourceUrl = contentSourceUrl; | |||||
return this; | |||||
} | |||||
public Builder content(String content) { | |||||
this.content = content; | |||||
return this; | |||||
} | |||||
public Builder digest(String digest) { | |||||
this.digest = digest; | |||||
return this; | |||||
} | |||||
public Builder showCoverPic(String showCoverPic) { | |||||
this.showCoverPic = showCoverPic; | |||||
return this; | |||||
} | |||||
public MpnewsArticle build() { | |||||
return new MpnewsArticle(this); | |||||
} | |||||
} | |||||
} | } |
@@ -1,5 +1,7 @@ | |||||
package me.chanjar.weixin.cp.bean.article; | package me.chanjar.weixin.cp.bean.article; | ||||
import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
@@ -9,6 +11,7 @@ import java.io.Serializable; | |||||
* | * | ||||
* @author Binary Wang | * @author Binary Wang | ||||
*/ | */ | ||||
@Data | |||||
public class NewArticle implements Serializable { | public class NewArticle implements Serializable { | ||||
private static final long serialVersionUID = 4087852055781140659L; | private static final long serialVersionUID = 4087852055781140659L; | ||||
@@ -17,36 +20,4 @@ public class NewArticle implements Serializable { | |||||
private String url; | private String url; | ||||
private String picUrl; | private String picUrl; | ||||
public String getTitle() { | |||||
return this.title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.description = description; | |||||
} | |||||
public String getUrl() { | |||||
return this.url; | |||||
} | |||||
public void setUrl(String url) { | |||||
this.url = url; | |||||
} | |||||
public String getPicUrl() { | |||||
return this.picUrl; | |||||
} | |||||
public void setPicUrl(String picUrl) { | |||||
this.picUrl = picUrl; | |||||
} | |||||
} | } |
@@ -44,7 +44,7 @@ public class BaseBuilder<T> { | |||||
m.setToUser(this.toUser); | m.setToUser(this.toUser); | ||||
m.setToParty(this.toParty); | m.setToParty(this.toParty); | ||||
m.setToTag(this.toTag); | m.setToTag(this.toTag); | ||||
m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.CUSTOM_MSG_SAFE_NO)); | |||||
m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.KefuMsgSafe.NO)); | |||||
return m; | return m; | ||||
} | } | ||||
@@ -15,7 +15,7 @@ public final class FileBuilder extends BaseBuilder<FileBuilder> { | |||||
private String mediaId; | private String mediaId; | ||||
public FileBuilder() { | public FileBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_FILE; | |||||
this.msgType = WxConsts.KefuMsgType.FILE; | |||||
} | } | ||||
public FileBuilder mediaId(String media_id) { | public FileBuilder mediaId(String media_id) { | ||||
@@ -15,7 +15,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||||
private String mediaId; | private String mediaId; | ||||
public ImageBuilder() { | public ImageBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_IMAGE; | |||||
this.msgType = WxConsts.KefuMsgType.IMAGE; | |||||
} | } | ||||
public ImageBuilder mediaId(String media_id) { | public ImageBuilder mediaId(String media_id) { | ||||
@@ -23,7 +23,7 @@ public final class MpnewsBuilder extends BaseBuilder<MpnewsBuilder> { | |||||
private String mediaId; | private String mediaId; | ||||
public MpnewsBuilder() { | public MpnewsBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_MPNEWS; | |||||
this.msgType = WxConsts.KefuMsgType.MPNEWS; | |||||
} | } | ||||
public MpnewsBuilder mediaId(String mediaId) { | public MpnewsBuilder mediaId(String mediaId) { | ||||
@@ -22,7 +22,7 @@ public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | |||||
private List<NewArticle> articles = new ArrayList<>(); | private List<NewArticle> articles = new ArrayList<>(); | ||||
public NewsBuilder() { | public NewsBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_NEWS; | |||||
this.msgType = WxConsts.KefuMsgType.NEWS; | |||||
} | } | ||||
public NewsBuilder addArticle(NewArticle... articles) { | public NewsBuilder addArticle(NewArticle... articles) { | ||||
@@ -15,7 +15,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder> { | |||||
private String content; | private String content; | ||||
public TextBuilder() { | public TextBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_TEXT; | |||||
this.msgType = WxConsts.KefuMsgType.TEXT; | |||||
} | } | ||||
public TextBuilder content(String content) { | public TextBuilder content(String content) { | ||||
@@ -18,7 +18,7 @@ public class TextCardBuilder extends BaseBuilder<TextCardBuilder> { | |||||
private String url; | private String url; | ||||
public TextCardBuilder() { | public TextCardBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_TEXTCARD; | |||||
this.msgType = WxConsts.KefuMsgType.TEXTCARD; | |||||
} | } | ||||
public TextCardBuilder title(String title) { | public TextCardBuilder title(String title) { | ||||
@@ -24,7 +24,7 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder> { | |||||
private String thumbMediaId; | private String thumbMediaId; | ||||
public VideoBuilder() { | public VideoBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_VIDEO; | |||||
this.msgType = WxConsts.KefuMsgType.VIDEO; | |||||
} | } | ||||
public VideoBuilder mediaId(String mediaId) { | public VideoBuilder mediaId(String mediaId) { | ||||
@@ -15,7 +15,7 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> { | |||||
private String mediaId; | private String mediaId; | ||||
public VoiceBuilder() { | public VoiceBuilder() { | ||||
this.msgType = WxConsts.CUSTOM_MSG_VOICE; | |||||
this.msgType = WxConsts.KefuMsgType.VOICE; | |||||
} | } | ||||
public VoiceBuilder mediaId(String media_id) { | public VoiceBuilder mediaId(String media_id) { | ||||
@@ -9,7 +9,11 @@ import redis.clients.jedis.JedisPoolConfig; | |||||
import java.io.File; | import java.io.File; | ||||
/** | /** | ||||
* Jedis client implementor for wechat config storage | |||||
* Jedis client implementor for wechat config storage. | |||||
* <pre> | |||||
* 使用说明:本实现仅供参考,并不完整, | |||||
* 比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。 | |||||
* </pre> | |||||
* | * | ||||
* @author gaigeshen | * @author gaigeshen | ||||
*/ | */ | ||||
@@ -11,6 +11,7 @@ import me.chanjar.weixin.common.util.LogExceptionHandler; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
@@ -215,17 +216,19 @@ public class WxCpMessageRouter { | |||||
} | } | ||||
protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) { | protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) { | ||||
String messageId = ""; | |||||
String messageId; | |||||
if (wxMessage.getMsgId() == null) { | if (wxMessage.getMsgId() == null) { | ||||
messageId = String.valueOf(wxMessage.getCreateTime()) | messageId = String.valueOf(wxMessage.getCreateTime()) | ||||
+ "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId()) | |||||
+ "-" + StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId())) | |||||
+ "-" + wxMessage.getFromUserName() | + "-" + wxMessage.getFromUserName() | ||||
+ "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey()) | |||||
+ "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent()) | |||||
+ "-" + StringUtils.trimToEmpty(wxMessage.getEventKey()) | |||||
+ "-" + StringUtils.trimToEmpty(wxMessage.getEvent()) | |||||
; | ; | ||||
} else { | } else { | ||||
messageId = String.valueOf(wxMessage.getMsgId()); | |||||
messageId = new StringBuilder().append(wxMessage.getMsgId()) | |||||
.append("-").append(wxMessage.getCreateTime()) | |||||
.append("-").append(wxMessage.getFromUserName()) | |||||
.toString(); | |||||
} | } | ||||
return this.messageDuplicateChecker.isDuplicate(messageId); | return this.messageDuplicateChecker.isDuplicate(messageId); | ||||
@@ -49,7 +49,7 @@ public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDe | |||||
depart.setName(GsonHelper.getAsString(departJson.get("name"))); | depart.setName(GsonHelper.getAsString(departJson.get("name"))); | ||||
} | } | ||||
if (departJson.get("order") != null && !departJson.get("order").isJsonNull()) { | if (departJson.get("order") != null && !departJson.get("order").isJsonNull()) { | ||||
depart.setOrder(GsonHelper.getAsInteger(departJson.get("order"))); | |||||
depart.setOrder(GsonHelper.getAsLong(departJson.get("order"))); | |||||
} | } | ||||
if (departJson.get("parentid") != null && !departJson.get("parentid").isJsonNull()) { | if (departJson.get("parentid") != null && !departJson.get("parentid").isJsonNull()) { | ||||
depart.setParentId(GsonHelper.getAsInteger(departJson.get("parentid"))); | depart.setParentId(GsonHelper.getAsInteger(departJson.get("parentid"))); | ||||
@@ -37,13 +37,13 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
if (StringUtils.isNotBlank(message.getToTag())) { | if (StringUtils.isNotBlank(message.getToTag())) { | ||||
messageJson.addProperty("totag", message.getToTag()); | messageJson.addProperty("totag", message.getToTag()); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_TEXT.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) { | |||||
JsonObject text = new JsonObject(); | JsonObject text = new JsonObject(); | ||||
text.addProperty("content", message.getContent()); | text.addProperty("content", message.getContent()); | ||||
messageJson.add("text", text); | messageJson.add("text", text); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_TEXTCARD.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.TEXTCARD.equals(message.getMsgType())) { | |||||
JsonObject text = new JsonObject(); | JsonObject text = new JsonObject(); | ||||
text.addProperty("title", message.getTitle()); | text.addProperty("title", message.getTitle()); | ||||
text.addProperty("description", message.getDescription()); | text.addProperty("description", message.getDescription()); | ||||
@@ -51,19 +51,19 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
messageJson.add("textcard", text); | messageJson.add("textcard", text); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_IMAGE.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) { | |||||
JsonObject image = new JsonObject(); | JsonObject image = new JsonObject(); | ||||
image.addProperty("media_id", message.getMediaId()); | image.addProperty("media_id", message.getMediaId()); | ||||
messageJson.add("image", image); | messageJson.add("image", image); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_FILE.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.FILE.equals(message.getMsgType())) { | |||||
JsonObject image = new JsonObject(); | JsonObject image = new JsonObject(); | ||||
image.addProperty("media_id", message.getMediaId()); | image.addProperty("media_id", message.getMediaId()); | ||||
messageJson.add("file", image); | messageJson.add("file", image); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_VOICE.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) { | |||||
JsonObject voice = new JsonObject(); | JsonObject voice = new JsonObject(); | ||||
voice.addProperty("media_id", message.getMediaId()); | voice.addProperty("media_id", message.getMediaId()); | ||||
messageJson.add("voice", voice); | messageJson.add("voice", voice); | ||||
@@ -73,7 +73,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
messageJson.addProperty("safe", message.getSafe()); | messageJson.addProperty("safe", message.getSafe()); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_VIDEO.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) { | |||||
JsonObject video = new JsonObject(); | JsonObject video = new JsonObject(); | ||||
video.addProperty("media_id", message.getMediaId()); | video.addProperty("media_id", message.getMediaId()); | ||||
video.addProperty("thumb_media_id", message.getThumbMediaId()); | video.addProperty("thumb_media_id", message.getThumbMediaId()); | ||||
@@ -82,7 +82,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
messageJson.add("video", video); | messageJson.add("video", video); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) { | |||||
JsonObject newsJsonObject = new JsonObject(); | JsonObject newsJsonObject = new JsonObject(); | ||||
JsonArray articleJsonArray = new JsonArray(); | JsonArray articleJsonArray = new JsonArray(); | ||||
for (NewArticle article : message.getArticles()) { | for (NewArticle article : message.getArticles()) { | ||||
@@ -97,7 +97,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
messageJson.add("news", newsJsonObject); | messageJson.add("news", newsJsonObject); | ||||
} | } | ||||
if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) { | |||||
if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) { | |||||
JsonObject newsJsonObject = new JsonObject(); | JsonObject newsJsonObject = new JsonObject(); | ||||
if (message.getMediaId() != null) { | if (message.getMediaId() != null) { | ||||
newsJsonObject.addProperty("media_id", message.getMediaId()); | newsJsonObject.addProperty("media_id", message.getMediaId()); | ||||
@@ -28,7 +28,7 @@ public class XStreamTransformer { | |||||
} | } | ||||
/** | /** | ||||
* 注册扩展消息的解析器 | |||||
* 注册扩展消息的解析器. | |||||
* | * | ||||
* @param clz 类型 | * @param clz 类型 | ||||
* @param xStream xml解析器 | * @param xStream xml解析器 | ||||
@@ -46,17 +46,19 @@ public class XStreamTransformer { | |||||
private static Map<Class, XStream> configXStreamInstance() { | private static Map<Class, XStream> configXStreamInstance() { | ||||
Map<Class, XStream> map = new HashMap<>(); | Map<Class, XStream> map = new HashMap<>(); | ||||
map.put(WxCpXmlMessage.class, config_WxCpXmlMessage()); | |||||
map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage()); | |||||
map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage()); | |||||
map.put(WxCpXmlOutImageMessage.class, config_WxCpXmlOutImageMessage()); | |||||
map.put(WxCpXmlOutVideoMessage.class, config_WxCpXmlOutVideoMessage()); | |||||
map.put(WxCpXmlOutVoiceMessage.class, config_WxCpXmlOutVoiceMessage()); | |||||
map.put(WxCpXmlMessage.class, configWxCpXmlMessage()); | |||||
map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage()); | |||||
map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage()); | |||||
map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage()); | |||||
map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage()); | |||||
map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage()); | |||||
return map; | return map; | ||||
} | } | ||||
private static XStream config_WxCpXmlMessage() { | |||||
private static XStream configWxCpXmlMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlMessage.class); | xstream.processAnnotations(WxCpXmlMessage.class); | ||||
xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | ||||
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class); | xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class); | ||||
@@ -65,38 +67,48 @@ public class XStreamTransformer { | |||||
return xstream; | return xstream; | ||||
} | } | ||||
private static XStream config_WxCpXmlOutImageMessage() { | |||||
private static XStream configWxCpXmlOutImageMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutImageMessage.class); | xstream.processAnnotations(WxCpXmlOutImageMessage.class); | ||||
return xstream; | return xstream; | ||||
} | } | ||||
private static XStream config_WxCpXmlOutNewsMessage() { | |||||
private static XStream configWxCpXmlOutNewsMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class); | xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class); | ||||
return xstream; | return xstream; | ||||
} | } | ||||
private static XStream config_WxCpXmlOutTextMessage() { | |||||
private static XStream configWxCpXmlOutTextMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutTextMessage.class); | xstream.processAnnotations(WxCpXmlOutTextMessage.class); | ||||
return xstream; | return xstream; | ||||
} | } | ||||
private static XStream config_WxCpXmlOutVideoMessage() { | |||||
private static XStream configWxCpXmlOutVideoMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class); | xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class); | ||||
return xstream; | return xstream; | ||||
} | } | ||||
private static XStream config_WxCpXmlOutVoiceMessage() { | |||||
private static XStream configWxCpXmlOutVoiceMessage() { | |||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(WxCpXmlOutMessage.class); | xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | ||||
return xstream; | return xstream; | ||||
@@ -24,9 +24,7 @@ public class WxCpBusyRetryTest { | |||||
RequestExecutor<T, E> executor, String uri, E data) | RequestExecutor<T, E> executor, String uri, E data) | ||||
throws WxErrorException { | throws WxErrorException { | ||||
this.log.info("Executed"); | this.log.info("Executed"); | ||||
WxError error = new WxError(); | |||||
error.setErrorCode(-1); | |||||
throw new WxErrorException(error); | |||||
throw new WxErrorException(WxError.builder().errorCode(-1).build()); | |||||
} | } | ||||
}; | }; | ||||
@@ -3,7 +3,6 @@ package me.chanjar.weixin.cp.api; | |||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | |||||
import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
import org.testng.annotations.*; | import org.testng.annotations.*; | ||||
@@ -32,7 +31,7 @@ public class WxCpMessageAPITest { | |||||
public void testSendMessage() throws WxErrorException { | public void testSendMessage() throws WxErrorException { | ||||
WxCpMessage message = new WxCpMessage(); | WxCpMessage message = new WxCpMessage(); | ||||
// message.setAgentId(configStorage.getAgentId()); | // message.setAgentId(configStorage.getAgentId()); | ||||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||||
message.setMsgType(WxConsts.KefuMsgType.TEXT); | |||||
message.setToUser(configStorage.getUserId()); | message.setToUser(configStorage.getUserId()); | ||||
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | ||||
@@ -27,21 +27,21 @@ public class WxCpMessageRouterTest { | |||||
router | router | ||||
.rule() | .rule() | ||||
.async(async) | .async(async) | ||||
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") | |||||
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1").content("CONTENT_1") | |||||
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_4")) | .handler(new WxEchoCpMessageHandler(sb, "COMBINE_4")) | ||||
.end() | .end() | ||||
.rule() | .rule() | ||||
.async(async) | .async(async) | ||||
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") | |||||
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1") | |||||
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_3")) | .handler(new WxEchoCpMessageHandler(sb, "COMBINE_3")) | ||||
.end() | .end() | ||||
.rule() | .rule() | ||||
.async(async) | .async(async) | ||||
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK) | |||||
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK) | |||||
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_2")) | .handler(new WxEchoCpMessageHandler(sb, "COMBINE_2")) | ||||
.end() | .end() | ||||
.rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end() | |||||
.rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end() | |||||
.rule().async(async).msgType(WxConsts.XmlMsgType.TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XmlMsgType.TEXT)).end() | |||||
.rule().async(async).event(WxConsts.EventType.CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EventType.CLICK)).end() | |||||
.rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end() | .rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end() | ||||
.rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end() | .rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end() | ||||
.rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end() | .rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end() | ||||
@@ -104,10 +104,10 @@ public class WxCpMessageRouterTest { | |||||
@DataProvider(name = "messages-1") | @DataProvider(name = "messages-1") | ||||
public Object[][] messages2() { | public Object[][] messages2() { | ||||
WxCpXmlMessage message1 = new WxCpXmlMessage(); | WxCpXmlMessage message1 = new WxCpXmlMessage(); | ||||
message1.setMsgType(WxConsts.XML_MSG_TEXT); | |||||
message1.setMsgType(WxConsts.XmlMsgType.TEXT); | |||||
WxCpXmlMessage message2 = new WxCpXmlMessage(); | WxCpXmlMessage message2 = new WxCpXmlMessage(); | ||||
message2.setEvent(WxConsts.EVT_CLICK); | |||||
message2.setEvent(WxConsts.EventType.CLICK); | |||||
WxCpXmlMessage message3 = new WxCpXmlMessage(); | WxCpXmlMessage message3 = new WxCpXmlMessage(); | ||||
message3.setEventKey("KEY_1"); | message3.setEventKey("KEY_1"); | ||||
@@ -125,24 +125,24 @@ public class WxCpMessageRouterTest { | |||||
message7.setFormat("strangeformat"); | message7.setFormat("strangeformat"); | ||||
WxCpXmlMessage c2 = new WxCpXmlMessage(); | WxCpXmlMessage c2 = new WxCpXmlMessage(); | ||||
c2.setMsgType(WxConsts.XML_MSG_TEXT); | |||||
c2.setEvent(WxConsts.EVT_CLICK); | |||||
c2.setMsgType(WxConsts.XmlMsgType.TEXT); | |||||
c2.setEvent(WxConsts.EventType.CLICK); | |||||
WxCpXmlMessage c3 = new WxCpXmlMessage(); | WxCpXmlMessage c3 = new WxCpXmlMessage(); | ||||
c3.setMsgType(WxConsts.XML_MSG_TEXT); | |||||
c3.setEvent(WxConsts.EVT_CLICK); | |||||
c3.setMsgType(WxConsts.XmlMsgType.TEXT); | |||||
c3.setEvent(WxConsts.EventType.CLICK); | |||||
c3.setEventKey("KEY_1"); | c3.setEventKey("KEY_1"); | ||||
WxCpXmlMessage c4 = new WxCpXmlMessage(); | WxCpXmlMessage c4 = new WxCpXmlMessage(); | ||||
c4.setMsgType(WxConsts.XML_MSG_TEXT); | |||||
c4.setEvent(WxConsts.EVT_CLICK); | |||||
c4.setMsgType(WxConsts.XmlMsgType.TEXT); | |||||
c4.setEvent(WxConsts.EventType.CLICK); | |||||
c4.setEventKey("KEY_1"); | c4.setEventKey("KEY_1"); | ||||
c4.setContent("CONTENT_1"); | c4.setContent("CONTENT_1"); | ||||
return new Object[][]{ | return new Object[][]{ | ||||
new Object[]{message1, WxConsts.XML_MSG_TEXT + ","}, | |||||
new Object[]{message2, WxConsts.EVT_CLICK + ","}, | |||||
new Object[]{message1, WxConsts.XmlMsgType.TEXT + ","}, | |||||
new Object[]{message2, WxConsts.EventType.CLICK + ","}, | |||||
new Object[]{message3, "KEY_1,"}, | new Object[]{message3, "KEY_1,"}, | ||||
new Object[]{message4, "CONTENT_1,"}, | new Object[]{message4, "CONTENT_1,"}, | ||||
new Object[]{message5, "ALL,"}, | new Object[]{message5, "ALL,"}, | ||||
@@ -1,12 +1,10 @@ | |||||
package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.ApiTestModule; | import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
import me.chanjar.weixin.cp.bean.WxCpDepart; | import me.chanjar.weixin.cp.bean.WxCpDepart; | ||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import org.testng.annotations.*; | |||||
import java.util.List; | import java.util.List; | ||||
@@ -31,7 +29,7 @@ public class WxCpDepartmentServiceImplTest { | |||||
WxCpDepart cpDepart = new WxCpDepart(); | WxCpDepart cpDepart = new WxCpDepart(); | ||||
cpDepart.setName("子部门" + System.currentTimeMillis()); | cpDepart.setName("子部门" + System.currentTimeMillis()); | ||||
cpDepart.setParentId(1); | cpDepart.setParentId(1); | ||||
cpDepart.setOrder(1); | |||||
cpDepart.setOrder(1L); | |||||
Integer departId = this.wxCpService.getDepartmentService().create(cpDepart); | Integer departId = this.wxCpService.getDepartmentService().create(cpDepart); | ||||
System.out.println(departId); | System.out.println(departId); | ||||
} | } | ||||
@@ -34,11 +34,11 @@ public class WxCpMediaServiceImplTest { | |||||
@DataProvider | @DataProvider | ||||
public Object[][] mediaData() { | public Object[][] mediaData() { | ||||
return new Object[][]{ | return new Object[][]{ | ||||
new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, | |||||
new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"}, | |||||
new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_AMR, "mm.amr"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"} | |||||
new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, | |||||
new Object[]{WxConsts.MEDIA_FILE, TestConstants.FILE_JPG, "mm.jpeg"} | |||||
new Object[]{WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, | |||||
new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_MP3, "mm.mp3"}, | |||||
new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_AMR, "mm.amr"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"} | |||||
new Object[]{WxConsts.MediaFileType.VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, | |||||
new Object[]{WxConsts.MediaFileType.FILE, TestConstants.FILE_JPG, "mm.jpeg"} | |||||
}; | }; | ||||
} | } | ||||
@@ -26,12 +26,12 @@ public class WxCpMenuServiceImplTest { | |||||
public Object[][] menuData() { | public Object[][] menuData() { | ||||
WxMenu menu = new WxMenu(); | WxMenu menu = new WxMenu(); | ||||
WxMenuButton button1 = new WxMenuButton(); | WxMenuButton button1 = new WxMenuButton(); | ||||
button1.setType(WxConsts.BUTTON_CLICK); | |||||
button1.setType(WxConsts.MenuButtonType.CLICK); | |||||
button1.setName("今日歌曲"); | button1.setName("今日歌曲"); | ||||
button1.setKey("V1001_TODAY_MUSIC"); | button1.setKey("V1001_TODAY_MUSIC"); | ||||
WxMenuButton button2 = new WxMenuButton(); | WxMenuButton button2 = new WxMenuButton(); | ||||
button2.setType(WxConsts.BUTTON_CLICK); | |||||
button2.setType(WxConsts.MenuButtonType.CLICK); | |||||
button2.setName("歌手简介"); | button2.setName("歌手简介"); | ||||
button2.setKey("V1001_TODAY_SINGER"); | button2.setKey("V1001_TODAY_SINGER"); | ||||
@@ -43,17 +43,17 @@ public class WxCpMenuServiceImplTest { | |||||
menu.getButtons().add(button3); | menu.getButtons().add(button3); | ||||
WxMenuButton button31 = new WxMenuButton(); | WxMenuButton button31 = new WxMenuButton(); | ||||
button31.setType(WxConsts.BUTTON_VIEW); | |||||
button31.setType(WxConsts.MenuButtonType.VIEW); | |||||
button31.setName("搜索"); | button31.setName("搜索"); | ||||
button31.setUrl("http://www.soso.com/"); | button31.setUrl("http://www.soso.com/"); | ||||
WxMenuButton button32 = new WxMenuButton(); | WxMenuButton button32 = new WxMenuButton(); | ||||
button32.setType(WxConsts.BUTTON_VIEW); | |||||
button32.setType(WxConsts.MenuButtonType.VIEW); | |||||
button32.setName("视频"); | button32.setName("视频"); | ||||
button32.setUrl("http://v.qq.com/"); | button32.setUrl("http://v.qq.com/"); | ||||
WxMenuButton button33 = new WxMenuButton(); | WxMenuButton button33 = new WxMenuButton(); | ||||
button33.setType(WxConsts.BUTTON_CLICK); | |||||
button33.setType(WxConsts.MenuButtonType.CLICK); | |||||
button33.setName("赞一下我们"); | button33.setName("赞一下我们"); | ||||
button33.setKey("V1001_GOOD"); | button33.setKey("V1001_GOOD"); | ||||
@@ -58,7 +58,7 @@ public class WxCpXmlMessageTest { | |||||
assertEquals(wxMessage.getToUserName(), "toUser"); | assertEquals(wxMessage.getToUserName(), "toUser"); | ||||
assertEquals(wxMessage.getFromUserName(), "fromUser"); | assertEquals(wxMessage.getFromUserName(), "fromUser"); | ||||
assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); | assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); | ||||
assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); | |||||
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); | |||||
assertEquals(wxMessage.getContent(), "this is a test"); | assertEquals(wxMessage.getContent(), "this is a test"); | ||||
assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); | assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); | ||||
assertEquals(wxMessage.getPicUrl(), "this is a url"); | assertEquals(wxMessage.getPicUrl(), "this is a url"); | ||||
@@ -86,7 +86,7 @@ public class WxCpXmlMessageTest { | |||||
assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); | ||||
assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); | assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); | ||||
assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); | assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); | ||||
assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi"); | |||||
assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); | |||||
} | } | ||||
public void testSendPicsInfo() { | public void testSendPicsInfo() { | ||||
@@ -108,7 +108,7 @@ public class WxCpXmlMessageTest { | |||||
assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); | assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); | ||||
assertEquals(wxMessage.getFromUserName(), "xiaohe"); | assertEquals(wxMessage.getFromUserName(), "xiaohe"); | ||||
assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); | assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); | ||||
assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_EVENT); | |||||
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); | |||||
assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); | assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); | ||||
assertEquals(wxMessage.getEvent(), "pic_weixin"); | assertEquals(wxMessage.getEvent(), "pic_weixin"); | ||||
assertEquals(wxMessage.getEventKey(), "faceSimilarity"); | assertEquals(wxMessage.getEventKey(), "faceSimilarity"); | ||||
@@ -7,7 +7,7 @@ | |||||
<parent> | <parent> | ||||
<groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
<artifactId>weixin-java-parent</artifactId> | <artifactId>weixin-java-parent</artifactId> | ||||
<version>2.8.0</version> | |||||
<version>2.9.0</version> | |||||
</parent> | </parent> | ||||
<artifactId>weixin-java-miniapp</artifactId> | <artifactId>weixin-java-miniapp</artifactId> | ||||
<name>WeiXin Java Tools - MiniApp</name> | <name>WeiXin Java Tools - MiniApp</name> | ||||
@@ -1,5 +1,6 @@ | |||||
package cn.binarywang.wx.miniapp.api; | package cn.binarywang.wx.miniapp.api; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import java.io.File; | import java.io.File; | ||||
@@ -16,6 +17,9 @@ import java.io.File; | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public interface WxMaQrcodeService { | public interface WxMaQrcodeService { | ||||
String CREATE_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode"; | |||||
String GET_WXACODE_URL = "https://api.weixin.qq.com/wxa/getwxacode"; | |||||
String GET_WXACODE_UNLIMIT_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit"; | |||||
/** | /** | ||||
* 接口C | * 接口C | ||||
@@ -42,10 +46,8 @@ public interface WxMaQrcodeService { | |||||
* @param width 默认430 二维码的宽度 | * @param width 默认430 二维码的宽度 | ||||
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | * @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | ||||
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | * @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | ||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | */ | ||||
File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException; | |||||
File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException; | |||||
File createWxCode(String path, int width) throws WxErrorException; | File createWxCode(String path, int width) throws WxErrorException; | ||||
@@ -65,49 +67,9 @@ public interface WxMaQrcodeService { | |||||
* @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | * @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | ||||
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | * @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 | ||||
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | * @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} | ||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | */ | ||||
File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException; | |||||
File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException; | |||||
File createWxCodeLimit(String scene, String page) throws WxErrorException; | File createWxCodeLimit(String scene, String page) throws WxErrorException; | ||||
/** | |||||
* lineColor 包装类 | |||||
* 用于描述二维码(小程序码)颜色(RGB参数值),详情请查看文档 | |||||
*/ | |||||
public static class LineColor { | |||||
private String r = "0", g = "0", b = "0"; | |||||
public LineColor(String r, String g, String b) { | |||||
this.r = r; | |||||
this.g = g; | |||||
this.b = b; | |||||
} | |||||
public String getR() { | |||||
return r; | |||||
} | |||||
public void setR(String r) { | |||||
this.r = r; | |||||
} | |||||
public String getG() { | |||||
return g; | |||||
} | |||||
public void setG(String g) { | |||||
this.g = g; | |||||
} | |||||
public String getB() { | |||||
return b; | |||||
} | |||||
public void setB(String b) { | |||||
this.b = b; | |||||
} | |||||
} | |||||
} | } |
@@ -6,11 +6,9 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
@@ -22,8 +20,6 @@ import java.util.UUID; | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class WxMaMediaServiceImpl implements WxMaMediaService { | public class WxMaMediaServiceImpl implements WxMaMediaService { | ||||
private final Logger log = LoggerFactory.getLogger(this.getClass()); | |||||
private WxMaService wxMaService; | private WxMaService wxMaService; | ||||
public WxMaMediaServiceImpl(WxMaService wxMaService) { | public WxMaMediaServiceImpl(WxMaService wxMaService) { | ||||
@@ -35,8 +31,7 @@ public class WxMaMediaServiceImpl implements WxMaMediaService { | |||||
try { | try { | ||||
return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
e.printStackTrace(); | |||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); | |||||
} | } | ||||
} | } | ||||
@@ -49,12 +44,11 @@ public class WxMaMediaServiceImpl implements WxMaMediaService { | |||||
@Override | @Override | ||||
public File getMedia(String mediaId) throws WxErrorException { | public File getMedia(String mediaId) throws WxErrorException { | ||||
try { | try { | ||||
RequestExecutor<File, String> executor = MediaDownloadRequestExecutor | |||||
RequestExecutor<File, String> executor = BaseMediaDownloadRequestExecutor | |||||
.create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); | .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); | ||||
return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); | return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
this.log.error(e.getMessage(), e); | |||||
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); | |||||
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); | |||||
} | } | ||||
} | } | ||||
@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaMsgService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | ||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
@@ -30,7 +31,7 @@ public class WxMaMsgServiceImpl implements WxMaMsgService { | |||||
public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | ||||
String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | ||||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | ||||
if (jsonObject.get("errcode").getAsInt() != 0) { | |||||
if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||||
throw new WxErrorException(WxError.fromJson(responseContent)); | throw new WxErrorException(WxError.fromJson(responseContent)); | ||||
} | } | ||||
} | } | ||||
@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | ||||
import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaQrcode; | import cn.binarywang.wx.miniapp.bean.WxMaQrcode; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaWxcode; | import cn.binarywang.wx.miniapp.bean.WxMaWxcode; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaWxcodeLimit; | import cn.binarywang.wx.miniapp.bean.WxMaWxcodeLimit; | ||||
@@ -22,9 +23,8 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||||
@Override | @Override | ||||
public File createQrcode(String path, int width) throws WxErrorException { | public File createQrcode(String path, int width) throws WxErrorException { | ||||
String url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode"; | |||||
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | ||||
url, new WxMaQrcode(path, width)); | |||||
CREATE_QRCODE_URL, new WxMaQrcode(path, width)); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -33,15 +33,14 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException { | |||||
String url = "https://api.weixin.qq.com/wxa/getwxacode"; | |||||
public File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException { | |||||
WxMaWxcode wxMaWxcode = new WxMaWxcode(); | WxMaWxcode wxMaWxcode = new WxMaWxcode(); | ||||
wxMaWxcode.setPath(path); | wxMaWxcode.setPath(path); | ||||
wxMaWxcode.setWidth(width); | wxMaWxcode.setWidth(width); | ||||
wxMaWxcode.setAutoColor(autoColor); | wxMaWxcode.setAutoColor(autoColor); | ||||
wxMaWxcode.setLineColor(lineColor); | wxMaWxcode.setLineColor(lineColor); | ||||
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | ||||
url, wxMaWxcode); | |||||
GET_WXACODE_URL, wxMaWxcode); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -55,8 +54,7 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||||
} | } | ||||
@Override | @Override | ||||
public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException { | |||||
String url = "http://api.weixin.qq.com/wxa/getwxacodeunlimit"; | |||||
public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException { | |||||
WxMaWxcodeLimit wxMaWxcodeLimit = new WxMaWxcodeLimit(); | WxMaWxcodeLimit wxMaWxcodeLimit = new WxMaWxcodeLimit(); | ||||
wxMaWxcodeLimit.setScene(scene); | wxMaWxcodeLimit.setScene(scene); | ||||
wxMaWxcodeLimit.setPage(page); | wxMaWxcodeLimit.setPage(page); | ||||
@@ -64,7 +62,7 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||||
wxMaWxcodeLimit.setAutoColor(autoColor); | wxMaWxcodeLimit.setAutoColor(autoColor); | ||||
wxMaWxcodeLimit.setLineColor(lineColor); | wxMaWxcodeLimit.setLineColor(lineColor); | ||||
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), | ||||
url, wxMaWxcodeLimit); | |||||
GET_WXACODE_UNLIMIT_URL, wxMaWxcodeLimit); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api.impl; | |||||
import cn.binarywang.wx.miniapp.api.*; | import cn.binarywang.wx.miniapp.api.*; | ||||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||||
import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
@@ -147,6 +148,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
/** | /** | ||||
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
*/ | */ | ||||
@Override | |||||
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | ||||
int retryTimes = 0; | int retryTimes = 0; | ||||
do { | do { | ||||
@@ -179,7 +181,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
throw new RuntimeException("微信服务端异常,超出重试次数"); | throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||
} | } | ||||
public synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { | |||||
if (uri.contains("access_token=")) { | if (uri.contains("access_token=")) { | ||||
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); | ||||
} | } | ||||
@@ -195,11 +197,10 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
WxError error = e.getError(); | WxError error = e.getError(); | ||||
/* | /* | ||||
* 发生以下情况时尝试刷新access_token | * 发生以下情况时尝试刷新access_token | ||||
* 40001 获取access_token时AppSecret错误,或者access_token无效 | |||||
* 42001 access_token超时 | |||||
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期) | |||||
*/ | */ | ||||
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | |||||
if (error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40001 | |||||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_42001 | |||||
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40014) { | |||||
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
this.getWxMaConfig().expireAccessToken(); | this.getWxMaConfig().expireAccessToken(); | ||||
if (this.getWxMaConfig().autoRefreshToken()) { | if (this.getWxMaConfig().autoRefreshToken()) { | ||||
@@ -19,14 +19,14 @@ import java.util.Map; | |||||
public class WxMaUserServiceImpl implements WxMaUserService { | public class WxMaUserServiceImpl implements WxMaUserService { | ||||
private WxMaService service; | private WxMaService service; | ||||
WxMaUserServiceImpl(WxMaService service) { | |||||
public WxMaUserServiceImpl(WxMaService service) { | |||||
this.service = service; | this.service = service; | ||||
} | } | ||||
@Override | @Override | ||||
public WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException { | public WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException { | ||||
final WxMaConfig config = service.getWxMaConfig(); | final WxMaConfig config = service.getWxMaConfig(); | ||||
Map<String, String> params = new HashMap<>(); | |||||
Map<String, String> params = new HashMap<>(8); | |||||
params.put("appid", config.getAppid()); | params.put("appid", config.getAppid()); | ||||
params.put("secret", config.getSecret()); | params.put("secret", config.getSecret()); | ||||
params.put("js_code", jsCode); | params.put("js_code", jsCode); | ||||
@@ -3,10 +3,11 @@ package cn.binarywang.wx.miniapp.bean; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
/** | /** | ||||
* 微信二维码(小程序码)包装器 | |||||
* Created by Element on 2017/7/27. | |||||
* 微信二维码(小程序码)包装器. | |||||
* | |||||
* @author Element | |||||
*/ | */ | ||||
public abstract class WxMaQrcodeWrapper { | |||||
public abstract class AbstractWxMaQrcodeWrapper { | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { |
@@ -0,0 +1,18 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
/** | |||||
* <pre> | |||||
* lineColor 包装类 | |||||
* 用于描述二维码(小程序码)颜色(RGB参数值), | |||||
* 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html | |||||
* </pre> | |||||
* @author Element | |||||
*/ | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class WxMaCodeLineColor { | |||||
private String r = "0", g = "0", b = "0"; | |||||
} |
@@ -2,13 +2,21 @@ package cn.binarywang.wx.miniapp.bean; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import java.io.Serializable; | |||||
/** | /** | ||||
* {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} | * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} | ||||
* | * | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class WxMaJscode2SessionResult { | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = false) | |||||
public class WxMaJscode2SessionResult implements Serializable { | |||||
private static final long serialVersionUID = -1060216618475607933L; | |||||
@SerializedName("session_key") | @SerializedName("session_key") | ||||
private String sessionKey; | private String sessionKey; | ||||
@@ -25,36 +33,4 @@ public class WxMaJscode2SessionResult { | |||||
return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); | return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); | ||||
} | } | ||||
public String getSessionKey() { | |||||
return sessionKey; | |||||
} | |||||
public void setSessionKey(String sessionKey) { | |||||
this.sessionKey = sessionKey; | |||||
} | |||||
public Integer getExpiresin() { | |||||
return expiresin; | |||||
} | |||||
public void setExpiresin(Integer expiresin) { | |||||
this.expiresin = expiresin; | |||||
} | |||||
public String getOpenid() { | |||||
return openid; | |||||
} | |||||
public void setOpenid(String openid) { | |||||
this.openid = openid; | |||||
} | |||||
public String getUnionid() { | |||||
return unionid; | |||||
} | |||||
public void setUnionid(String unionid) { | |||||
this.unionid = unionid; | |||||
} | |||||
} | } |
@@ -3,6 +3,7 @@ package cn.binarywang.wx.miniapp.bean; | |||||
import cn.binarywang.wx.miniapp.builder.ImageBuilder; | import cn.binarywang.wx.miniapp.builder.ImageBuilder; | ||||
import cn.binarywang.wx.miniapp.builder.TextBuilder; | import cn.binarywang.wx.miniapp.builder.TextBuilder; | ||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
@@ -11,6 +12,7 @@ import java.io.Serializable; | |||||
* | * | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
@Data | |||||
public class WxMaKefuMessage implements Serializable { | public class WxMaKefuMessage implements Serializable { | ||||
private static final long serialVersionUID = -9196732086954365246L; | private static final long serialVersionUID = -9196732086954365246L; | ||||
@@ -25,73 +27,17 @@ public class WxMaKefuMessage implements Serializable { | |||||
/** | /** | ||||
* 获得文本消息builder | * 获得文本消息builder | ||||
*/ | */ | ||||
public static TextBuilder TEXT() { | |||||
public static TextBuilder newTextBuilder() { | |||||
return new TextBuilder(); | return new TextBuilder(); | ||||
} | } | ||||
/** | /** | ||||
* 获得图片消息builder | * 获得图片消息builder | ||||
*/ | */ | ||||
public static ImageBuilder IMAGE() { | |||||
public static ImageBuilder newImageBuilder() { | |||||
return new ImageBuilder(); | return new ImageBuilder(); | ||||
} | } | ||||
public String getToUser() { | |||||
return this.toUser; | |||||
} | |||||
public void setToUser(String toUser) { | |||||
this.toUser = toUser; | |||||
} | |||||
public String getMsgType() { | |||||
return this.msgType; | |||||
} | |||||
public void setMsgType(String msgType) { | |||||
this.msgType = msgType; | |||||
} | |||||
public String getContent() { | |||||
return this.content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public String getMediaId() { | |||||
return this.mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getThumbMediaId() { | |||||
return this.thumbMediaId; | |||||
} | |||||
public void setThumbMediaId(String thumbMediaId) { | |||||
this.thumbMediaId = thumbMediaId; | |||||
} | |||||
public String getTitle() { | |||||
return this.title; | |||||
} | |||||
public void setTitle(String title) { | |||||
this.title = title; | |||||
} | |||||
public String getDescription() { | |||||
return this.description; | |||||
} | |||||
public void setDescription(String description) { | |||||
this.description = description; | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxMaGsonBuilder.create().toJson(this); | return WxMaGsonBuilder.create().toJson(this); | ||||
} | } | ||||
@@ -7,6 +7,7 @@ import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer; | |||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
import lombok.Data; | |||||
import me.chanjar.weixin.common.util.ToStringUtils; | import me.chanjar.weixin.common.util.ToStringUtils; | ||||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
import org.apache.commons.io.IOUtils; | import org.apache.commons.io.IOUtils; | ||||
@@ -20,6 +21,7 @@ import java.nio.charset.StandardCharsets; | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
@XStreamAlias("xml") | @XStreamAlias("xml") | ||||
@Data | |||||
public class WxMaMessage implements Serializable { | public class WxMaMessage implements Serializable { | ||||
private static final long serialVersionUID = -3586245291677274914L; | private static final long serialVersionUID = -3586245291677274914L; | ||||
@@ -146,91 +148,4 @@ public class WxMaMessage implements Serializable { | |||||
return WxMaGsonBuilder.create().toJson(this); | return WxMaGsonBuilder.create().toJson(this); | ||||
} | } | ||||
public String getToUser() { | |||||
return toUser; | |||||
} | |||||
public void setToUser(String toUser) { | |||||
this.toUser = toUser; | |||||
} | |||||
public String getFromUser() { | |||||
return fromUser; | |||||
} | |||||
public void setFromUser(String fromUser) { | |||||
this.fromUser = fromUser; | |||||
} | |||||
public Integer getCreateTime() { | |||||
return createTime; | |||||
} | |||||
public void setCreateTime(Integer createTime) { | |||||
this.createTime = createTime; | |||||
} | |||||
public String getMsgType() { | |||||
return msgType; | |||||
} | |||||
public void setMsgType(String msgType) { | |||||
this.msgType = msgType; | |||||
} | |||||
public String getContent() { | |||||
return content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public Long getMsgId() { | |||||
return msgId; | |||||
} | |||||
public void setMsgId(Long msgId) { | |||||
this.msgId = msgId; | |||||
} | |||||
public String getPicUrl() { | |||||
return picUrl; | |||||
} | |||||
public void setPicUrl(String picUrl) { | |||||
this.picUrl = picUrl; | |||||
} | |||||
public String getMediaId() { | |||||
return mediaId; | |||||
} | |||||
public void setMediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
} | |||||
public String getEvent() { | |||||
return event; | |||||
} | |||||
public void setEvent(String event) { | |||||
this.event = event; | |||||
} | |||||
public String getSessionFrom() { | |||||
return sessionFrom; | |||||
} | |||||
public void setSessionFrom(String sessionFrom) { | |||||
this.sessionFrom = sessionFrom; | |||||
} | |||||
public String getEncrypt() { | |||||
return encrypt; | |||||
} | |||||
public void setEncrypt(String encrypt) { | |||||
this.encrypt = encrypt; | |||||
} | |||||
} | } |
@@ -1,13 +1,17 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class WxMaQrcode extends WxMaQrcodeWrapper implements Serializable { | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = false) | |||||
public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { | |||||
private static final long serialVersionUID = 5777119669111011584L; | private static final long serialVersionUID = 5777119669111011584L; | ||||
private String path; | private String path; | ||||
private int width = 430; | private int width = 430; | ||||
@@ -21,22 +25,6 @@ public class WxMaQrcode extends WxMaQrcodeWrapper implements Serializable { | |||||
return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); | return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); | ||||
} | } | ||||
public String getPath() { | |||||
return path; | |||||
} | |||||
public void setPath(String path) { | |||||
this.path = path; | |||||
} | |||||
public int getWidth() { | |||||
return width; | |||||
} | |||||
public void setWidth(int width) { | |||||
this.width = width; | |||||
} | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
return WxMaGsonBuilder.create().toJson(this); | return WxMaGsonBuilder.create().toJson(this); | ||||
@@ -1,6 +1,8 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
@@ -11,6 +13,8 @@ import java.util.List; | |||||
* | * | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
@Data | |||||
@Builder | |||||
public class WxMaTemplateMessage implements Serializable { | public class WxMaTemplateMessage implements Serializable { | ||||
private static final long serialVersionUID = 5063374783759519418L; | private static final long serialVersionUID = 5063374783759519418L; | ||||
@@ -57,7 +61,8 @@ public class WxMaTemplateMessage implements Serializable { | |||||
* 描述: 模板内容,不填则下发空模板 | * 描述: 模板内容,不填则下发空模板 | ||||
* </pre> | * </pre> | ||||
*/ | */ | ||||
private List<Data> data = new ArrayList<>(); | |||||
@Builder.Default | |||||
private final List<Data> data = new ArrayList<>(); | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -77,80 +82,11 @@ public class WxMaTemplateMessage implements Serializable { | |||||
*/ | */ | ||||
private String emphasisKeyword; | private String emphasisKeyword; | ||||
private WxMaTemplateMessage(Builder builder) { | |||||
setToUser(builder.toUser); | |||||
setTemplateId(builder.templateId); | |||||
setPage(builder.page); | |||||
setFormId(builder.formId); | |||||
setData(builder.data); | |||||
setColor(builder.color); | |||||
setEmphasisKeyword(builder.emphasisKeyword); | |||||
} | |||||
public static Builder newBuilder() { | |||||
return new Builder(); | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxMaGsonBuilder.create().toJson(this); | return WxMaGsonBuilder.create().toJson(this); | ||||
} | } | ||||
public String getToUser() { | |||||
return toUser; | |||||
} | |||||
public void setToUser(String toUser) { | |||||
this.toUser = toUser; | |||||
} | |||||
public String getTemplateId() { | |||||
return templateId; | |||||
} | |||||
public void setTemplateId(String templateId) { | |||||
this.templateId = templateId; | |||||
} | |||||
public String getPage() { | |||||
return page; | |||||
} | |||||
public void setPage(String page) { | |||||
this.page = page; | |||||
} | |||||
public String getFormId() { | |||||
return formId; | |||||
} | |||||
public void setFormId(String formId) { | |||||
this.formId = formId; | |||||
} | |||||
public List<Data> getData() { | |||||
return data; | |||||
} | |||||
public void setData(List<Data> data) { | |||||
this.data = data; | |||||
} | |||||
public String getColor() { | |||||
return color; | |||||
} | |||||
public void setColor(String color) { | |||||
this.color = color; | |||||
} | |||||
public String getEmphasisKeyword() { | |||||
return emphasisKeyword; | |||||
} | |||||
public void setEmphasisKeyword(String emphasisKeyword) { | |||||
this.emphasisKeyword = emphasisKeyword; | |||||
} | |||||
@lombok.Data | |||||
public static class Data { | public static class Data { | ||||
private String name; | private String name; | ||||
private String value; | private String value; | ||||
@@ -167,81 +103,6 @@ public class WxMaTemplateMessage implements Serializable { | |||||
this.color = color; | this.color = color; | ||||
} | } | ||||
public String getName() { | |||||
return this.name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getValue() { | |||||
return this.value; | |||||
} | |||||
public void setValue(String value) { | |||||
this.value = value; | |||||
} | |||||
public String getColor() { | |||||
return this.color; | |||||
} | |||||
public void setColor(String color) { | |||||
this.color = color; | |||||
} | |||||
} | } | ||||
public static final class Builder { | |||||
private String toUser; | |||||
private String templateId; | |||||
private String page; | |||||
private String formId; | |||||
private List<Data> data; | |||||
private String color; | |||||
private String emphasisKeyword; | |||||
private Builder() { | |||||
} | |||||
public Builder toUser(String toUser) { | |||||
this.toUser = toUser; | |||||
return this; | |||||
} | |||||
public Builder templateId(String templateId) { | |||||
this.templateId = templateId; | |||||
return this; | |||||
} | |||||
public Builder page(String page) { | |||||
this.page = page; | |||||
return this; | |||||
} | |||||
public Builder formId(String formId) { | |||||
this.formId = formId; | |||||
return this; | |||||
} | |||||
public Builder data(List<Data> data) { | |||||
this.data = data; | |||||
return this; | |||||
} | |||||
public Builder color(String color) { | |||||
this.color = color; | |||||
return this; | |||||
} | |||||
public Builder emphasisKeyword(String emphasisKeyword) { | |||||
this.emphasisKeyword = emphasisKeyword; | |||||
return this; | |||||
} | |||||
public WxMaTemplateMessage build() { | |||||
return new WxMaTemplateMessage(this); | |||||
} | |||||
} | |||||
} | } |
@@ -1,13 +1,17 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||||
import org.apache.commons.lang3.builder.ToStringStyle; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class WxMaUserInfo { | |||||
@Data | |||||
public class WxMaUserInfo implements Serializable { | |||||
private static final long serialVersionUID = 6719822331555402137L; | |||||
private String openId; | private String openId; | ||||
private String nickName; | private String nickName; | ||||
private String gender; | private String gender; | ||||
@@ -23,109 +27,9 @@ public class WxMaUserInfo { | |||||
return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); | return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class); | ||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); | |||||
} | |||||
public String getOpenId() { | |||||
return openId; | |||||
} | |||||
public void setOpenId(String openId) { | |||||
this.openId = openId; | |||||
} | |||||
public String getNickName() { | |||||
return nickName; | |||||
} | |||||
public void setNickName(String nickName) { | |||||
this.nickName = nickName; | |||||
} | |||||
public String getGender() { | |||||
return gender; | |||||
} | |||||
public void setGender(String gender) { | |||||
this.gender = gender; | |||||
} | |||||
public String getLanguage() { | |||||
return language; | |||||
} | |||||
public void setLanguage(String language) { | |||||
this.language = language; | |||||
} | |||||
public String getCity() { | |||||
return city; | |||||
} | |||||
public void setCity(String city) { | |||||
this.city = city; | |||||
} | |||||
public String getProvince() { | |||||
return province; | |||||
} | |||||
public void setProvince(String province) { | |||||
this.province = province; | |||||
} | |||||
public String getCountry() { | |||||
return country; | |||||
} | |||||
public void setCountry(String country) { | |||||
this.country = country; | |||||
} | |||||
public String getAvatarUrl() { | |||||
return avatarUrl; | |||||
} | |||||
public void setAvatarUrl(String avatarUrl) { | |||||
this.avatarUrl = avatarUrl; | |||||
} | |||||
public String getUnionId() { | |||||
return unionId; | |||||
} | |||||
public void setUnionId(String unionId) { | |||||
this.unionId = unionId; | |||||
} | |||||
public Watermark getWatermark() { | |||||
return watermark; | |||||
} | |||||
public void setWatermark(Watermark watermark) { | |||||
this.watermark = watermark; | |||||
} | |||||
@Data | |||||
public static class Watermark { | public static class Watermark { | ||||
private String timestamp; | private String timestamp; | ||||
private String appid; | private String appid; | ||||
public String getTimestamp() { | |||||
return timestamp; | |||||
} | |||||
public void setTimestamp(String timestamp) { | |||||
this.timestamp = timestamp; | |||||
} | |||||
public String getAppid() { | |||||
return appid; | |||||
} | |||||
public void setAppid(String appid) { | |||||
this.appid = appid; | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,17 +1,22 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* Created by Element on 2017/7/27. | |||||
* | |||||
* @author Element | |||||
* @date 2017/7/27 | |||||
*/ | */ | ||||
public class WxMaWxcode extends WxMaQrcodeWrapper implements Serializable { | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = false) | |||||
public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable { | |||||
private static final long serialVersionUID = 1287399621649210322L; | private static final long serialVersionUID = 1287399621649210322L; | ||||
private String path; | private String path; | ||||
private int width = 430; | private int width = 430; | ||||
@@ -19,46 +24,10 @@ public class WxMaWxcode extends WxMaQrcodeWrapper implements Serializable { | |||||
private boolean autoColor = true; | private boolean autoColor = true; | ||||
@SerializedName("line_color") | @SerializedName("line_color") | ||||
private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0"); | |||||
private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); | |||||
public static WxMaWxcode fromJson(String json) { | public static WxMaWxcode fromJson(String json) { | ||||
return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); | return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class); | ||||
} | } | ||||
public static long getSerialVersionUID() { | |||||
return serialVersionUID; | |||||
} | |||||
public String getPath() { | |||||
return path; | |||||
} | |||||
public void setPath(String path) { | |||||
this.path = path; | |||||
} | |||||
public int getWidth() { | |||||
return width; | |||||
} | |||||
public void setWidth(int width) { | |||||
this.width = width; | |||||
} | |||||
public boolean isAutoColor() { | |||||
return autoColor; | |||||
} | |||||
public void setAutoColor(boolean autoColor) { | |||||
this.autoColor = autoColor; | |||||
} | |||||
public WxMaQrcodeService.LineColor getLineColor() { | |||||
return lineColor; | |||||
} | |||||
public void setLineColor(WxMaQrcodeService.LineColor lineColor) { | |||||
this.lineColor = lineColor; | |||||
} | |||||
} | } |
@@ -1,15 +1,20 @@ | |||||
package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | |||||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/** | /** | ||||
* Created by Element on 2017/7/27. | |||||
* | |||||
* @author Element | |||||
* @date 2017/7/27 | |||||
*/ | */ | ||||
public class WxMaWxcodeLimit extends WxMaQrcodeWrapper implements Serializable { | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = false) | |||||
public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable { | |||||
private static final long serialVersionUID = 4782193774524960401L; | private static final long serialVersionUID = 4782193774524960401L; | ||||
private String scene; | private String scene; | ||||
private String page; | private String page; | ||||
@@ -20,49 +25,10 @@ public class WxMaWxcodeLimit extends WxMaQrcodeWrapper implements Serializable { | |||||
private boolean autoColor = true; | private boolean autoColor = true; | ||||
@SerializedName("line_color") | @SerializedName("line_color") | ||||
private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0"); | |||||
private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0"); | |||||
public static WxMaWxcodeLimit fromJson(String json) { | public static WxMaWxcodeLimit fromJson(String json) { | ||||
return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); | return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); | ||||
} | } | ||||
public String getPage() { | |||||
return page; | |||||
} | |||||
public void setPage(String page) { | |||||
this.page = page; | |||||
} | |||||
public String getScene() { | |||||
return scene; | |||||
} | |||||
public void setScene(String scene) { | |||||
this.scene = scene; | |||||
} | |||||
public int getWidth() { | |||||
return width; | |||||
} | |||||
public void setWidth(int width) { | |||||
this.width = width; | |||||
} | |||||
public boolean isAutoColor() { | |||||
return autoColor; | |||||
} | |||||
public void setAutoColor(boolean autoColor) { | |||||
this.autoColor = autoColor; | |||||
} | |||||
public WxMaQrcodeService.LineColor getLineColor() { | |||||
return lineColor; | |||||
} | |||||
public void setLineColor(WxMaQrcodeService.LineColor lineColor) { | |||||
this.lineColor = lineColor; | |||||
} | |||||
} | } |
@@ -15,6 +15,9 @@ public class BaseBuilder<T> { | |||||
return (T) this; | return (T) this; | ||||
} | } | ||||
/** | |||||
* 构造器方法. | |||||
*/ | |||||
public WxMaKefuMessage build() { | public WxMaKefuMessage build() { | ||||
WxMaKefuMessage m = new WxMaKefuMessage(); | WxMaKefuMessage m = new WxMaKefuMessage(); | ||||
m.setMsgType(this.msgType); | m.setMsgType(this.msgType); | ||||
@@ -13,8 +13,8 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||||
this.msgType = WxMaConstants.KefuMsgType.IMAGE; | this.msgType = WxMaConstants.KefuMsgType.IMAGE; | ||||
} | } | ||||
public ImageBuilder mediaId(String media_id) { | |||||
this.mediaId = media_id; | |||||
public ImageBuilder mediaId(String mediaId) { | |||||
this.mediaId = mediaId; | |||||
return this; | return this; | ||||
} | } | ||||
@@ -175,6 +175,7 @@ public class WxMaInMemoryConfig implements WxMaConfig { | |||||
return true; | return true; | ||||
} | } | ||||
@Override | |||||
public String getAppid() { | public String getAppid() { | ||||
return appid; | return appid; | ||||
} | } | ||||
@@ -8,11 +8,19 @@ package cn.binarywang.wx.miniapp.constant; | |||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class WxMaConstants { | public class WxMaConstants { | ||||
/** | |||||
* 微信接口返回的参数errcode | |||||
*/ | |||||
public static final String ERRCODE = "errcode"; | |||||
/** | /** | ||||
* 素材类型 | * 素材类型 | ||||
*/ | */ | ||||
public static class MediaType { | public static class MediaType { | ||||
public static final String IMAGE = "image";//图片 | |||||
/** | |||||
* 图片 | |||||
*/ | |||||
public static final String IMAGE = "image"; | |||||
} | } | ||||
/** | /** | ||||
@@ -27,7 +35,30 @@ public class WxMaConstants { | |||||
* 客服消息的消息类型 | * 客服消息的消息类型 | ||||
*/ | */ | ||||
public static class KefuMsgType { | public static class KefuMsgType { | ||||
public static final String TEXT = "text";//文本消息 | |||||
public static final String IMAGE = "image";//图片消息 | |||||
/** | |||||
* 文本消息 | |||||
*/ | |||||
public static final String TEXT = "text"; | |||||
/** | |||||
* 图片消息 | |||||
*/ | |||||
public static final String IMAGE = "image"; | |||||
} | |||||
public static final class ErrorCode { | |||||
/** | |||||
* 40001 获取access_token时AppSecret错误,或者access_token无效 | |||||
*/ | |||||
public static final int ERR_40001 = 40001; | |||||
/** | |||||
* 42001 access_token超时 | |||||
*/ | |||||
public static final int ERR_42001 = 42001; | |||||
/** | |||||
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期) | |||||
*/ | |||||
public static final int ERR_40014 = 40014; | |||||
} | } | ||||
} | } |
@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.message; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaMessage; | import cn.binarywang.wx.miniapp.bean.WxMaMessage; | ||||
import com.google.common.util.concurrent.ThreadFactoryBuilder; | |||||
import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | ||||
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | ||||
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | ||||
@@ -17,10 +18,7 @@ import java.util.ArrayList; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.concurrent.ExecutionException; | |||||
import java.util.concurrent.ExecutorService; | |||||
import java.util.concurrent.Executors; | |||||
import java.util.concurrent.Future; | |||||
import java.util.concurrent.*; | |||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
@@ -42,7 +40,9 @@ public class WxMaMessageRouter { | |||||
public WxMaMessageRouter(WxMaService wxMaService) { | public WxMaMessageRouter(WxMaService wxMaService) { | ||||
this.wxMaService = wxMaService; | this.wxMaService = wxMaService; | ||||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||||
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("WxMaMessageRouter-pool-%d").build(); | |||||
this.executorService = new ThreadPoolExecutor(DEFAULT_THREAD_POOL_SIZE, DEFAULT_THREAD_POOL_SIZE, | |||||
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), namedThreadFactory); | |||||
this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); | ||||
this.sessionManager = new StandardSessionManager(); | this.sessionManager = new StandardSessionManager(); | ||||
this.exceptionHandler = new LogExceptionHandler(); | this.exceptionHandler = new LogExceptionHandler(); | ||||
@@ -159,7 +159,7 @@ public class WxMaMessageRouter { | |||||
} | } | ||||
public void route(final WxMaMessage wxMessage) { | public void route(final WxMaMessage wxMessage) { | ||||
this.route(wxMessage, new HashMap<String, Object>()); | |||||
this.route(wxMessage, new HashMap<String, Object>(2)); | |||||
} | } | ||||
/** | /** | ||||
@@ -196,7 +196,7 @@ public class WxMaMessageRouterRule { | |||||
WxSessionManager sessionManager, | WxSessionManager sessionManager, | ||||
WxErrorExceptionHandler exceptionHandler) { | WxErrorExceptionHandler exceptionHandler) { | ||||
if (context == null) { | if (context == null) { | ||||
context = new HashMap<>(); | |||||
context = new HashMap<>(16); | |||||
} | } | ||||
try { | try { | ||||
@@ -1,6 +1,6 @@ | |||||
package cn.binarywang.wx.miniapp.util.http; | package cn.binarywang.wx.miniapp.util.http; | ||||
import cn.binarywang.wx.miniapp.bean.WxMaQrcodeWrapper; | |||||
import cn.binarywang.wx.miniapp.bean.AbstractWxMaQrcodeWrapper; | |||||
import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
import me.chanjar.weixin.common.util.fs.FileUtils; | import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
@@ -25,7 +25,7 @@ import java.util.UUID; | |||||
/** | /** | ||||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
*/ | */ | ||||
public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWrapper> { | |||||
public class QrCodeRequestExecutor implements RequestExecutor<File, AbstractWxMaQrcodeWrapper> { | |||||
protected RequestHttp<CloseableHttpClient, HttpHost> requestHttp; | protected RequestHttp<CloseableHttpClient, HttpHost> requestHttp; | ||||
public QrCodeRequestExecutor(RequestHttp requestHttp) { | public QrCodeRequestExecutor(RequestHttp requestHttp) { | ||||
@@ -33,14 +33,12 @@ public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWr | |||||
} | } | ||||
@Override | @Override | ||||
public File execute(String uri, WxMaQrcodeWrapper ticket) throws WxErrorException, IOException { | |||||
public File execute(String uri, AbstractWxMaQrcodeWrapper ticket) throws WxErrorException, IOException { | |||||
HttpPost httpPost = new HttpPost(uri); | HttpPost httpPost = new HttpPost(uri); | ||||
if (requestHttp.getRequestHttpProxy() != null) { | if (requestHttp.getRequestHttpProxy() != null) { | ||||
httpPost | |||||
.setConfig(RequestConfig.custom() | |||||
.setProxy(requestHttp.getRequestHttpProxy()) | |||||
.build() | |||||
); | |||||
httpPost.setConfig( | |||||
RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build() | |||||
); | |||||
} | } | ||||
httpPost.setEntity(new StringEntity(ticket.toString())); | httpPost.setEntity(new StringEntity(ticket.toString())); | ||||
@@ -48,7 +46,8 @@ public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWr | |||||
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) { | InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) { | ||||
Header[] contentTypeHeader = response.getHeaders("Content-Type"); | Header[] contentTypeHeader = response.getHeaders("Content-Type"); | ||||
if (contentTypeHeader != null && contentTypeHeader.length > 0 | if (contentTypeHeader != null && contentTypeHeader.length > 0 | ||||
&& ContentType.APPLICATION_JSON.getMimeType().equals(contentTypeHeader[0].getValue())) { | |||||
&& ContentType.APPLICATION_JSON.getMimeType() | |||||
.equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) { | |||||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
throw new WxErrorException(WxError.fromJson(responseContent)); | throw new WxErrorException(WxError.fromJson(responseContent)); | ||||
} | } | ||||
@@ -18,7 +18,7 @@ public class XStreamTransformer { | |||||
} | } | ||||
/** | /** | ||||
* xml -> pojo | |||||
* xml -> pojo. | |||||
*/ | */ | ||||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
public static <T> T fromXml(Class<T> clazz, String xml) { | public static <T> T fromXml(Class<T> clazz, String xml) { | ||||
@@ -33,14 +33,14 @@ public class XStreamTransformer { | |||||
} | } | ||||
/** | /** | ||||
* pojo -> xml | |||||
* pojo -> xml. | |||||
*/ | */ | ||||
public static <T> String toXml(Class<T> clazz, T object) { | public static <T> String toXml(Class<T> clazz, T object) { | ||||
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | ||||
} | } | ||||
/** | /** | ||||
* 注册扩展消息的解析器 | |||||
* 注册扩展消息的解析器. | |||||
* | * | ||||
* @param clz 类型 | * @param clz 类型 | ||||
* @param xStream xml解析器 | * @param xStream xml解析器 | ||||
@@ -50,12 +50,14 @@ public class XStreamTransformer { | |||||
} | } | ||||
/** | /** | ||||
* 会自动注册该类及其子类 | |||||
* 会自动注册该类及其子类. | |||||
* | * | ||||
* @param clz 要注册的类 | * @param clz 要注册的类 | ||||
*/ | */ | ||||
private static void registerClass(Class<?> clz) { | private static void registerClass(Class<?> clz) { | ||||
XStream xstream = XStreamInitializer.getInstance(); | XStream xstream = XStreamInitializer.getInstance(); | ||||
xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); | |||||
xstream.processAnnotations(clz); | xstream.processAnnotations(clz); | ||||
xstream.processAnnotations(getInnerClasses(clz)); | xstream.processAnnotations(getInnerClasses(clz)); | ||||
if (clz.equals(WxMaMessage.class)) { | if (clz.equals(WxMaMessage.class)) { | ||||
@@ -31,7 +31,7 @@ public class WxMaMsgServiceImplTest { | |||||
TestConfig configStorage = (TestConfig) this.wxService | TestConfig configStorage = (TestConfig) this.wxService | ||||
.getWxMaConfig(); | .getWxMaConfig(); | ||||
WxMaKefuMessage message = new WxMaKefuMessage(); | WxMaKefuMessage message = new WxMaKefuMessage(); | ||||
message.setMsgType(WxConsts.CUSTOM_MSG_MPNEWS); | |||||
message.setMsgType(WxConsts.KefuMsgType.MPNEWS); | |||||
message.setToUser(configStorage.getOpenid()); | message.setToUser(configStorage.getOpenid()); | ||||
this.wxService.getMsgService().sendKefuMsg(message); | this.wxService.getMsgService().sendKefuMsg(message); | ||||
@@ -41,7 +41,7 @@ public class WxMaMsgServiceImplTest { | |||||
TestConfig config = (TestConfig) this.wxService | TestConfig config = (TestConfig) this.wxService | ||||
.getWxMaConfig(); | .getWxMaConfig(); | ||||
WxMaKefuMessage message = new WxMaKefuMessage(); | WxMaKefuMessage message = new WxMaKefuMessage(); | ||||
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); | |||||
message.setMsgType(WxConsts.KefuMsgType.TEXT); | |||||
message.setToUser(config.getOpenid()); | message.setToUser(config.getOpenid()); | ||||
message.setContent( | message.setContent( | ||||
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | "欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | ||||
@@ -54,7 +54,7 @@ public class WxMaMsgServiceImplTest { | |||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); | ||||
TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); | TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); | ||||
WxMaTemplateMessage templateMessage = WxMaTemplateMessage.newBuilder() | |||||
WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() | |||||
.toUser(config.getOpenid()) | .toUser(config.getOpenid()) | ||||
.formId("FORMID") | .formId("FORMID") | ||||
.page("index") | .page("index") | ||||