diff --git a/CHANGE.md b/CHANGE.md index 8d46fdf5..bc90aa86 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -196,7 +196,7 @@ * 2015-03-25 - + **weixin4j-mp**: 根据《微信商户平台文档》修缮[Pay3Api](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类 + + **weixin4j-mp**: 根据《微信商户平台文档》修缮[Pay3Api](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类 + **weixin4j-mp**: 新增客服创建、关闭、转接会话事件 @@ -210,27 +210,27 @@ + **weixin4j-mp**: 单行注释调整为多行文档注释 - + **weixin4j-mp**: 新增[CouponApi](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口 + + **weixin4j-mp**: 新增[CouponApi](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口 + **weixin4j-qy**: 单行注释调整为多行文档注释 * 2015-04-01 - + **weixin4j-mp**: 新增[CashApi](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口 + + **weixin4j-mp**: 新增[CashApi](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口 - + **weixin4j-qy**: 新增[BatchApi](./weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/BatchApi.java)批量异步执行任务接口 + + **weixin4j-qy**: 新增[BatchApi](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/BatchApi.java)批量异步执行任务接口 + **weixin4j-qy**: DepartApi命名为[PartyApi](./weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/PartyApi.java) * 2015-04-04 - + **weixin4j-qy**: [MediaApi](./weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java)新增批量上传成员和部门接口 + + **weixin4j-qy**: [MediaApi](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java)新增批量上传成员和部门接口 + released 1.3 * 2015-04-09 - + **weixin4j-qy**: [AgentApi](./weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/AgentApi.java)新增获取应用列表概况接口 + + **weixin4j-qy**: [AgentApi](./weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/AgentApi.java)新增获取应用列表概况接口 * 2015-04-13 @@ -244,12 +244,19 @@ * 2015-04-16 - + **weixin4j-mp**: 调整[二维码参数](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类 + + **weixin4j-mp**: 调整[二维码参数](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类 - + **weixin4j-mp**: 新增获取[自定义菜单配置、自动回复配置](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口 + + **weixin4j-mp**: 新增获取[自定义菜单配置、自动回复配置](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口 * 2015-04-18 - + **weixin4j-mp**: 调整[客服接口](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名 + + **weixin4j-mp**: 调整[客服接口](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名 - + **weixin4j-mp**: 在[二维码接口](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法 \ No newline at end of file + + **weixin4j-mp**: 在[二维码接口](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法 + + + * 2015-04-19 + + + 调整聚合方式,去除原先的weixin4j-mp和weixin4j-qy模块,相应的api模块直接继承weixin4j父模块 + + + **weixin4j-base**: 删除ActionMapping相关类 \ No newline at end of file diff --git a/README.md b/README.md index 97f6ddec..8179096c 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ weixin4j `公众平台API封装` `微信支付(刷卡/扫码/公众号)` - - `netty服务器&消息分发` * **weixin4j-qy** `企业号API封装` +* **weixin4j-server** + `netty服务器&消息分发` 项目说明 @@ -58,13 +58,11 @@ https://github.com/foxinmy/weixin4j/releases ###3.从源码打包 -`git clone`&`mvn package -Prelease`,到相应的target目录下将`weixin4j-[mp|qy]-full`包或者`weixin4j-base`和`weixin4j-[mp|qy]-api`引入到自己的工程. +`git clone`&`mvn package -Prelease`,到相应的target目录下将`weixin4j-[mp|qy]-full`包或者`weixin4j-base`和`weixin4j-[mp|qy]`引入到自己的工程. 如何获取netty部分 --------------- -netty的代码没有放到maven中心仓库,也没什么意义,因为最终需要自己去实现具体的业务逻辑, - -下载winxin4j-[mp|qy]-server项目的源代码复制到自己的工程内,当然也可以在上面直接开发. +正在构思中... [更新LOG](./CHANGE.md) ---------------------- diff --git a/pom.xml b/pom.xml index da7f0fce..9bd1cfea 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ weixin4j-base weixin4j-mp weixin4j-qy + weixin4j-server 1.7 diff --git a/weixin4j-base/README.md b/weixin4j-base/README.md index 6cd830c0..6049ccb8 100644 --- a/weixin4j-base/README.md +++ b/weixin4j-base/README.md @@ -11,52 +11,5 @@ weixin4j-base `通用消息实体` -更新LOG -------- -* 2014-10-31 - - + `TokenApi`重命名为`TokenHolder` - - + 新增`WeixinConfig`等类 - -* 2014-11-06 - - + 删除`WeixinConfig`类只保留`WeixinAccount`类 - -* 2014-11-15 - - + 新增`aes加密解密`函数 - -* 2014-11-19 - - + 新增`WeixinQyAccount`企业号账号信息类 - -* 2014-11-23 - - + 新增企业号消息体以及用`Responseable`,`Notifyable`,`Massable`三个接口标记不同的可接受的消息类型 - -* 2014-11-24 - - + 将Action跟Mapping基础类并入到项目 - -* 2015-01-04 - - + ConfigUtil类新增获取classpath目录下的资源路径的方法 - -* 2015-01-10 - - + 重构token实现机制 - - + 新增JSTICKET支持 - -* 2015-03-29 - - + 单行注释调整为多行文档注释 - -* 2015-04-01 - - + 新增异步消息事件[BatchjobresultMessage](./src/main/java/com/foxinmy/weixin4j/msg/event/BatchjobresultMessage.java) - -* 2015-04-13 - - + 删除WeixinTokenCreator与WeixinJSTicketCreator类 \ No newline at end of file +[更新LOG](./CHANGE.md) +--------------------- diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/AbstractAction.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/AbstractAction.java deleted file mode 100644 index bd56f794..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/AbstractAction.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.foxinmy.weixin4j.action; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - -import org.dom4j.DocumentException; - -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.response.ResponseMessage; -import com.foxinmy.weixin4j.util.MessageUtil; -import com.foxinmy.weixin4j.xml.XmlStream; - -/** - * 继承的类需实现execute(M inMessage) - * - * @className AbstractAction - * @author jy - * @date 2014年10月12日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.action.WeixinAction - */ -@SuppressWarnings("unchecked") -public abstract class AbstractAction implements WeixinAction { - - public abstract ResponseMessage execute(M inMessage); - - @Override - public ResponseMessage execute(String msg) throws DocumentException { - BaseMsg message = MessageUtil.xml2msg(msg); - if (message == null) { - return execute(XmlStream.get(msg, getGenericType())); - } - return execute((M) message); - } - - private Class getGenericType() { - Class clazz = null; - Type type = getClass().getGenericSuperclass(); - if (type instanceof ParameterizedType) { - ParameterizedType ptype = ((ParameterizedType) type); - Type[] args = ptype.getActualTypeArguments(); - clazz = (Class) args[0]; - } - return clazz; - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/BlankAction.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/BlankAction.java deleted file mode 100644 index 7a754876..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/BlankAction.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.foxinmy.weixin4j.action; - -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.response.ResponseMessage; - -/** - * 回复一个空字符串 而不是一个XML结构体中content字段的内容为空 - * - * @className BlankAction - * @author jy.hu - * @date 2014年10月2日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.action.AbstractAction - */ -public class BlankAction extends AbstractAction { - - @Override - public ResponseMessage execute(M inMessage) { - return null; - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/DebugAction.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/DebugAction.java deleted file mode 100644 index a5d1d06c..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/DebugAction.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.foxinmy.weixin4j.action; - -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.msg.model.Text; -import com.foxinmy.weixin4j.response.ResponseMessage; - -/** - * 调试输出用户消息 - * - * @className DebugAction - * @author jy - * @date 2014年10月8日 - * @since JDK 1.7 - * @see - */ -public class DebugAction extends AbstractAction { - - @Override - public ResponseMessage execute(M message) { - return new ResponseMessage(new Text(message.toString()), message); - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/README.md deleted file mode 100644 index 1cb9faa2..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/README.md +++ /dev/null @@ -1,3 +0,0 @@ -消息处理接口,与weixin4j-*-server配合使用 - -如果单纯只使用API包,则可以不关注 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/WeixinAction.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/WeixinAction.java deleted file mode 100644 index cbd6bf54..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/WeixinAction.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.foxinmy.weixin4j.action; - -import org.dom4j.DocumentException; - -import com.foxinmy.weixin4j.response.ResponseMessage; - -/** - * 消息处理接口 - * - * @className Action - * @author jy.hu - * @date 2014年10月2日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.action.AbstractAction - * @see com.foxinmy.weixin4j.action.BlankAction - * @see com.foxinmy.weixin4j.action.DebugAction - */ -public interface WeixinAction { - public ResponseMessage execute(String inMsg) throws DocumentException; -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AbstractActionMapping.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AbstractActionMapping.java deleted file mode 100644 index e3770fd1..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AbstractActionMapping.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.foxinmy.weixin4j.action.mapping; - -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; - -import com.foxinmy.weixin4j.type.MessageType; - -/** - * 获取默认的Mapping Key 如text,event_click - * - * @className AbstractActionMapping - * @author jy - * @date 2014年10月28日 - * @since JDK 1.7 - * @see - */ -public abstract class AbstractActionMapping implements ActionMapping { - - protected final static String DECOLLATOR = ":"; - - protected String getMappingKey(String xmlMsg) throws DocumentException { - Document doc = DocumentHelper.parseText(xmlMsg); - String msgType = doc.selectSingleNode("/xml/MsgType").getStringValue(); - if (msgType.equalsIgnoreCase(MessageType.event.name())) { - msgType += DECOLLATOR - + doc.selectSingleNode("/xml/Event").getStringValue(); - } - return msgType.toLowerCase(); - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionAnnotation.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionAnnotation.java deleted file mode 100644 index 7ab1e535..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionAnnotation.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.foxinmy.weixin4j.action.mapping; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.foxinmy.weixin4j.type.EventType; -import com.foxinmy.weixin4j.type.MessageType; - -/** - * 标注Action类来处理消息请求 - * @className Action - * @author jy - * @date 2014年10月12日 - * @since JDK 1.7 - * @see - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface ActionAnnotation { - - MessageType msgType(); - - EventType[] eventType() default {}; -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionMapping.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionMapping.java deleted file mode 100644 index 5ea85556..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/ActionMapping.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.foxinmy.weixin4j.action.mapping; - -import org.dom4j.DocumentException; - -import com.foxinmy.weixin4j.action.WeixinAction; - -/** - * 可扩展的Mapping接口 - * - * @className ActionMapping - * @author jy - * @date 2014年10月28日 - * @since JDK 1.7 - * @see - */ -public interface ActionMapping { - public WeixinAction getAction(String xmlMsg) throws DocumentException; -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AnnotationActionMapping.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AnnotationActionMapping.java deleted file mode 100644 index 6fa6d425..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/AnnotationActionMapping.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.foxinmy.weixin4j.action.mapping; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.dom4j.DocumentException; - -import com.foxinmy.weixin4j.action.WeixinAction; -import com.foxinmy.weixin4j.type.EventType; -import com.foxinmy.weixin4j.type.MessageType; -import com.foxinmy.weixin4j.util.ClassUtil; - -/** - * 注解实现的Mapping - * - * @className AnnotationActionMapping - * @author jy - * @date 2014年10月28日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.action.mapping.ActionAnnotation - */ -public class AnnotationActionMapping extends AbstractActionMapping { - private final Map actionMap; - - public AnnotationActionMapping(Package actionPackage) { - actionMap = new HashMap(); - Set> weixinActions = ClassUtil.getClasses(actionPackage); - for (Class clazz : weixinActions) { - ActionAnnotation action = clazz - .getAnnotation(ActionAnnotation.class); - if (action == null) { - continue; - } - WeixinAction weixinAction = null; - try { - weixinAction = (WeixinAction) clazz.newInstance(); - } catch (Exception e) { - continue; - } - MessageType msgType = action.msgType(); - EventType[] eventTypes = action.eventType(); - if (eventTypes != null && eventTypes.length > 0) { - for (EventType e : eventTypes) { - actionMap.put((msgType.name() + DECOLLATOR + e.name()) - .toLowerCase(), weixinAction); - } - continue; - } - actionMap.put(msgType.name().toLowerCase(), weixinAction); - } - } - - public WeixinAction getAction(String xmlMsg) throws DocumentException { - String key = getMappingKey(xmlMsg); - return actionMap.get(key); - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/README.md deleted file mode 100644 index 38f6c322..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/action/mapping/README.md +++ /dev/null @@ -1,7 +0,0 @@ -消息处理与Action类的mapping对应(使用注解类的方式) - -一般来说Action中应该有自己的实际业务处理类,那么上述方式可能不妥 - -推荐用org.springframework.context.ApplicationContext#getBeansWithAnnotation函数 - -当然,也可以重写AbstractActionMapping类实现自己的Mapping \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml index 290c0aab..a08afcb1 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml @@ -297,6 +297,26 @@ 40074 news消息不支持指定为高保密消息 + + 40117 + 分组名字不合法 + + + 40118 + media_id大小不合法 + + + 40119 + button类型错误 + + + 40120 + button类型错误 + + + 40121 + 不合法的media_id类型 + 41001 access_token missing diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/BaseMsg.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/BaseMessage.java similarity index 81% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/BaseMsg.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/BaseMessage.java index 4997748b..567326fa 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/BaseMsg.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/BaseMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.model; +package com.foxinmy.weixin4j.message; import java.io.Serializable; @@ -7,12 +7,12 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 消息基类 * - * @className BaseMsg + * @className BaseMessage * @author jy.hu * @date 2014年4月6日 * @since JDK 1.7 */ -public class BaseMsg implements Serializable { +public class BaseMessage implements Serializable { private static final long serialVersionUID = 7761192742840031607L; @@ -49,19 +49,19 @@ public class BaseMsg implements Serializable { @XStreamAlias("AgentID") private String agentId; - public BaseMsg() { + public BaseMessage() { } - public BaseMsg(String msgType) { + public BaseMessage(String msgType) { this.msgType = msgType; } - public BaseMsg(String toUserName, String fromUserName) { + public BaseMessage(String toUserName, String fromUserName) { this(null, toUserName, fromUserName); } - public BaseMsg(String msgType, String toUserName, String fromUserName) { + public BaseMessage(String msgType, String toUserName, String fromUserName) { this.msgType = msgType; this.toUserName = toUserName; this.fromUserName = fromUserName; @@ -124,8 +124,9 @@ public class BaseMsg implements Serializable { @Override public boolean equals(Object obj) { - if (obj instanceof BaseMsg) { - return ((BaseMsg) obj).getMsgId() == msgId; + if (obj instanceof BaseMessage) { + return ((BaseMessage) obj).getMsgId() == msgId + && ((BaseMessage) obj).getCreateTime() == createTime; } return false; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/ImageMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/ImageMessage.java similarity index 87% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/ImageMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/ImageMessage.java index 6c741a0e..45e0fe3d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/ImageMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/ImageMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的图片消息 */ -public class ImageMessage extends BaseMsg { +public class ImageMessage extends BaseMessage { private static final long serialVersionUID = 8430800898756567016L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LinkMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LinkMessage.java similarity index 85% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LinkMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LinkMessage.java index bcec93cb..98ff2ea0 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LinkMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LinkMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -14,7 +13,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 订阅号、服务号的链接消息 */ -public class LinkMessage extends BaseMsg { +public class LinkMessage extends BaseMessage { private static final long serialVersionUID = 754952745115497030L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LocationMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LocationMessage.java similarity index 88% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LocationMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LocationMessage.java index 2001e30a..bfabc618 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/LocationMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/LocationMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的地理位置消息 */ -public class LocationMessage extends BaseMsg { +public class LocationMessage extends BaseMessage { private static final long serialVersionUID = 2866021596599237334L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/README.md similarity index 100% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/README.md rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/README.md diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/TextMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/TextMessage.java similarity index 88% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/TextMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/TextMessage.java index 7188a0a7..36d73cbc 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/TextMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/TextMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的文本消息 */ -public class TextMessage extends BaseMsg { +public class TextMessage extends BaseMessage { private static final long serialVersionUID = -7018053906644190260L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VideoMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VideoMessage.java similarity index 88% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VideoMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VideoMessage.java index 99483784..cd83bb42 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VideoMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VideoMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的视频消息 */ -public class VideoMessage extends BaseMsg { +public class VideoMessage extends BaseMessage { private static final long serialVersionUID = -1013075358679078381L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VoiceMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VoiceMessage.java similarity index 89% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VoiceMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VoiceMessage.java index 4f2b0064..fb68ae26 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/VoiceMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/VoiceMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg; +package com.foxinmy.weixin4j.message; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -19,7 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的语音消息 */ -public class VoiceMessage extends BaseMsg { +public class VoiceMessage extends BaseMessage { private static final long serialVersionUID = -7988380977182214003L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/EventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/EventMessage.java similarity index 72% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/EventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/EventMessage.java index 8b2b898e..613a98f9 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/EventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/EventMessage.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.message.event; -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.BaseMessage; import com.foxinmy.weixin4j.type.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -17,11 +16,11 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see 企业号的事件消息 */ -public class EventMessage extends BaseMsg { +public class EventMessage extends BaseMessage { private static final long serialVersionUID = 7703667223814088865L; - public EventMessage(EventType eventType) { + public EventMessage(String eventType) { super(MessageType.event.name()); this.eventType = eventType; } @@ -32,9 +31,9 @@ public class EventMessage extends BaseMsg { * @see com.foxinmy.weixin4j.type.EventType */ @XStreamAlias("Event") - private EventType eventType; + private String eventType; - public EventType getEventType() { + public String getEventType() { return eventType; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/LocationEventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/LocationEventMessage.java similarity index 91% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/LocationEventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/LocationEventMessage.java index ee8d375b..400e36d5 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/LocationEventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/LocationEventMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.message.event; import com.foxinmy.weixin4j.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -20,7 +20,7 @@ public class LocationEventMessage extends EventMessage { private static final long serialVersionUID = -2030716800669824861L; public LocationEventMessage() { - super(EventType.location); + super(EventType.location.name()); } /** * 地理位置纬度 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuEventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuEventMessage.java similarity index 86% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuEventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuEventMessage.java index 927cc8d8..b21bad55 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuEventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuEventMessage.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg.event.menu; +package com.foxinmy.weixin4j.message.event; -import com.foxinmy.weixin4j.msg.event.EventMessage; import com.foxinmy.weixin4j.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -21,11 +20,11 @@ public class MenuEventMessage extends EventMessage { private static final long serialVersionUID = -1049672447995366063L; public MenuEventMessage() { - super(EventType.click); + super(EventType.click.name()); } public MenuEventMessage(EventType eventType) { - super(eventType); + super(eventType.name()); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuLocationEventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuLocationEventMessage.java similarity index 98% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuLocationEventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuLocationEventMessage.java index d63f8958..574f3e15 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuLocationEventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuLocationEventMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.event.menu; +package com.foxinmy.weixin4j.message.event; import java.io.Serializable; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuPhotoEventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuPhotoEventMessage.java similarity index 98% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuPhotoEventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuPhotoEventMessage.java index 91c99d19..a6a9a51d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuPhotoEventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuPhotoEventMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.event.menu; +package com.foxinmy.weixin4j.message.event; import java.io.Serializable; import java.util.List; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuScanEventMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuScanEventMessage.java similarity index 97% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuScanEventMessage.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuScanEventMessage.java index 31ad5dfc..c83c6165 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/MenuScanEventMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/MenuScanEventMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.event.menu; +package com.foxinmy.weixin4j.message.event; import java.io.Serializable; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/README.md similarity index 82% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/README.md rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/README.md index 5885ae05..f2651b2b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/menu/README.md +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/message/event/README.md @@ -1,3 +1,3 @@ -菜单消息 +菜单事件消息 用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。请注意,第3个到第8个的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java index 1860e8e2..67ce4624 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java @@ -25,10 +25,6 @@ public final class Consts { public static final String PROTOCOL_FILE = "file"; public static final String PROTOCOL_JAR = "jar"; - /** - * oauth验证url - */ - public static final String OAUTH_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"; /** * 公众平台获取token的url */ diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java index 87c19dcd..19a5f75e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java @@ -1,12 +1,6 @@ package com.foxinmy.weixin4j.model; import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - -import org.apache.commons.lang3.StringUtils; - -import com.foxinmy.weixin4j.type.AccountType; /** * 微信账号信息 @@ -17,7 +11,7 @@ import com.foxinmy.weixin4j.type.AccountType; * @since JDK 1.7 * @see */ -public abstract class WeixinAccount implements Serializable { +public class WeixinAccount implements Serializable { private static final long serialVersionUID = -6001008896414323534L; /** @@ -33,11 +27,6 @@ public abstract class WeixinAccount implements Serializable { * 安全模式下的加密密钥 */ private String encodingAesKey; - /** - * 账号类型 - * @return - */ - public abstract AccountType getAccountType(); public WeixinAccount() { } @@ -79,39 +68,6 @@ public abstract class WeixinAccount implements Serializable { this.encodingAesKey = encodingAesKey; } - /** - * 拼接授权URL - * - * @param redirectUri - * 授权后重定向的回调链接地址 - * @param scope - * 应用授权作用域,snsapi_base - * (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo - * (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) - * @param state - * 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值 - * @return 授权URL - */ - public String getOauthAuthorizeUrl(String redirectUri, String scope, - String state) { - if (StringUtils.isBlank(scope)) { - scope = "snsapi_base"; - } - if (StringUtils.isBlank(state)) { - state = "STATE"; - } - try { - return String.format( - Consts.OAUTH_AUTHORIZE_URL, - URLEncoder.encode(redirectUri, - org.apache.http.Consts.UTF_8.name()), id, scope, - state); - } catch (UnsupportedEncodingException ignore) { - ; - } - return ""; - } - @Override public String toString() { return "id=" + id + ", secret=" + secret + ", token=" + token diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/README.md deleted file mode 100644 index 9a537b99..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/README.md +++ /dev/null @@ -1,10 +0,0 @@ -事件消息 -------- - -当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。各消息类型的推送XML数据包结构如下: - -微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次 - -关于重试的消息排重,推荐使用msgid排重。 - -假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Base.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Base.java deleted file mode 100644 index 1b6c9987..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Base.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.foxinmy.weixin4j.msg.model; - -import java.io.Serializable; - -import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; -import com.thoughtworks.xstream.annotations.XStreamOmitField; - -/** - * 消息对象基类 - * - * @className Base - * @author jy - * @date 2015年3月21日 - * @since JDK 1.7 - * @see - */ -public class Base implements Serializable { - - private static final long serialVersionUID = 8487251213352068227L; - - /** - * 媒体类型 - */ - @JSONField(serialize = false) - @XStreamOmitField - private MediaType mediaType; - - public Base(MediaType mediaType) { - this.mediaType = mediaType; - } - - public MediaType getMediaType() { - return mediaType; - } - - @Override - public String toString() { - return "Base [mediaType=" + mediaType + "]"; - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Massable.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Massable.java deleted file mode 100644 index f80ca632..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Massable.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.foxinmy.weixin4j.msg.model; - -/** - * 标记群发消息 - * - * @className Massable - * @author jy - * @date 2014年11月22日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.MpVideo - * @see com.foxinmy.weixin4j.msg.model.MpNews - */ -public interface Massable { - -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Notifyable.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Notifyable.java deleted file mode 100644 index 8ad731ac..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Notifyable.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.foxinmy.weixin4j.msg.model; - -/** - * 标记客服消息 - * - * @className Notifyable - * @author jy - * @date 2014年11月22日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.Video - * @see com.foxinmy.weixin4j.msg.model.Music - * @see com.foxinmy.weixin4j.msg.model.News - */ -public interface Notifyable { - -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Responseable.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Responseable.java deleted file mode 100644 index b90f5b72..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Responseable.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.foxinmy.weixin4j.msg.model; - -/** - * 标记被动消息 - * - * @className Responseable - * @author jy - * @date 2014年11月22日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.Video - * @see com.foxinmy.weixin4j.msg.model.Music - * @see com.foxinmy.weixin4j.msg.model.News - * @see com.foxinmy.weixin4j.msg.model.Trans - */ -public interface Responseable { - -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/response/ResponseMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/response/ResponseMessage.java deleted file mode 100644 index 0ad701bf..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/response/ResponseMessage.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.foxinmy.weixin4j.response; - -import org.apache.commons.lang3.StringUtils; - -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.msg.model.Article; -import com.foxinmy.weixin4j.msg.model.Base; -import com.foxinmy.weixin4j.msg.model.News; -import com.foxinmy.weixin4j.msg.model.Responseable; -import com.foxinmy.weixin4j.util.ClassUtil; -import com.foxinmy.weixin4j.xml.TextConverter; -import com.foxinmy.weixin4j.xml.XmlStream; -import com.thoughtworks.xstream.annotations.XStreamAlias; - -/** - * 被动消息 - *

- * 回复图片等多媒体消息时需要预先上传多媒体文件到微信服务器, - * 假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试 - *

- * - * @className ResponseMessage - * @author jy.hu - * @date 2014年11月22日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.Video - * @see com.foxinmy.weixin4j.msg.model.Music - * @see com.foxinmy.weixin4j.msg.model.News - * @see com.foxinmy.weixin4j.msg.model.Trans - * @see 订阅号、服务号的被动响应消息 - * @see 企业号的被动响应消息 - */ -@XStreamAlias("xml") -public class ResponseMessage extends BaseMsg { - - private static final long serialVersionUID = 7761192742840031607L; - - protected final static XmlStream xmlStream = XmlStream.get(); - static { - Class[] classes = ClassUtil.getClasses(Base.class.getPackage()) - .toArray(new Class[0]); - xmlStream.autodetectAnnotations(true); - xmlStream.processAnnotations(classes); - xmlStream.processAnnotations(ResponseMessage.class); - xmlStream.registerConverter(new TextConverter()); - - xmlStream.omitField(BaseMsg.class, "msgId"); - xmlStream.alias("item", Article.class); - xmlStream.addImplicitCollection(News.class, "articles"); - xmlStream.aliasSystemAttribute(null, "class"); - } - /** - * 附加数据 - */ - private String attach; - /** - * 消息对象 - * - * @see com.foxinmy.weixin4j.msg.model.Responseable - */ - private final Base box; - - public ResponseMessage(Base box) { - super(box.getMediaType().name()); - this.box = box; - } - - public ResponseMessage(Base box, BaseMsg inMessage) { - this(box, inMessage.getFromUserName(), inMessage.getToUserName()); - } - - public ResponseMessage(Base box, String toUserName, String fromUserName) { - super(box.getMediaType().name(), toUserName, fromUserName); - this.box = box; - } - - public String getAttach() { - return attach; - } - - public Base getBox() { - return box; - } - - /** - * 消息对象转换为微信服务器接受的xml格式消息
需Responseable标识,否则返回空 - * - * @see com.foxinmy.weixin4j.msg.model.Responseable - * @return xml字符串 - */ - public String toXml() { - // check responseable - if (!(box instanceof Responseable)) { - return ""; - } - String boxAlias = StringUtils.capitalize(getMsgType()); - XStreamAlias alias = box.getClass().getAnnotation(XStreamAlias.class); - if (alias != null) { - boxAlias = alias.value(); - } - xmlStream.aliasField(boxAlias, ResponseMessage.class, "box"); - if (box instanceof News) { - attach = Integer.toString(((News) box).getArticles().size()); - xmlStream.aliasField("ArticleCount", ResponseMessage.class, - "attach"); - } - return xmlStream.toXML(this); - } - - @Override - public String toString() { - return "ResponseMessage [ " + super.toString() + ", attach=" + attach - + ", box=" + box + "]"; - } -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Article.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java similarity index 97% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Article.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java index 2a246a65..f01e3d34 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Article.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Article.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import java.io.Serializable; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/File.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java similarity index 82% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/File.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java index 72040207..9b434da0 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/File.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/File.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,9 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -public class File extends Base implements Notifyable { +public class File implements NotifyTuple { + private static final long serialVersionUID = -8149837316289636110L; + @Override + public String getMessageType() { + return "file"; + } + /** * 上传后的微信返回的媒体ID */ @@ -27,7 +32,6 @@ public class File extends Base implements Notifyable { private String mediaId; public File(String mediaId) { - super(MediaType.file); this.mediaId = mediaId; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Image.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java similarity index 73% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Image.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java index 3ce3b035..798388dc 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Image.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Image.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -public class Image extends Base implements Responseable, Notifyable, Massable { +public class Image implements ResponseTuple, MassTuple, NotifyTuple { private static final long serialVersionUID = 6928681900960656161L; + @Override + public String getMessageType() { + return "image"; + } + /** * 上传后的微信返回的媒体ID */ @@ -28,12 +32,6 @@ public class Image extends Base implements Responseable, Notifyable, Massable { private String mediaId; public Image(String mediaId) { - super(MediaType.image); - this.mediaId = mediaId; - } - - public Image(MediaType mediaType, String mediaId) { - super(mediaType); this.mediaId = mediaId; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MassTuple.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MassTuple.java new file mode 100644 index 00000000..50f84bcd --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MassTuple.java @@ -0,0 +1,18 @@ +package com.foxinmy.weixin4j.tuple; + +/** + * 群发消息元件 + * + * @className MassTuple + * @author jy + * @date 2014年11月22日 + * @since JDK 1.7 + * @see com.foxinmy.weixin4j.tuple.Text + * @see com.foxinmy.weixin4j.tuple.Image + * @see com.foxinmy.weixin4j.tuple.Voice + * @see com.foxinmy.weixin4j.tuple.MpVideo + * @see com.foxinmy.weixin4j.tuple.MpNews + */ +public interface MassTuple extends Tuple { + +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpArticle.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java similarity index 98% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpArticle.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java index cca1e5ea..8f2cab25 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpArticle.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpArticle.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import java.io.Serializable; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpNews.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java similarity index 89% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpNews.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java index 2f5af91e..ae77d3bc 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpNews.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpNews.java @@ -1,10 +1,9 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import java.util.ArrayList; import java.util.List; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamOmitField; @@ -20,10 +19,15 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @since JDK 1.7 * @see */ -public class MpNews extends Base implements Massable, Notifyable { +public class MpNews implements MassTuple, NotifyTuple { private static final long serialVersionUID = 8853054484809101524L; + @Override + public String getMessageType() { + return "mpnews"; + } + /** * 上传图文列表后微信返回的媒体ID */ @@ -42,7 +46,6 @@ public class MpNews extends Base implements Massable, Notifyable { } public MpNews(String mediaId) { - super(MediaType.mpnews); this.mediaId = mediaId; this.articles = new ArrayList(); } @@ -88,7 +91,6 @@ public class MpNews extends Base implements Massable, Notifyable { @Override public String toString() { - return "MpNews [articles=" + articles + ", mediaId=" + mediaId - + ", getMediaType()=" + getMediaType() + "]"; + return "MpNews [articles=" + articles + ", mediaId=" + mediaId + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpVideo.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java similarity index 82% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpVideo.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java index 4daf0395..a2c327a4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/MpVideo.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/MpVideo.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -public class MpVideo extends Base implements Massable { +public class MpVideo implements MassTuple { private static final long serialVersionUID = 2167437425244069128L; + @Override + public String getMessageType() { + return "mpvideo"; + } + /** * 上传视频后微信返回的媒体ID */ @@ -28,7 +32,6 @@ public class MpVideo extends Base implements Massable { private String mediaId; public MpVideo(String mediaId) { - super(MediaType.mpvideo); this.mediaId = mediaId; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Music.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java similarity index 92% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Music.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java index 33b3461c..004a9bf7 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Music.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Music.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @since JDK 1.7 * @see */ -public class Music extends Base implements Responseable, Notifyable { +public class Music implements ResponseTuple, NotifyTuple { private static final long serialVersionUID = -5952134916367253297L; + @Override + public String getMessageType() { + return "music"; + } + /** * 音乐标题 */ @@ -56,7 +60,6 @@ public class Music extends Base implements Responseable, Notifyable { public Music(String title, String desc, String musicUrl, String hqMusicUrl, String thumbMediaId) { - super(MediaType.music); this.title = title; this.desc = desc; this.musicUrl = musicUrl; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/News.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java similarity index 90% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/News.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java index 10f26b22..a2314a0b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/News.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/News.java @@ -1,10 +1,9 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import java.util.ArrayList; import java.util.List; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -20,21 +19,27 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see */ @XStreamAlias("Articles") -public class News extends Base implements Responseable, Notifyable { - private static final int MAX_ARTICLE_COUNT = 10; +public class News implements ResponseTuple, NotifyTuple { + private static final long serialVersionUID = 3348756809039388415L; + @Override + public String getMessageType() { + return "news"; + } + + private static final int MAX_ARTICLE_COUNT = 10; + /** * 图文列表 * - * @see com.foxinmy.weixin4j.msg.model.Article + * @see com.foxinmy.weixin4j.tuple.Article */ @JSONField(name = "articles") @XStreamAlias("Articles") private List
articles; public News() { - super(MediaType.news); this.articles = new ArrayList
(); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/NotifyTuple.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/NotifyTuple.java new file mode 100644 index 00000000..34ca0e7a --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/NotifyTuple.java @@ -0,0 +1,19 @@ +package com.foxinmy.weixin4j.tuple; + +/** + * 客服消息元件 + * + * @className Notifyable + * @author jy + * @date 2014年11月22日 + * @since JDK 1.7 + * @see com.foxinmy.weixin4j.tuple.Text + * @see com.foxinmy.weixin4j.tuple.Image + * @see com.foxinmy.weixin4j.tuple.Voice + * @see com.foxinmy.weixin4j.tuple.Video + * @see com.foxinmy.weixin4j.tuple.Music + * @see com.foxinmy.weixin4j.tuple.News + */ +public interface NotifyTuple extends Tuple { + +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/README.md similarity index 100% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/README.md rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/README.md diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/ResponseTuple.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/ResponseTuple.java new file mode 100644 index 00000000..b7a7d906 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/ResponseTuple.java @@ -0,0 +1,20 @@ +package com.foxinmy.weixin4j.tuple; + +/** + * 被动消息元件 + * + * @className ResponseTuple + * @author jy + * @date 2014年11月22日 + * @since JDK 1.7 + * @see com.foxinmy.weixin4j.tuple.Text + * @see com.foxinmy.weixin4j.tuple.Image + * @see com.foxinmy.weixin4j.tuple.Voice + * @see com.foxinmy.weixin4j.tuple.Video + * @see com.foxinmy.weixin4j.tuple.Music + * @see com.foxinmy.weixin4j.tuple.News + * @see com.foxinmy.weixin4j.tuple.Trans + */ +public interface ResponseTuple extends Tuple { + +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Text.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java similarity index 78% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Text.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java index e0867342..c7d705a0 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Text.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Text.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,17 +15,21 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see */ @XStreamAlias("Content") -public class Text extends Base implements Responseable, Notifyable, Massable { +public class Text implements ResponseTuple, MassTuple, NotifyTuple { private static final long serialVersionUID = 520050144519064503L; + @Override + public String getMessageType() { + return "text"; + } + /** * 内容 */ private String content; public Text(String content) { - super(MediaType.text); this.content = content; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Trans.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Trans.java similarity index 78% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Trans.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Trans.java index 76ac578e..88eb115f 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Trans.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Trans.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; * @see */ @XStreamAlias("TransInfo") -public class Trans extends Base implements Responseable { +public class Trans implements ResponseTuple { private static final long serialVersionUID = -214711609286629729L; + @Override + public String getMessageType() { + return "transfer_customer_service"; + } + /** * 指定会话接入的客服账号 */ @@ -31,7 +35,6 @@ public class Trans extends Base implements Responseable { } public Trans(String kfAccount) { - super(MediaType.transfer_customer_service); this.kfAccount = kfAccount; } @@ -43,4 +46,5 @@ public class Trans extends Base implements Responseable { public String toString() { return "Trans [kfAccount=" + kfAccount + "]"; } + } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Video.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java similarity index 86% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Video.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java index d8df3733..a59cfe51 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Video.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java @@ -1,7 +1,6 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.MediaType; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamOmitField; @@ -17,10 +16,15 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField; * @since JDK 1.7 * @see */ -public class Video extends Base implements Responseable, Notifyable { +public class Video implements ResponseTuple, NotifyTuple { private static final long serialVersionUID = 2167437425244069128L; + @Override + public String getMessageType() { + return "video"; + } + /** * 上传视频微信返回的媒体ID */ @@ -46,7 +50,6 @@ public class Video extends Base implements Responseable, Notifyable { private String desc; public Video(String mediaId) { - super(MediaType.video); this.mediaId = mediaId; } @@ -59,7 +62,6 @@ public class Video extends Base implements Responseable, Notifyable { } public Video(String mediaId, String thumbMediaId, String title, String desc) { - super(MediaType.video); this.mediaId = mediaId; this.thumbMediaId = thumbMediaId; this.title = title; @@ -101,7 +103,6 @@ public class Video extends Base implements Responseable, Notifyable { @Override public String toString() { return "Video [thumbMediaId=" + thumbMediaId + ", title=" + title - + ", desc=" + desc + ", mediaId=" + mediaId - + ", getMediaType()=" + getMediaType() + "]"; + + ", desc=" + desc + ", mediaId=" + mediaId + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Voice.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Voice.java similarity index 62% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Voice.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Voice.java index 9b4951f4..578ad929 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/model/Voice.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Voice.java @@ -1,6 +1,5 @@ -package com.foxinmy.weixin4j.msg.model; +package com.foxinmy.weixin4j.tuple; -import com.foxinmy.weixin4j.type.MediaType; /** * 语音对象 @@ -14,11 +13,16 @@ import com.foxinmy.weixin4j.type.MediaType; * @since JDK 1.7 * @see */ -public class Voice extends Image implements Responseable, Notifyable, Massable { +public class Voice extends Image implements ResponseTuple, NotifyTuple { private static final long serialVersionUID = 8853054484809101524L; + @Override + public String getMessageType() { + return "voice"; + } + public Voice(String mediaId) { - super(MediaType.voice, mediaId); + super(mediaId); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java deleted file mode 100644 index c83620d6..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.foxinmy.weixin4j.type; - - -/** - * 账号类型 - * - * @className AccountType - * @author jy - * @date 2014年11月18日 - * @since JDK 1.7 - * @see - */ -public enum AccountType { - /** - * 公众号 - */ - MP, - /** - * 企业号 - */ - QY; -} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/EventType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/EventType.java index 5c563cd5..860adab2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/EventType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/EventType.java @@ -1,21 +1,5 @@ package com.foxinmy.weixin4j.type; -import com.foxinmy.weixin4j.msg.event.BatchjobresultMessage; -import com.foxinmy.weixin4j.msg.event.EnterAgentEventMessage; -import com.foxinmy.weixin4j.msg.event.EventMessage; -import com.foxinmy.weixin4j.msg.event.KfCloseEventMessage; -import com.foxinmy.weixin4j.msg.event.KfCreateEventMessage; -import com.foxinmy.weixin4j.msg.event.KfSwitchEventMessage; -import com.foxinmy.weixin4j.msg.event.LocationEventMessage; -import com.foxinmy.weixin4j.msg.event.MassEventMessage; -import com.foxinmy.weixin4j.msg.event.ScanEventMessage; -import com.foxinmy.weixin4j.msg.event.ScribeEventMessage; -import com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage; -import com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage; -import com.foxinmy.weixin4j.msg.event.menu.MenuLocationEventMessage; -import com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage; -import com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage; - /** * 事件类型 * @@ -29,125 +13,65 @@ public enum EventType { /** * 关注事件 * - * @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage */ - subscribe(ScribeEventMessage.class), + subscribe, /** * 取消关注事件 * - * @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage */ - unsubscribe(ScribeEventMessage.class), - /** - * 二维码扫描事件 - * - * @see com.foxinmy.weixin4j.msg.event.ScanEventMessage - */ - scan(ScanEventMessage.class), + unsubscribe, /** * 上报地理位置事件 * * @see com.foxinmy.weixin4j.msg.event.LocationEventMessage */ - location(LocationEventMessage.class), + location, /** * 菜单扫描事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage */ - scancode_push(MenuScanEventMessage.class), + scancode_push, /** * 菜单点击关键字事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage */ - view(MenuEventMessage.class), + view, /** * 菜单点击链接事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage */ - click(MenuEventMessage.class), + click, /** * 菜单扫描并调出等待界面事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage */ - scancode_waitmsg(MenuScanEventMessage.class), + scancode_waitmsg, /** * 菜单弹出拍照事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage */ - pic_sysphoto(MenuPhotoEventMessage.class), + pic_sysphoto, /** * 菜单弹出发图事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage */ - pic_photo_or_album(MenuPhotoEventMessage.class), + pic_photo_or_album, /** * 菜单弹出发图事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage */ - pic_weixin(MenuPhotoEventMessage.class), + pic_weixin, /** * 菜单发送地理位置事件 * * @see com.foxinmy.weixin4j.msg.event.menu.MenuLocationEventMessage */ - location_select(MenuLocationEventMessage.class), - /** - * 群发消息事件 - * - * @see com.foxinmy.weixin4j.msg.event.MassEventMessage - */ - masssendjobfinish(MassEventMessage.class), - /** - * 模板消息事件 - * - * @see com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage - */ - templatesendjobfinish(TemplatesendjobfinishMessage.class), - /** - * 进入企业号应用事件 - * - * @see com.foxinmy.weixin4j.msg.event.EnterAgentEventMessage - */ - enter_agent(EnterAgentEventMessage.class), - /** - * 客服接入会话事件 - * - * @see com.foxinmy.weixin4j.msg.event.KfCreateEventMessage - */ - kf_create_session(KfCreateEventMessage.class), - /** - * 客服关闭会话事件 - * - * @see com.foxinmy.weixin4j.msg.event.KfCloseEventMessage - */ - kf_close_session(KfCloseEventMessage.class), - /** - * 客服转接会话事件 - * - * @see com.foxinmy.weixin4j.msg.event.KfSwitchEventMessage - */ - kf_switch_session(KfSwitchEventMessage.class), - /** - * 异步任务完成事件 - * - * @see com.foxinmy.weixin4j.msg.event.BatchjobresultMessage - */ - batch_job_result(BatchjobresultMessage.class); - - private Class eventClass; - - EventType(Class eventClass) { - this.eventClass = eventClass; - } - - public Class getEventClass() { - return eventClass; - } + location_select; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java index 36338a1d..b4195132 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java @@ -3,17 +3,13 @@ package com.foxinmy.weixin4j.type; /** * 上传的媒体类型
*

- * 公众平台上传限制:
- * 图片(image): 128K,支持JPG格式
- * 语音(voice):256K,播放长度不超过60s,支持AMR\MP3格式
- * 视频(video):1MB,支持MP4格式
+ * 公众平台上传限制:
图片(image): 128K,支持JPG格式
+ * 语音(voice):256K,播放长度不超过60s,支持AMR\MP3格式
视频(video):1MB,支持MP4格式
* 缩略图(thumb):64KB,支持JPG格式
*

*

- * 企业号上传限制:
- * 图片(image):1MB,支持JPG格式
- * 语音(voice):2MB,播放长度不超过60s,支持AMR格式
- * 视频(video):10MB,支持MP4格式
+ * 企业号上传限制:
图片(image):1MB,支持JPG格式
+ * 语音(voice):2MB,播放长度不超过60s,支持AMR格式
视频(video):10MB,支持MP4格式
* 普通文件(file):10MB
*

*

@@ -25,8 +21,7 @@ package com.foxinmy.weixin4j.type; * @since JDK 1.7 */ public enum MediaType { - image("jpg"), voice("amr/mp3"), video("mp4"), thumb("jpg"), file("unknown"), text( - ""), music(""), news(""), mpnews(""), mpvideo(""), transfer_customer_service( + image("jpg"), voice("amr/mp3"), video("mp4"), thumb("jpg"), file("unknown"), news( ""); MediaType(String formatName) { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MessageType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MessageType.java index 5b5b9eef..c671db22 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MessageType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MessageType.java @@ -1,13 +1,5 @@ package com.foxinmy.weixin4j.type; -import com.foxinmy.weixin4j.model.BaseMsg; -import com.foxinmy.weixin4j.msg.ImageMessage; -import com.foxinmy.weixin4j.msg.LinkMessage; -import com.foxinmy.weixin4j.msg.LocationMessage; -import com.foxinmy.weixin4j.msg.TextMessage; -import com.foxinmy.weixin4j.msg.VideoMessage; -import com.foxinmy.weixin4j.msg.VoiceMessage; -import com.foxinmy.weixin4j.msg.event.EventMessage; /** * @@ -22,56 +14,47 @@ public enum MessageType { * * @see com.foxinmy.weixin4j.msg.TextMessage */ - text(TextMessage.class), + text, /** * 图片消息 * * @see com.foxinmy.weixin4j.msg.ImageMessage */ - image(ImageMessage.class), + image, /** * 语音消息 * * @see com.foxinmy.weixin4j.msg.VoiceMessage */ - voice(VoiceMessage.class), + voice, /** * 视频消息 * * @see com.foxinmy.weixin4j.msg.VideoMessage */ - video(VideoMessage.class), + video, /** * 小视频消息 * * @see com.foxinmy.weixin4j.msg.VideoMessage */ - shortvideo(VideoMessage.class), + shortvideo, /** * 位置消息 * * @see com.foxinmy.weixin4j.msg.LocationMessage */ - location(LocationMessage.class), + location, /** * 链接消息 * * @see com.foxinmy.weixin4j.msg.LinkMessage */ - link(LinkMessage.class), + link, /** * 事件消息 * * @see com.foxinmy.weixin4j.msg.event.EventMessage */ - event(EventMessage.class); - private Class messageClass; - - MessageType(Class messageClass) { - this.messageClass = messageClass; - } - - public Class getMessageClass() { - return messageClass; - } + event; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java index eb932aee..da4de144 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java @@ -6,8 +6,6 @@ import java.util.Set; import com.alibaba.fastjson.JSON; import com.foxinmy.weixin4j.model.WeixinAccount; -import com.foxinmy.weixin4j.model.WeixinMpAccount; -import com.foxinmy.weixin4j.model.WeixinQyAccount; /** * 商户配置工具类 @@ -62,16 +60,8 @@ public class ConfigUtil { CLASSPATH_VALUE)).getPath(); } - public static T getWeixinAccount(Class clazz) { + public static WeixinAccount getWeixinAccount() { String text = getValue("account"); - return JSON.parseObject(text, clazz); - } - - public static WeixinMpAccount getWeixinMpAccount() { - return getWeixinAccount(WeixinMpAccount.class); - } - - public static WeixinQyAccount getWeixinQyAccount() { - return getWeixinAccount(WeixinQyAccount.class); + return JSON.parseObject(text, WeixinAccount.class); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java index 96dc5a57..8399a993 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java @@ -1,6 +1,5 @@ package com.foxinmy.weixin4j.util; -import java.io.InputStream; import java.util.Arrays; import javax.crypto.Cipher; @@ -9,18 +8,9 @@ import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.io.SAXReader; import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.model.Consts; -import com.foxinmy.weixin4j.type.EventType; -import com.foxinmy.weixin4j.type.MessageType; -import com.foxinmy.weixin4j.xml.XmlStream; /** * 消息工具类 @@ -165,62 +155,4 @@ public class MessageUtil { } return xmlContent; } - - /** - * xml消息转换为消息对象 - * - * @param xmlMsg - * 消息字符串 - * @return 消息对象 - * @throws DocumentException - * @see 验证消息的合法性 - * @see 普通消息 - * @see 事件消息 - * @see com.foxinmy.weixin4j.type.MessageType - * @see com.feican.weixin.msg.BaeMessage - * @see com.foxinmy.weixin4j.msg.TextMessage - * @see com.foxinmy.weixin4j.msg.ImageMessage - * @see com.foxinmy.weixin4j.msg.VoiceMessage - * @see com.foxinmy.weixin4j.msg.VideoMessage - * @see com.foxinmy.weixin4j.msg.LocationMessage - * @see com.foxinmy.weixin4j.msg.LinkMessage - * @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage - * @see com.foxinmy.weixin4j.msg.event.ScanEventMessage - * @see com.foxinmy.weixin4j.msg.event.LocationEventMessage - * @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage - */ - public static BaseMsg xml2msg(String xmlMsg) throws DocumentException { - Document doc = DocumentHelper.parseText(xmlMsg); - String type = doc.selectSingleNode("/xml/MsgType").getStringValue(); - if (StringUtils.isBlank(type)) { - return null; - } - MessageType messageType = MessageType.valueOf(type.toLowerCase()); - Class messageClass = messageType.getMessageClass(); - if (messageType == MessageType.event) { - type = doc.selectSingleNode("/xml/Event").getStringValue(); - messageClass = EventType.valueOf(type.toLowerCase()) - .getEventClass(); - } - return XmlStream.get(xmlMsg, messageClass); - } - - /** - * xml消息转换为消息对象 - * - * @param inputStream - * 带消息字符串的输入流 - * @return 消息对象 - * @throws DocumentException - * @see {@link com.foxinmy.weixin4j.util.MessageUtil#xml2msg(String)} - */ - public static BaseMsg xml2msg(InputStream inputStream) - throws DocumentException { - SAXReader reader = new SAXReader(); - Document doc = reader.read(inputStream); - return xml2msg(doc.asXML()); - } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java index 93baaf7b..64591ae1 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/TextConverter.java @@ -1,6 +1,6 @@ package com.foxinmy.weixin4j.xml; -import com.foxinmy.weixin4j.msg.model.Text; +import com.foxinmy.weixin4j.tuple.Text; import com.thoughtworks.xstream.converters.SingleValueConverter; /** diff --git a/weixin4j-mp/README.md b/weixin4j-mp/README.md index 47677ecd..ab9562d8 100644 --- a/weixin4j-mp/README.md +++ b/weixin4j-mp/README.md @@ -6,55 +6,48 @@ weixin4j-mp 功能列表 ------- -* **weixin4j-mp-api** - + MediaApi `上传/下载媒体文件API` - - + NotifyApi `客服消息API` - - + CustomApi `多客服API` - - + MassApi `群发消息API` - - + UserApi `用户管理API` - - + GroupApi `分组管理API` - - + MenuApi `底部菜单API` - - + QrApi `二维码API` - - + TmplApi `模板消息API` - - + HelperApi `辅助API` - - + Pay2Api `V2支付API` - - + Pay3Api `V3支付API` - - + CouponApi `代金券API` - - + DataApi `数据统计API` - - + OauthApi `oauth授权API` - - + CashApi `现金API` +* MediaApi `上传/下载媒体文件API` -* **weixin4j-mp-server** +* NotifyApi `客服消息API` - + `netty服务器` & `消息分发` +* CustomApi `多客服API` + +* MassApi `群发消息API` + +* UserApi `用户管理API` + +* GroupApi `分组管理API` + +* MenuApi `底部菜单API` + +* QrApi `二维码API` + +* TmplApi `模板消息API` + +* HelperApi `辅助API` + +* Pay2Api `V2支付API` - + 被动消息`AES`加密、解密 +* Pay3Api `V3支付API` -项目说明 -------- -1.`weixin4j-mp`包含「微信公众平台」的API封装以及一个半成品的netty服务实现. +* CouponApi `代金券API` -2.API的成功调用依赖于正确的appid等数据,创建(或者copy项目里面的)一个名为**weixin.properties**的资源文件放在自己工程中的classpath下. +* DataApi `数据统计API` -| 属性名 | 说明 | -| :---------- | :-------------- | -| account | 微信公众号信息 `json格式` | +* OauthApi `oauth授权API` + +* CashApi `现金API` + +如何使用 +-------- +1.API工程可以单独打包到其他项目中使用,需新增或拷贝`weixin.properties`文件到项目的`classpath`中 + +weixin.properties说明 + +| 属性名 | 说明 | +| :---------- | :-------------- | +| account | 微信公众号信息 `json格式` | | token_path | 使用FileTokenHolder时token保存的物理路径 | | qr_path | 调用二维码接口时保存二维码图片的物理路径 | | media_path | 调用媒体接口时保存媒体文件的物理路径 | @@ -84,148 +77,19 @@ weixin4j-mp #微信登陆授权的重定向路径 redirect_uri=http://xxx -3.在项目根目录下执行`mvn package -Prelease`命令后得到jar包,将`weixin4j-mp-full`包或者`weixin4j-base`和`weixin4j-mp-api`两个包引入到自己的工程. +2.实例化一个`WeixinProxy`对象,调用API,需要强调的是如果只传入appid,appsecret两个参数将无法调用支付相关接口 WeixinProxy weixinProxy = new WeixinProxy(); // weixinProxy = new WeixinProxy(appid,appsecret); // weixinProxy = new WeixinProxy(weixinAccount); weixinProxy.getUser(openId); -4.如需使用netty服务,则可以在相应的action中实现自己的业务处理,打包后放到`正确的目录`下解压`weixin-*-server-bin.zip`执行`sh startup.sh start`便可启动服务. +3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`,默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`. - @ActionAnnotation(msgType = MessageType.text) - public class TextAction extends AbstractAction { + WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder()); + // weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount)); + +4.`mvn package`. - @Override - public ResponseMessage execute(TextMessage inMessage) { - return new ResponseMessage(new Text("Hello World!"), inMessage); - } - } - -更新LOG -------- -* 2014-10-27 - - + 用netty构建http服务器&消息分发 - -* 2014-10-28 - - + 调整`ActionMapping`抽象化 - -* 2014-10-31 - - + `weixin.properties`切分为API调用地址和公众号appid等信息两部分 - -* 2014-11-03 - - + `weixin-mp`分离为`weixin4j-mp-api`和`weixin4j-mp-server`两个工程 - - + **weixin4j-mp**: 新增`支付`模块 - -* 2014-11-06 - - + **weixin4j-mp-api**: 新增V3版本`退款接口` - -* 2014-11-08 - - + **weixin4j-mp-api**: 新增V2版本`退款申请`、`退款查询`、`对账单下载`三个接口 - - + **weixin4j-mp-api**: 新增一个简单的`语义理解`接口 - -* 2014-11-11 - - + **weixin4j-mp-api**: 自定义`assembly`将`weixin4j-base`工程也一起打包(`weixin4j-mp-api-full.jar`) - -* 2014-11-15 - - + **weixin4j-mp-api**: 新增获取`微信服务器IP地址接口` - - + **weixin4j-mp-server**: 解决`server工程`打包后不能运行问题(`ClassUtil`无法获取jar包里面的类) - - + **weixin4j-mp-server**: 新增被动消息的`加密`以及回复消息的`解密` - -* 2014-11-16 - - + **weixin4j-mp-api**: 新增`多客服`接口 - -* 2014-11-17 - - + **weixin4j-mp-api**: 新增`冲正`和`被扫支付`接口 - -* 2014-11-23 - - + **weixin4j-mp-api**: 重新定义(手贱)了「被动消息」「客服消息」「群发消息」的传输实体 - - + **weixin4j-mp-server**: `WeixinServerBootstrap`重命名为`WeixinMpServerBootstrap` - -* 2014-12-12 - - + **weixin4j-mp-api**: 新增设置`模板消息所处行业`、`获取模板消息ID`接口 - -* 2014-12-16 - - + **weixin4j-mp-api**: 调整方法上@see注解的文档说明接口url - - + **weixin4j-mp-api**: 新增群发消息预览、状态查询接口 - - + **weixin4j-mp-api**: 新增多客服添加账号、更新账号、上传头像、删除账号接口 - -* 2015-01-04 - - + **weixin4j-mp-api**: 支付模块拆分为V2跟V3,新增WeixinPayProxy类 - - + **weixin4j-mp-api**: 退款相关类拆分为V2跟V3 - - + **weixin4j-mp-api**: 新增接口上报接口 - -* 2015-01-31 - - + **weixin4j-mp-api**: 新增数据分析接口 - -* 2015-03-06 - - + **weixin4j-mp-api**: 新增oauth授权接口 - -* 2015-03-21 - - + **weixin4j-mp-api**: 新增群发消息给所有人接口 - - + **weixin4j-mp-api**: 新增素材管理多个接口 - - + **weixin4j-mp-api**: 新增多客服会话管理多个接口 - -* 2015-03-25 - - + **weixin4j-mp-api**: 根据《微信商户平台文档》修缮[Pay3Api](./weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类 - - + **weixin4j-mp-server**: 新增客服创建、关闭、转接会话事件 - - + **weixin4j-mp-server**: 新增deploy.xml远程部署ant脚本 - -* 2015-03-29 - - + **weixin4j-mp-api**: 单行注释调整为多行文档注释 - - + **weixin4j-mp-api**: 新增[CouponApi](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口 - -* 2015-04-01 - - + **weixin4j-mp-api**: 新增[CashApi](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口 - -* 2015-04-13 - - + **weixin4j-mp-api**: 新增WeixinTokenCreator与WeixinJSTicketCreator类 - - + **weixin4j-mp-api**: 新增用户分组批量移动、删除组别接口 - -* 2015-04-16 - - + **weixin4j-mp-api**: 调整[二维码参数](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类 - - + **weixin4j-mp-api**: 新增获取[自定义菜单配置、自动回复配置](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口 - -* 2015-04-18 - - + **weixin4j-mp-api**: 调整[客服接口](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名 - - + **weixin4j-mp-api**: 在[二维码接口](./weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法 \ No newline at end of file +[更新LOG](./CHANGE.md) +---------------------- \ No newline at end of file diff --git a/weixin4j-mp/pom.xml b/weixin4j-mp/pom.xml index 8c0f92ad..dc96f5a8 100644 --- a/weixin4j-mp/pom.xml +++ b/weixin4j-mp/pom.xml @@ -8,11 +8,58 @@ weixin4j-mp weixin4j-mp - pom https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp - 微信公众平台工具包 - - weixin4j-mp-api - weixin4j-mp-server - + 微信公众平台API + + + + org.apache.maven.plugins + maven-assembly-plugin + + weixin4j-mp-${project.version} + + + + + + + com.foxinmy + weixin4j-base + ${project.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + commons-codec + commons-codec + + + dom4j + dom4j + + + + + org.jsoup + jsoup + ${jsoup.version} + + + org.slf4j + slf4j-api + ${jcl.over.version} + + + jaxen + jaxen + ${jaxen.version} + + + junit + junit + + \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCloseEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCloseEventMessage.java similarity index 81% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCloseEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCloseEventMessage.java index e708d505..3566db4d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCloseEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCloseEventMessage.java @@ -1,6 +1,7 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -18,7 +19,7 @@ public class KfCloseEventMessage extends EventMessage { private static final long serialVersionUID = 3644449346935205541L; public KfCloseEventMessage() { - super(EventType.kf_close_session); + super(EventType.kf_close_session.name()); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCreateEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCreateEventMessage.java similarity index 81% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCreateEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCreateEventMessage.java index 4061bc84..aca1de86 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfCreateEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfCreateEventMessage.java @@ -1,6 +1,7 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -18,7 +19,7 @@ public class KfCreateEventMessage extends EventMessage { private static final long serialVersionUID = -8968189700999202108L; public KfCreateEventMessage() { - super(EventType.kf_create_session); + super(EventType.kf_create_session.name()); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfSwitchEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfSwitchEventMessage.java similarity index 84% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfSwitchEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfSwitchEventMessage.java index 9016d13b..d004275d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/KfSwitchEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/KfSwitchEventMessage.java @@ -1,6 +1,7 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -18,7 +19,7 @@ public class KfSwitchEventMessage extends EventMessage { private static final long serialVersionUID = 4319501074109623413L; public KfSwitchEventMessage() { - super(EventType.kf_switch_session); + super(EventType.kf_switch_session.name()); } /** * 来自的客服账号 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/MassEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/MassEventMessage.java similarity index 95% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/MassEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/MassEventMessage.java index c99b4142..8f915add 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/MassEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/MassEventMessage.java @@ -1,9 +1,10 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; import java.util.HashMap; import java.util.Map; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamOmitField; @@ -22,7 +23,7 @@ public class MassEventMessage extends EventMessage { private static final long serialVersionUID = -1660543255873723895L; public MassEventMessage() { - super(EventType.masssendjobfinish); + super(EventType.masssendjobfinish.name()); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScanEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScanEventMessage.java similarity index 81% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScanEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScanEventMessage.java index 17651ed0..497a55bd 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScanEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScanEventMessage.java @@ -1,6 +1,7 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -18,10 +19,10 @@ public class ScanEventMessage extends EventMessage { private static final long serialVersionUID = 8078674062833071562L; public ScanEventMessage() { - super(EventType.scan); + super(EventType.scan.name()); } - public ScanEventMessage(EventType eventType) { + public ScanEventMessage(String eventType) { super(eventType); } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScribeEventMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScribeEventMessage.java similarity index 64% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScribeEventMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScribeEventMessage.java index b913ce34..0974dd8e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/ScribeEventMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/ScribeEventMessage.java @@ -1,4 +1,4 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; import com.foxinmy.weixin4j.type.EventType; @@ -11,17 +11,13 @@ import com.foxinmy.weixin4j.type.EventType; * @since JDK 1.7 * @see 订阅号、服务号的关注/取消关注事件 - * @see 企业号的关注/取消关注 - * 事 件 */ public class ScribeEventMessage extends ScanEventMessage { private static final long serialVersionUID = -6846321620262204915L; public ScribeEventMessage() { - super(EventType.subscribe); + super(EventType.subscribe.name()); } @Override diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/TemplatesendjobfinishMessage.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/TemplatesendjobfinishMessage.java similarity index 81% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/TemplatesendjobfinishMessage.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/TemplatesendjobfinishMessage.java index 0e90eff7..7d5b98a8 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/event/TemplatesendjobfinishMessage.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/event/TemplatesendjobfinishMessage.java @@ -1,6 +1,7 @@ -package com.foxinmy.weixin4j.msg.event; +package com.foxinmy.weixin4j.mp.event; -import com.foxinmy.weixin4j.type.EventType; +import com.foxinmy.weixin4j.message.event.EventMessage; +import com.foxinmy.weixin4j.mp.type.EventType; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -18,7 +19,7 @@ public class TemplatesendjobfinishMessage extends EventMessage { private static final long serialVersionUID = -2903359365988594012L; public TemplatesendjobfinishMessage() { - super(EventType.templatesendjobfinish); + super(EventType.templatesendjobfinish.name()); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/WeixinMpAccount.java similarity index 83% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java rename to weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/WeixinMpAccount.java index f20b540b..4822d510 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/WeixinMpAccount.java @@ -1,9 +1,8 @@ -package com.foxinmy.weixin4j.model; +package com.foxinmy.weixin4j.mp.model; import org.apache.commons.lang3.StringUtils; -import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.type.AccountType; +import com.foxinmy.weixin4j.model.WeixinAccount; /** * 微信公众平台信息 @@ -130,10 +129,14 @@ public class WeixinMpAccount extends WeixinAccount { /** * 商户平台版本(V3)字段 * - * @param appId 公众号唯一的身份ID - * @param appSecret 调用接口的凭证 - * @param paySignKey 支付密钥字符串 - * @param mchId 微信支付分配的商户号 + * @param appId + * 公众号唯一的身份ID + * @param appSecret + * 调用接口的凭证 + * @param paySignKey + * 支付密钥字符串 + * @param mchId + * 微信支付分配的商户号 */ public WeixinMpAccount(String appId, String appSecret, String paySignKey, String mchId) { @@ -145,11 +148,16 @@ public class WeixinMpAccount extends WeixinAccount { /** * V2版本字段 * - * @param appId 公众号唯一的身份ID - * @param appSecret 调用接口的凭证 - * @param paySignKey 支付密钥字符串 - * @param partnerId 财付通账号的ID - * @param partnerKey 财付通账号的key + * @param appId + * 公众号唯一的身份ID + * @param appSecret + * 调用接口的凭证 + * @param paySignKey + * 支付密钥字符串 + * @param partnerId + * 财付通账号的ID + * @param partnerKey + * 财付通账号的key */ public WeixinMpAccount(String appId, String appSecret, String paySignKey, String partnerId, String partnerKey) { @@ -159,12 +167,6 @@ public class WeixinMpAccount extends WeixinAccount { this.partnerKey = partnerKey; } - @Override - @JSONField(deserialize = false) - public AccountType getAccountType() { - return AccountType.MP; - } - @Override public String toString() { return "WeixinMpAccount [openId=" + openId + ", paySignKey=" diff --git a/weixin4j-mp/weixin4j-mp-api/.gitignore b/weixin4j-mp/weixin4j-mp-api/.gitignore deleted file mode 100644 index 87bd9366..00000000 --- a/weixin4j-mp/weixin4j-mp-api/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -*~ - -# eclipse ignore -*.settings/* -/.project -/.classpath -/.tomcatplugin - -# idea ignore -/.idea -*.iml - -# maven ignore -target/* - -# other ignore -*.log -*.tmp -Thumbs.db -/target/ -.DS_Store diff --git a/weixin4j-mp/weixin4j-mp-api/README.md b/weixin4j-mp/weixin4j-mp-api/README.md deleted file mode 100644 index aa9ef265..00000000 --- a/weixin4j-mp/weixin4j-mp-api/README.md +++ /dev/null @@ -1,206 +0,0 @@ -weixin4j-mp-api -=============== - -[微信公众平台](http://mp.weixin.qq.com/wiki)开发工具包 ----------------------------------------------------- - -功能列表 -------- - -* MediaApi `上传/下载媒体文件API` - -* NotifyApi `客服消息API` - -* CustomApi `多客服API` - -* MassApi `群发消息API` - -* UserApi `用户管理API` - -* GroupApi `分组管理API` - -* MenuApi `底部菜单API` - -* QrApi `二维码API` - -* TmplApi `模板消息API` - -* HelperApi `辅助API` - -* Pay2Api `V2支付API` - -* Pay3Api `V3支付API` - -* CouponApi `代金券API` - -* DataApi `数据统计API` - -* OauthApi `oauth授权API` - -* CashApi `现金API` - -如何使用 --------- -1.API工程可以单独打包到其他项目中使用,需新增或拷贝`weixin.properties`文件到项目的`classpath`中 - -weixin.properties说明 - -| 属性名 | 说明 | -| :---------- | :-------------- | -| account | 微信公众号信息 `json格式` | -| token_path | 使用FileTokenHolder时token保存的物理路径 | -| qr_path | 调用二维码接口时保存二维码图片的物理路径 | -| media_path | 调用媒体接口时保存媒体文件的物理路径 | -| bill_path | 调用下载对账单接口保存excel文件的物理路径 | -| ca_file | 调用某些接口(支付相关)强制需要auth的ca授权文件 | -| redirect_uri | 调用OauthApi接口时需要填写的重定向路径 | - -示例(properties中换行用右斜杆\\) - - account={"id":"appId","secret":"appSecret",\ - "token":"开放者的token",\ - "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入",\ - "mchId":"V3.x版本下的微信商户号",\ - "partnerId":"V2版本下的财付通的商户号",\ - "partnerKey":"V2版本下的财付通商户权限密钥Key",\ - "version":"针对微信支付的版本号(2,3),如果不填则按照mchId非空与否来判断",\ - "paySignKey":"微信支付中调用API的密钥"} - - token_path=/tmp/weixin/token - qr_path=/tmp/weixin/qr - media_path=/tmp/weixin/media - bill_path=/tmp/weixin/bill - # ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12) - ca_file=/tmp/weixin/xxxxx.p12 - #classpath路径下:ca_file=classpath:xxxxx.p12 - - #微信登陆授权的重定向路径 - redirect_uri=http://xxx - -2.实例化一个`WeixinProxy`对象,调用API,需要强调的是如果只传入appid,appsecret两个参数将无法调用支付相关接口 - - WeixinProxy weixinProxy = new WeixinProxy(); - // weixinProxy = new WeixinProxy(appid,appsecret); - // weixinProxy = new WeixinProxy(weixinAccount); - weixinProxy.getUser(openId); - -3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`,默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`. - - WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder()); - // weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount)); - -4.`mvn package`. - -更新LOG -------- -* 2014-10-27 - - + 用netty构建http服务器&消息分发 - -* 2014-10-28 - - + 调整`ActionMapping`抽象化 - -* 2014-10-31 - - + `weixin.properties`切分为API调用地址和公众号appid等信息两部分 - -* 2014-11-03 - - + 分离为`weixin-mp-api`和`weixin-mp-server`两个工程 - - + 新增`支付模块` - -* 2014-11-06 - - + 新增V3版本`退款申请`接口 - -* 2014-11-08 - - + 新增V2版本`退款申请`、`退款查询`、`对账单下载`三个接口 - - + 新增一个简单的`语义理解`接口 - -* 2014-11-11 - - + 自定义`assembly`将`weixin4j-base`工程也一起打包(`weixin4j-mp-api-full.jar`) - -* 2014-11-15 - - + 新增获取`微信服务器IP地址接口` - -* 2014-11-16 - - + 新增`多客服`接口 - -* 2014-11-17 - - + 新增`冲正`和`被扫支付`接口 - -* 2014-12-12 - - + 新增设置`模板消息所处行业`、`获取模板消息ID`接口 - -* 2014-12-16 - - + 调整方法上@see注解的文档说明接口url - - + 新增群发消息预览、状态查询接口 - - + 新增多客服添加账号、更新账号、上传头像、删除账号接口 - -* 2015-01-04 - - + 支付模块拆分为V2跟V3,新增WeixinPayProxy类 - - + 退款相关类拆分为V2跟V3 - - + 新增接口上报接口 - -* 2015-01-31 - - + 新增数据分析接口 - -* 2015-03-06 - - + 新增oauth授权接口 - -* 2015-03-21 - - + 新增群发消息给所有人接口 - - + 新增素材管理多个接口 - - + 新增多客服会话管理多个接口 - -* 2015-03-25 - - + 根据《微信商户平台文档》修缮[Pay3Api](./src/main/java/com/foxinmy/weixin4j/mp/api/Pay3Api.java)类 - -* 2015-03-29 - - + 单行注释调整为多行文档注释 - - + 新增[CouponApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CouponApi.java)代金券接口 - -* 2015-04-01 - - + 新增[CashApi](./src/main/java/com/foxinmy/weixin4j/mp/api/CashApi.java)发红包、企业付款接口 - -* 2015-04-13 - - + 新增WeixinTokenCreator与WeixinJSTicketCreator类 - - + 新增用户分组批量移动、删除组别接口 - -* 2015-04-16 - - + **weixin4j-mp-api**: 调整[二维码参数](./src/main/java/com/foxinmy/weixin4j/mp/model/QRParameter.java)类 - - + **weixin4j-mp-api**: 新增获取[自定义菜单配置、自动回复配置](./src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java)接口 - -* 2015-04-18 - - + 调整[客服接口](./src/main/java/com/foxinmy/weixin4j/mp/api/CustomApi.java)类的方法名 - - + 在[二维码接口](./src/main/java/com/foxinmy/weixin4j/mp/api/QRApi.java)类新增获取二维码url方法 \ No newline at end of file diff --git a/weixin4j-mp/weixin4j-mp-api/pom.xml b/weixin4j-mp/weixin4j-mp-api/pom.xml deleted file mode 100644 index b4bd7c29..00000000 --- a/weixin4j-mp/weixin4j-mp-api/pom.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - 4.0.0 - - com.foxinmy - weixin4j-mp - 1.3 - - weixin4j-mp-api - weixin4j-mp-api - https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-mp-api - 微信公众平台API - - - - org.apache.maven.plugins - maven-assembly-plugin - - weixin4j-mp-${project.version} - - - - - - - com.foxinmy - weixin4j-base - ${project.version} - - - org.apache.poi - poi-ooxml - ${poi.version} - - - commons-codec - commons-codec - - - dom4j - dom4j - - - - - org.jsoup - jsoup - ${jsoup.version} - - - org.slf4j - slf4j-api - ${jcl.over.version} - - - jaxen - jaxen - ${jaxen.version} - - - junit - junit - - - \ No newline at end of file diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/assembly.xml b/weixin4j-mp/weixin4j-mp-api/src/main/assembly.xml deleted file mode 100644 index fde1cf28..00000000 --- a/weixin4j-mp/weixin4j-mp-api/src/main/assembly.xml +++ /dev/null @@ -1,31 +0,0 @@ - - full - - jar - - false - - - target/classes - / - - /** - - - *.properties - *.xml - - - - - - true - - com.foxinmy:weixin4j-base - - - - \ No newline at end of file diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinPayProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinPayProxy.java deleted file mode 100644 index 2dcc4c8d..00000000 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinPayProxy.java +++ /dev/null @@ -1,622 +0,0 @@ -package com.foxinmy.weixin4j.mp; - -import java.io.File; -import java.util.Date; - -import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.JsonResult; -import com.foxinmy.weixin4j.http.XmlResult; -import com.foxinmy.weixin4j.model.WeixinMpAccount; -import com.foxinmy.weixin4j.mp.api.CashApi; -import com.foxinmy.weixin4j.mp.api.CouponApi; -import com.foxinmy.weixin4j.mp.api.Pay2Api; -import com.foxinmy.weixin4j.mp.api.Pay3Api; -import com.foxinmy.weixin4j.mp.api.PayApi; -import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail; -import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult; -import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock; -import com.foxinmy.weixin4j.mp.payment.v3.ApiResult; -import com.foxinmy.weixin4j.mp.payment.v3.MPPayment; -import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult; -import com.foxinmy.weixin4j.mp.payment.v3.Redpacket; -import com.foxinmy.weixin4j.mp.payment.v3.RedpacketSendResult; -import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator; -import com.foxinmy.weixin4j.mp.type.BillType; -import com.foxinmy.weixin4j.mp.type.CurrencyType; -import com.foxinmy.weixin4j.mp.type.IdQuery; -import com.foxinmy.weixin4j.mp.type.IdType; -import com.foxinmy.weixin4j.mp.type.RefundType; -import com.foxinmy.weixin4j.token.FileTokenHolder; -import com.foxinmy.weixin4j.token.TokenHolder; -import com.foxinmy.weixin4j.util.ConfigUtil; - -/** - * 微信支付接口实现 - * - * @className WeixinPayProxy - * @author jy - * @date 2015年1月3日 - * @since JDK 1.7 - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see 商户平台支付API - */ -public class WeixinPayProxy { - - private final PayApi payApi; - private final Pay2Api pay2Api; - private final Pay3Api pay3Api; - private final CouponApi couponApi; - private final CashApi cashApi; - - public WeixinPayProxy() { - this(ConfigUtil.getWeixinMpAccount(), new FileTokenHolder( - new WeixinTokenCreator())); - } - - /** - * WeixinAccount对象 - * - * @param weixinAccount - * 微信账户 - */ - public WeixinPayProxy(WeixinMpAccount weixinAccount, TokenHolder tokenHolder) { - this.pay2Api = new Pay2Api(weixinAccount, tokenHolder); - this.pay3Api = new Pay3Api(weixinAccount, tokenHolder); - int version = weixinAccount.getVersion(); - if (version == 2) { - this.payApi = this.pay2Api; - } else if (version == 3) { - this.payApi = this.pay3Api; - } else { - this.payApi = this.pay3Api; - } - this.couponApi = new CouponApi(weixinAccount); - this.cashApi = new CashApi(weixinAccount); - } - - /** - * 发货通知 - * - * @param openId - * 用户ID - * @param transid - * 交易单号 - * @param outTradeNo - * 订单号 - * @param status - * 成功|失败 - * @param statusMsg - * status为失败时携带的信息 - * @return 发货处理结果 - * @since V2 & V3 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @throws WeixinException - */ - public JsonResult deliverNotify(String openId, String transid, - String outTradeNo, boolean status, String statusMsg) - throws WeixinException { - return payApi.deliverNotify(openId, transid, outTradeNo, status, - statusMsg); - } - - /** - * 维权处理 - * - * @param openId - * 用户ID - * @param feedbackId - * 维权单号 - * @return 调用结果 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @since V2 & V3 - * @throws WeixinException - */ - public JsonResult updateFeedback(String openId, String feedbackId) - throws WeixinException { - return payApi.updateFeedback(openId, feedbackId); - } - - /** - * V2订单查询 - * - * @param idQuery - * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @since V2 - * @see com.foxinmy.weixin4j.mp.payment.v2.Order - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @return 订单详情 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v2.Order orderQueryV2( - String outTradeNo) throws WeixinException { - return pay2Api.orderQuery(new IdQuery(outTradeNo, IdType.TRADENO)); - } - - /** - * V3订单查询 - *

- * 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
调用支付接口后,返回系统错误或未知交易状态情况;
- * 调用被扫支付API,返回USERPAYING的状态;
调用关单或撤销接口API之前,需确认支付状态; - *

- * - * @param idQuery - * 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @since V3 - * @see com.foxinmy.weixin4j.mp.payment.v3.Order - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see 订单查询API - * @return 订单详情 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(IdQuery idQuery) - throws WeixinException { - return pay3Api.orderQuery(idQuery); - } - - /** - * V2申请退款(请求需要双向证书)
- *

- * 交易时间超过 1 年的订单无法提交退款;
支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失 - * 败后重新提交,要采用原来的 out_refund_no。总退款金额不能超过用户实际支付金额。
- *

- * - * @param caFile - * 证书文件(后缀为*.pfx) - * @param idQuery - * ) 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @param refundFee - * 退款总金额,单位为元,可以做部分退款 - * @param opUserId - * 操作员帐号, 默认为商户号 - * @param opUserPasswd - * 操作员密码 - * - * @return 退款申请结果 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundResult - * @since V2 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2( - File caFile, IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, String opUserId, String opUserPasswd) - throws WeixinException { - return pay2Api.refund(caFile, idQuery, outRefundNo, totalFee, - refundFee, opUserId, opUserPasswd); - } - - /** - * V2退款申请采用properties中配置的ca文件 - * - * @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#refundV2(File, IdQuery, String, double, double, String,String)} - */ - public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2( - IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, String opUserId, String opUserPasswd) - throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return refundV2(caFile, idQuery, outRefundNo, totalFee, refundFee, - opUserId, opUserPasswd); - } - - /** - * V2退款申请 - * - * @param caFile - * 证书文件(V2版本后缀为*.pfx) - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @param refundFee - * 退款总金额,单位为元,可以做部分退款 - * @param opUserId - * 操作员帐号, 默认为商户号 - * @param opUserPasswd - * 操作员密码,默认为商户后台登录密码 - * @param recvUserId - * 转账退款接收退款的财付通帐号。 一般无需填写,只有退银行失败,资金转入商 户号现金账号时(即状态为转入代发,查询返 回的 - * refund_status 是 7 或 11),填写原退款 单号并填写此字段,资金才会退到指定财付通 - * 账号。其他情况此字段忽略 - * @param reccvUserName - * 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致) - * @param refundType - * 为空或者填 1:商户号余额退款;2:现金帐号 退款;3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。使用 2 或 - * 3 时,需联系财 付通开通此功能 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundResult - * @return 退款结果 - */ - public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2( - File caFile, IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, String opUserId, String opUserPasswd, - String recvUserId, String reccvUserName, RefundType refundType) - throws WeixinException { - return pay2Api.refund(caFile, idQuery, outRefundNo, totalFee, - refundFee, opUserId, opUserPasswd, recvUserId, reccvUserName, - refundType); - } - - /** - * V2退款查询
退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态 - * - * @param idQuery - * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id - * 四个参数必填一个,优先级为: - * refund_id>out_refund_no>transaction_id>out_trade_no - * @return 退款记录 - * @see com.foxinmy.weixin4j.mp.payment.v2.RefundRecord - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @since V2 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v2.RefundRecord refundQueryV2( - IdQuery idQuery) throws WeixinException { - return pay2Api.refundQuery(idQuery); - } - - /** - * V3申请退款(请求需要双向证书)
- *

- * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后, - * 按照退款规则将支付款按原路退到买家帐号上。 - *

- *

- * 1.交易时间超过半年的订单无法提交退款; - * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交 - * ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 - *

- * - * @param caFile - * 证书文件(后缀为*.p12) - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @param outRefundNo - * 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔 - * @param totalFee - * 订单总金额,单位为元 - * @param refundFee - * 退款总金额,单位为元,可以做部分退款 - * @param refundFeeType - * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY - * @param opUserId - * 操作员帐号, 默认为商户号 - * - * @return 退款申请结果 - * @see com.foxinmy.weixin4j.mp.payment.v3.RefundResult - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see 申请退款API - * @since V3 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3( - File caFile, IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, CurrencyType refundFeeType, String opUserId) - throws WeixinException { - return pay3Api.refund(caFile, idQuery, outRefundNo, totalFee, - refundFee, refundFeeType, opUserId); - } - - /** - * V3退款申请采用properties中配置的ca文件 - * - * @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#refundV3(File, IdQuery, String, double, double,CurrencyType, String)} - */ - public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3( - IdQuery idQuery, String outRefundNo, double totalFee, - double refundFee, String opUserId) throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return pay3Api.refund(caFile, idQuery, outRefundNo, totalFee, - refundFee, CurrencyType.CNY, opUserId); - } - - /** - * V3退款查询 - *

- * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 - *

- * - * @param idQuery - * 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id - * 四个参数必填一个,优先级为: - * refund_id>out_refund_no>transaction_id>out_trade_no - * @return 退款记录 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see com.foxinmy.weixin4j.mp.payment.v3.RefundRecord - * @see 退款查询API - * @since V3 - * @throws WeixinException - */ - public com.foxinmy.weixin4j.mp.payment.v3.RefundRecord refundQueryV3( - IdQuery idQuery) throws WeixinException { - return pay3Api.refundQuery(idQuery); - } - - /** - * 下载对账单
- * 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为 - * REVOKED;
- * 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
- * 3.对账单中涉及金额的字段单位为“元”。
- * - * @param billDate - * 下载对账单的日期 - * @param billType - * 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单 - * REFUND,返回当日退款订单 - * @return excel表格 - * @since V2 & V3 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see 下载对账单API - * @throws WeixinException - */ - public File downloadbill(Date billDate, BillType billType) - throws WeixinException { - return payApi.downloadbill(billDate, billType); - } - - /** - * 冲正订单(需要证书)
当支付返回失败,或收银系统超时需要取消交易,可以调用该接口
接口逻辑:支 - * 付失败的关单,支付成功的撤销支付
7天以内的单可撤销,其他正常支付的单 - * 如需实现相同功能请调用退款接口
调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
- * - * @param ca - * 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12) - * @param idQuery - * 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级: - * transaction_id> out_trade_no - * @return 撤销结果 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @since V3 - * @throws WeixinException - */ - public ApiResult reverse(File caFile, IdQuery idQuery) - throws WeixinException { - return payApi.reverse(caFile, idQuery); - } - - /** - * 冲正撤销:默认采用properties中配置的ca文件 - * - * @param idQuery - * transaction_id、out_trade_no 二选一 - * @return 撤销结果 - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#reverse(File, IdQuery)} - * @throws WeixinException - */ - public ApiResult reverse(IdQuery idQuery) throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return payApi.reverse(caFile, idQuery); - } - - /** - * 关闭订单 - *

- * 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续 - * ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。 - *

- * - * @param outTradeNo - * 商户系统内部的订单号 - * @return 执行结果 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @since V3 - * @throws WeixinException - * @see 关闭订单API - */ - public ApiResult closeOrder(String outTradeNo) throws WeixinException { - return payApi.closeOrder(outTradeNo); - } - - /** - * native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量 - * ,提升扫描速度和精确度。 - * - * @param url - * 具有native标识的支付URL - * @return 转换后的短链接 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay2Api - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see 转换短链接API - * @since V2 & V3 - * @throws WeixinException - */ - public String getPayShorturl(String url) throws WeixinException { - return payApi.getShorturl(url); - } - - /** - * 接口上报 - * - * @param interfaceUrl - * 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q - * q.com/pay/unifiedorder - * @param executeTime - * 接口耗时情况,单位为毫秒 - * @param outTradeNo - * 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。 - * @param ip - * 发起接口调用时的机器 IP - * @param time - * 商户调用该接口时商户自己 系统的时间 - * @param returnXml - * 调用接口返回的基本数据 - * @return 处理结果 - * @see com.foxinmy.weixin4j.mp.api.PayApi - * @see com.foxinmy.weixin4j.mp.api.Pay3Api - * @see 接口测试上报API - * @throws WeixinException - */ - public XmlResult interfaceReport(String interfaceUrl, int executeTime, - String outTradeNo, String ip, Date time, XmlResult returnXml) - throws WeixinException { - return pay3Api.interfaceReport(interfaceUrl, executeTime, outTradeNo, - ip, time, returnXml); - } - - /** - * 发放代金券(需要证书) - * - * @param caFile - * 证书文件(后缀为*.p12) - * @param couponStockId - * 代金券批次id - * @param partnerTradeNo - * 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性 - * @param openId - * 用户的openid - * @param opUserId - * 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空 - * @return 发放结果 - * @see com.foxinmy.weixin4j.mp.api.CouponApi - * @see com.foxinmy.weixin4j.mp.payment.coupon.CouponResult - * @see 发放代金券接口 - * @throws WeixinException - */ - public CouponResult sendCoupon(File caFile, String couponStockId, - String partnerTradeNo, String openId, String opUserId) - throws WeixinException { - return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo, - openId, opUserId); - } - - /** - * 发放代金券采用properties中配置的ca文件 - * - * @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#sendCoupon(File, String, String, String, String)} - */ - public CouponResult sendCoupon(String couponStockId, String partnerTradeNo, - String openId) throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo, - openId, null); - } - - /** - * 查询代金券批次 - * - * @param couponStockId - * 代金券批次ID - * @return 代金券批次信息 - * @see com.foxinmy.weixin4j.mp.api.CouponApi - * @see com.foxinmy.weixin4j.mp.payment.coupon.CouponStock - * @see 查询代金券信息 - * @throws WeixinException - */ - public CouponStock queryCouponStock(String couponStockId) - throws WeixinException { - return couponApi.queryCouponStock(couponStockId); - } - - /** - * 查询代金券详细 - * - * @param couponId - * 代金券ID - * @return 代金券详细信息 - * @see com.foxinmy.weixin4j.mp.api.CouponApi - * @see com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail - * @see 查询代金券详细信息 - * @throws WeixinException - */ - public CouponDetail queryCouponDetail(String couponId) - throws WeixinException { - return couponApi.queryCouponDetail(couponId); - } - - /** - * 发放红包 企业向微信用户个人发现金红包 - * - * @param caFile - * 证书文件(V3版本后缀为*.p12) - * @param redpacket - * 红包信息 - * @return 发放结果 - * @see com.foxinmy.weixin4j.mp.api.CashApi - * @see com.foxinmy.weixin4j.mp.payment.v3.Redpacket - * @see com.foxinmy.weixin4j.mp.payment.v3.RedpacketSendResult - * @see 红包接口说明 - * @throws WeixinException - */ - public RedpacketSendResult sendRedpack(File caFile, Redpacket redpacket) - throws WeixinException { - return cashApi.sendRedpack(caFile, redpacket); - } - - /** - * 发放红包采用properties中配置的ca文件 - * - * @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#sendRedpack(File, Redpacket)} - */ - public RedpacketSendResult sendRedpack(Redpacket redpacket) - throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return cashApi.sendRedpack(caFile, redpacket); - } - - /** - * 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。 - * - * @param caFile - * 证书文件(V3版本后缀为*.p12) - * @param mpPayment - * 付款信息 - * @return 付款结果 - * @see com.foxinmy.weixin4j.mp.api.CashApi - * @see com.foxinmy.weixin4j.mp.payment.v3.MPPayment - * @see com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult - * @see 企业付款 - * @throws WeixinException - */ - public MPPaymentResult mpPayment(File caFile, MPPayment mpPayment) - throws WeixinException { - return cashApi.mpPayment(caFile, mpPayment); - } - - /** - * 企业付款采用properties中配置的ca文件 - * - * @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#mpPayment(File, MPPayment)} - */ - public MPPaymentResult mpPayment(MPPayment mpPayment) - throws WeixinException { - File caFile = new File(ConfigUtil.getClassPathValue("ca_file")); - return cashApi.mpPayment(caFile, mpPayment); - } -} diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java deleted file mode 100644 index a8246e10..00000000 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ /dev/null @@ -1,1328 +0,0 @@ -package com.foxinmy.weixin4j.mp; - -import java.io.File; -import java.io.IOException; -import java.util.Date; -import java.util.List; - -import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.JsonResult; -import com.foxinmy.weixin4j.model.Button; -import com.foxinmy.weixin4j.mp.api.CustomApi; -import com.foxinmy.weixin4j.mp.api.DataApi; -import com.foxinmy.weixin4j.mp.api.GroupApi; -import com.foxinmy.weixin4j.mp.api.HelperApi; -import com.foxinmy.weixin4j.mp.api.MassApi; -import com.foxinmy.weixin4j.mp.api.MediaApi; -import com.foxinmy.weixin4j.mp.api.MenuApi; -import com.foxinmy.weixin4j.mp.api.NotifyApi; -import com.foxinmy.weixin4j.mp.api.QrApi; -import com.foxinmy.weixin4j.mp.api.TmplApi; -import com.foxinmy.weixin4j.mp.api.UserApi; -import com.foxinmy.weixin4j.mp.message.NotifyMessage; -import com.foxinmy.weixin4j.mp.message.TemplateMessage; -import com.foxinmy.weixin4j.mp.model.AutoReplySetting; -import com.foxinmy.weixin4j.mp.model.CustomRecord; -import com.foxinmy.weixin4j.mp.model.Following; -import com.foxinmy.weixin4j.mp.model.Group; -import com.foxinmy.weixin4j.mp.model.KfAccount; -import com.foxinmy.weixin4j.mp.model.KfSession; -import com.foxinmy.weixin4j.mp.model.MediaCounter; -import com.foxinmy.weixin4j.mp.model.MediaItem; -import com.foxinmy.weixin4j.mp.model.MediaRecord; -import com.foxinmy.weixin4j.mp.model.MenuSetting; -import com.foxinmy.weixin4j.mp.model.QRParameter; -import com.foxinmy.weixin4j.mp.model.SemQuery; -import com.foxinmy.weixin4j.mp.model.SemResult; -import com.foxinmy.weixin4j.mp.model.User; -import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator; -import com.foxinmy.weixin4j.mp.type.DatacubeType; -import com.foxinmy.weixin4j.mp.type.IndustryType; -import com.foxinmy.weixin4j.mp.type.Lang; -import com.foxinmy.weixin4j.msg.model.Base; -import com.foxinmy.weixin4j.msg.model.MpArticle; -import com.foxinmy.weixin4j.msg.model.Video; -import com.foxinmy.weixin4j.token.FileTokenHolder; -import com.foxinmy.weixin4j.token.TokenHolder; -import com.foxinmy.weixin4j.type.MediaType; - -/** - * 微信公众平台接口实现 - * - * @className WeixinProxy - * @author jy.hu - * @date 2014年3月23日 - * @since JDK 1.7 - * @see api文档 - */ -public class WeixinProxy { - - private final MediaApi mediaApi; - private final NotifyApi notifyApi; - private final CustomApi customApi; - private final MassApi massApi; - private final UserApi userApi; - private final GroupApi groupApi; - private final MenuApi menuApi; - private final QrApi qrApi; - private final TmplApi tmplApi; - private final HelperApi helperApi; - private final DataApi dataApi; - - /** - * 默认采用文件存放Token信息 - */ - public WeixinProxy() { - this(new FileTokenHolder(new WeixinTokenCreator())); - } - - /** - * - * @param appid - * @param appsecret - */ - public WeixinProxy(String appid, String appsecret) { - this(new FileTokenHolder(new WeixinTokenCreator(appid, appsecret))); - } - - /** - * TokenHolder对象 - * - * @see com.foxinmy.weixin4j.token.TokenHolder - * @param tokenHolder - */ - public WeixinProxy(TokenHolder tokenHolder) { - this.mediaApi = new MediaApi(tokenHolder); - this.notifyApi = new NotifyApi(tokenHolder); - this.customApi = new CustomApi(tokenHolder); - this.massApi = new MassApi(tokenHolder); - this.userApi = new UserApi(tokenHolder); - this.groupApi = new GroupApi(tokenHolder); - this.menuApi = new MenuApi(tokenHolder); - this.qrApi = new QrApi(tokenHolder); - this.tmplApi = new TmplApi(tokenHolder); - this.helperApi = new HelperApi(tokenHolder); - this.dataApi = new DataApi(tokenHolder); - } - - /** - * 上传媒体文件 - * - * @param file - * 媒体对象 - * @param isMaterial - * 是否永久上传 - * @return 上传到微信服务器返回的媒体标识 - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#uploadMedia(File, MediaType)} - * @throws WeixinException - * @throws IOException - */ - public String uploadMedia(File file, boolean isMaterial) - throws WeixinException, IOException { - return mediaApi.uploadMedia(file, isMaterial); - } - - /** - * 上传媒体文件 - * - * @param file - * 文件对象 - * @param mediaType - * 媒体类型 - * @param isMaterial - * 是否永久上传 - * @return 上传到微信服务器返回的媒体标识 - * @throws WeixinException - * @throws IOException - * @see com.foxinmy.weixin4j.type.MediaType - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#uploadMedia(String, byte[],String)} - */ - public String uploadMedia(File file, MediaType mediaType, boolean isMaterial) - throws WeixinException, IOException { - return mediaApi.uploadMedia(file, mediaType, isMaterial); - } - - /** - * 上传媒体文件 - *

- * 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}, - * 否则抛出异常. - *

- * - * @param fileName - * 文件名 - * @param data - * 媒体数据包 - * @param mediaType - * 媒体类型 - * @param isMaterial - * 是否永久上传 - * @return 上传到微信服务器返回的媒体标识 - * @see 上传下载说明 - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @throws WeixinException - */ - public String uploadMedia(String fileName, byte[] data, String mediaType, - boolean isMaterial) throws WeixinException { - return mediaApi.uploadMedia(fileName, data, mediaType, isMaterial); - } - - /** - * 下载媒体文件 - *

- * 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常. - *

- * - * @param mediaId - * 存储在微信服务器上的媒体标识 - * @param mediaType - * 媒体类型 - * @param isMaterial - * 是否永久素材 - * @return 写入硬盘后的文件对象 - * @throws WeixinException - * @see 上传下载说明 - * @see com.foxinmy.weixin4j.type.MediaType - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#downloadMedia(String)} - */ - public File downloadMedia(String mediaId, MediaType mediaType, - boolean isMaterial) throws WeixinException { - return mediaApi.downloadMedia(mediaId, mediaType, isMaterial); - } - - /** - * 下载媒体文件 - * - * @param mediaId - * 媒体ID - * @param isMaterial - * 是否永久素材 - * @return 二进制数据包 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see 上传下载说明 - */ - public byte[] downloadMedia(String mediaId, boolean isMaterial) - throws WeixinException { - return mediaApi.downloadMedia(mediaId, isMaterial); - } - - /** - * 上传永久图文素材 - *

- * 、新增的永久素材也可以在公众平台官网素材管理模块中看到,永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000, - * 其他类型为1000 - *

- * - * @param articles - * 图文列表 - * @return 上传到微信服务器返回的媒体标识 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @see 上传永久媒体素材 - */ - public String uploadMaterialArticle(List articles) - throws WeixinException { - return mediaApi.uploadMaterialArticle(articles); - } - - /** - * 下载永久图文素材 - * - * @param mediaId - * 媒体ID - * @return 图文列表 - * @throws WeixinException - * @see 下载永久媒体素材 - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @see com.foxinmy.weixin4j.mp.api.MediaApi - */ - public List downloadArticle(String mediaId) - throws WeixinException { - return mediaApi.downloadArticle(mediaId); - } - - /** - * 更新永久图文素材 - * - * @param mediaId - * 要修改的图文消息的id - * @param index - * 要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为0 - * @param articles - * 图文列表 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @see 更新永久图文素材 - */ - public JsonResult updateMaterialArticle(String mediaId, int index, - List articles) throws WeixinException { - return mediaApi.updateMaterialArticle(mediaId, index, articles); - } - - /** - * 删除永久媒体素材 - * - * @param mediaId - * 媒体素材的media_id - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see 删除永久媒体素材 - */ - public JsonResult deleteMaterialMedia(String mediaId) - throws WeixinException { - return mediaApi.deleteMaterialMedia(mediaId); - } - - /** - * 上传永久视频素材 - * - * @param file - * 大小不超过1M且格式为MP4的视频文件 - * @param title - * 视频标题 - * @param introduction - * 视频描述 - * @return 上传到微信服务器返回的媒体标识 - * @see 上传永久媒体素材 - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @throws WeixinException - * @throws IOException - */ - public String uploadMaterialVideo(File file, String title, - String introduction) throws WeixinException, IOException { - return mediaApi.uploadMaterialVideo(file, title, introduction); - } - - /** - * 获取永久媒体素材的总数
.图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000 - * - * @return 总数对象 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.model.MediaCounter - * @see 获取素材总数 - * @see com.foxinmy.weixin4j.mp.api.MediaApi - */ - public MediaCounter countMaterialMedia() throws WeixinException { - return mediaApi.countMaterialMedia(); - } - - /** - * 获取媒体素材记录列表 - * - * @param mediaType - * 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news) - * @param offset - * 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回 - * @param count - * 返回素材的数量,取值在1到20之间 - * @return 媒体素材的记录对象 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see com.foxinmy.weixin4j.mp.model.MediaRecord - * @see com.foxinmy.weixin4j.type.MediaType - * @see com.foxinmy.weixin4j.mp.model.MediaItem - * @see 获取素材列表 - */ - public MediaRecord listMaterialMedia(MediaType mediaType, int offset, - int count) throws WeixinException { - return mediaApi.listMaterialMedia(mediaType, offset, count); - } - - /** - * 获取全部的媒体素材 - * - * @param mediaType - * 媒体类型 - * @return 素材列表 - * @see com.foxinmy.weixin4j.mp.api.MediaApi - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#listMaterialMedia(MediaType, int, int)} - * @throws WeixinException - */ - public List listAllMaterialMedia(MediaType mediaType) - throws WeixinException { - return mediaApi.listAllMaterialMedia(mediaType); - } - - /** - * 发送客服消息(在48小时内不限制发送次数) - * - * @param notify - * 客服消息对象 - * @return 处理结果 - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#sendNotify(NotifyMessage,String) } - * @throws WeixinException - */ - public JsonResult sendNotify(NotifyMessage notify) throws WeixinException { - return notifyApi.sendNotify(notify); - } - - /** - * 发送客服消息(在48小时内不限制发送次数) - * - * @param notify - * 客服消息对象 - * @param kfAccount - * 客服账号 可为空 - * @throws WeixinException - * @return 处理结果 - * @see 发送客服消息 - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.Video - * @see com.foxinmy.weixin4j.msg.model.Music - * @see com.foxinmy.weixin4j.msg.model.News - * @see com.foxinmy.weixin4j.mp.api.NotifyApi - */ - public JsonResult sendNotify(NotifyMessage notify, String kfAccount) - throws WeixinException { - return notifyApi.sendNotify(notify, kfAccount); - } - - /** - * 客服聊天记录 - * - * @param openId - * 用户标识 为空时则查询全部记录 - * @param starttime - * 查询开始时间 - * @param endtime - * 查询结束时间 每次查询不能跨日查询 - * @param pagesize - * 每页大小 每页最多拉取50条 - * @param pageindex - * 查询第几页 从1开始 - * @see com.foxinmy.weixin4j.mp.model.CustomRecord - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 查询客服聊天记录 - * @see 查询客服聊天记录 - * @throws WeixinException - */ - public List getCustomRecord(String openId, Date starttime, - Date endtime, int pagesize, int pageindex) throws WeixinException { - return customApi.getCustomRecord(openId, starttime, endtime, pagesize, - pageindex); - } - - /** - * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号 - * - * @param isOnline - * 是否在线 为ture时可以可以获取客服在线状态(手机在线、PC客户端在线、手机和PC客户端全都在线)、客服自动接入最大值、 - * 客服当前接待客户数 - * @return 多客服信息列表 - * @see com.foxinmy.weixin4j.mp.model.KfAccount - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 获取客服基本信息 - * @see 获取客服基本信息 - * @see 获取在线客服接待信息 - * @see 获取在线客服接待信息 - * @throws WeixinException - */ - public List getKfAccountList(boolean isOnline) - throws WeixinException { - return customApi.getKfAccountList(isOnline); - } - - /** - * 新增客服账号 - * - * @param id - * 完整客服账号,格式为:账号前缀@公众号微信号,账号前缀最多10个字符,必须是英文或者数字字符。如果没有公众号微信号, - * 请前往微信公众平台设置。 - * @param name - * 客服昵称,最长6个汉字或12个英文字符 - * @param pwd - * 客服账号登录密码 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 客服管理接口返回码 - * @see 新增客服账号 - */ - public JsonResult addAccount(String id, String name, String pwd) - throws WeixinException { - return customApi.addAccount(id, name, pwd); - } - - /** - * 更新客服账号 - * - * @param id - * 完整客服账号,格式为:账号前缀@公众号微信号,账号前缀最多10个字符,必须是英文或者数字字符。如果没有公众号微信号, - * 请前往微信公众平台设置。 - * @param name - * 客服昵称,最长6个汉字或12个英文字符 - * @param pwd - * 客服账号登录密码 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 客服管理接口返回码 - * @see 新增客服账号 - */ - public JsonResult updateAccount(String id, String name, String pwd) - throws WeixinException { - return customApi.updateAccount(id, name, pwd); - } - - /** - * 上传客服头像 - * - * @param id - * 完整客服账号,格式为:账号前缀@公众号微信号 - * @param headimg - * 头像图片文件必须是jpg格式,推荐使用640*640大小的图片以达到最佳效果 - * @return 处理结果 - * @throws WeixinException - * @throws IOException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 客服管理接口返回码 - * @see 上传客服头像 - */ - public JsonResult uploadAccountHeadimg(String id, File headimg) - throws WeixinException, IOException { - return customApi.uploadAccountHeadimg(id, headimg); - } - - /** - * 删除客服账号 - * - * @param id - * 完整客服账号,格式为:账号前缀@公众号微信号 - * @return 处理结果 - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @throws WeixinException - * @see 客服管理接口返回码 - * @see 删除客服账号 - */ - public JsonResult deleteAccount(String id) throws WeixinException { - return customApi.deleteAccount(id); - } - - /** - * 创建客服会话 - *

- * 开发者可以使用本接口,为多客服的客服工号创建会话,将某个客户直接指定给客服工号接待,需要注意此接口不会受客服自动接入数以及自动接入开关限制。 - * 只能为在线的客服(PC客户端在线,或者已绑定多客服助手)创建会话。 - *

- * - * @param userOpenId - * 用户的userOpenId - * @param kfAccount - * 完整客服账号,格式为:账号前缀@公众号微信号 - * @param text - * 附加信息,文本会展示在客服人员的多客服客户端 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 创建会话 - */ - public JsonResult createKfSession(String userOpenId, String kfAccount, - String text) throws WeixinException { - return customApi.createKfSession(userOpenId, kfAccount, text); - } - - /** - * 关闭客服会话 - * - * @param userOpenId - * 用户的userOpenId - * @param kfAccount - * 完整客服账号,格式为:账号前缀@公众号微信号 - * @param text - * 附加信息,文本会展示在客服人员的多客服客户端 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see 创建会话 - */ - public JsonResult closeKfSession(String userOpenId, String kfAccount, - String text) throws WeixinException { - return customApi.closeKfSession(userOpenId, kfAccount, text); - } - - /** - * 获取客户的会话状态:获取客户当前的会话状态。 - * - * @param userOpenId - * 用户的openid - * @return 会话对象 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see com.foxinmy.weixin4j.mp.model.KfSession - * @see 获取会话状态 - */ - public KfSession getKfSession(String userOpenId) throws WeixinException { - return customApi.getKfSession(userOpenId); - } - - /** - * 获取客服的会话列表:获取某个客服正在接待的会话列表。 - * - * @param kfAccount - * 完整客服账号,格式为:账号前缀@公众号微信号,账号前缀最多10个字符,必须是英文或者数字字符。 - * @return 会话列表 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see com.foxinmy.weixin4j.mp.model.KfSession - * @see 获取客服的会话列表 - */ - public List getKfSessionList(String kfAccount) - throws WeixinException { - return customApi.getKfSessionList(kfAccount); - } - - /** - * 获取未接入会话列表:获取当前正在等待队列中的会话列表,此接口最多返回最早进入队列的100个未接入会话。
缺陷:没有count字段 - * - * @return 会话列表 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.CustomApi - * @see com.foxinmy.weixin4j.mp.model.KfSession - * @see 获取客服的会话列表 - */ - public List getKfSessionWaitList() throws WeixinException { - return customApi.getKfSessionWaitList(); - } - - /** - * 上传群发的图文消息,一个图文消息支持1到10条图文 - * - * @param articles - * 图片消息 - * @return 媒体ID - * @throws WeixinException - * @see 上传图文素材 - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @see com.foxinmy.weixin4j.mp.api.MassApi - */ - public String uploadMassArticle(List articles) - throws WeixinException { - return massApi.uploadArticle(articles); - } - - /** - * 上传分组群发的视频素材 - * - * @param video - * 视频对象 其中mediaId媒体文件中上传得到的Id 不能为空 - * @return 上传后的ID - * @throws WeixinException - * - * @see 高级群发 - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see com.foxinmy.weixin4j.msg.model.Video - * @see com.foxinmy.weixin4j.msg.model.MpVideo - * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)} - */ - public String uploadMassVideo(Video video) throws WeixinException { - return massApi.uploadVideo(video); - } - - /** - * 分组群发 - * - * @param box - * 消息对象 - * @param groupId - * 分组ID - * @return 群发后的消息ID - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massMessage(Base,boolean,int)} - * @throws WeixinException - */ - public String massByGroupId(Base box, int groupId) throws WeixinException { - return massApi.massByGroupId(box, groupId); - } - - /** - * 群发消息 - *

- * 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息, - * 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕 - *

- * - * @param box - * 消息对象 - * @param isToAll - * 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户, - * 选择false可根据group_id发送给指定群组的用户 - * @param groupId - * 分组ID - * @return 群发后的消息ID - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.MpVideo - * @see com.foxinmy.weixin4j.msg.model.MpNews - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see {@link com.foxinmy.weixin4j.mp.api.GroupApi#getGroups()} - * @see 根据分组群发 - */ - public String massMessage(Base box, boolean isToAll, int groupId) - throws WeixinException { - return massApi.massMessage(box, isToAll, groupId); - } - - /** - * 分组ID群发图文消息 - * - * @param articles - * 图文列表 - * @param groupId - * 分组ID - * @return 群发后的消息ID - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroupId(Base,int)} - * @see 根据分组群发 - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @throws WeixinException - */ - public String massArticleByGroupId(List articles, int groupId) - throws WeixinException { - return massApi.massArticleByGroupId(articles, groupId); - } - - /** - * openId群发 - * - *

- * 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息, - * 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕 - *

- * - * @param box - * 消息对象 - * @param openIds - * openId列表 - * @return 群发后的消息ID - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.model.User - * @see com.foxinmy.weixin4j.msg.model.Text - * @see com.foxinmy.weixin4j.msg.model.Image - * @see com.foxinmy.weixin4j.msg.model.Voice - * @see com.foxinmy.weixin4j.msg.model.MpVideo - * @see com.foxinmy.weixin4j.msg.model.MpNews - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see 根据openid群发 - * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)} - * @see {@link com.foxinmy.weixin4j.mp.api.UserApi#getUser(String)} - */ - public String massByOpenIds(Base box, String... openIds) - throws WeixinException { - return massApi.massByOpenIds(box, openIds); - } - - /** - * 根据openid群发图文消息 - * - * @param articles - * 图文列表 - * @param openIds - * openId列表 - * @return 群发后的消息ID - * @see 根据openid群发 - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(Base,String...)} - * @see com.foxinmy.weixin4j.msg.model.MpArticle - * @throws WeixinException - */ - public String massArticleByOpenIds(List articles, - String... openIds) throws WeixinException { - return massApi.massArticleByOpenIds(articles, openIds); - } - - /** - * 删除群发消息 - *

- * 请注意,只有已经发送成功的消息才能删除删除消息只是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片 - *

- * - * @param msgid - * 发送出去的消息ID - * @throws WeixinException - * @see 删除群发 - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByGroupId(Base, int)} - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#massByOpenIds(Base, String...) - */ - public JsonResult deleteMassNews(String msgid) throws WeixinException { - return massApi.deleteMassNews(msgid); - } - - /** - * 预览群发消息
开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版 - * - * @param openId - * 接收用户的ID - * @param box - * 消息体 - * @return 处理结果 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see 预览群发消息 - */ - public JsonResult previewMassNews(String openId, Base box) - throws WeixinException { - return massApi.previewMassNews(openId, box); - } - - /** - * 查询群发发送状态 - * - * @param msgId - * 消息ID - * @return 消息发送状态 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.api.MassApi - * @see {@link com.foxinmy.weixin4j.msg.event.MassEventMessage#getStatusDesc(String)} - * @see 查询群发状态 - */ - public String getMassNews(String msgId) throws WeixinException { - return massApi.getMassNews(msgId); - } - - /** - * 获取用户信息 - * - * @param openId - * 用户对应的ID - * @return 用户对象 - * @throws WeixinException - * @see 获取用户信息 - * @see com.foxinmy.weixin4j.mp.model.User - * @see com.foxinmy.weixin4j.mp.api.UserApi - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#getUser(String,Lang)} - */ - public User getUser(String openId) throws WeixinException { - return userApi.getUser(openId); - } - - /** - * 获取用户信息 - *

- * 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的,对于不同公众号, - * 同一用户的openid不同),公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间 - *

- * - * @param openId - * 用户对应的ID - * @param lang - * 国家地区语言版本 - * @return 用户对象 - * @throws WeixinException - * @see 获取用户信息 - * @see com.foxinmy.weixin4j.mp.type.Lang - * @see com.foxinmy.weixin4j.mp.model.User - * @see com.foxinmy.weixin4j.mp.api.UserApi - */ - public User getUser(String openId, Lang lang) throws WeixinException { - return userApi.getUser(openId, lang); - } - - /** - * 获取用户一定数量(10000)的关注者列表 - * - * @param nextOpenId - * 第一个拉取的OPENID,不填默认从头开始拉取 - * @return 关注信息 - * @throws WeixinException - * @see 获取关注者列表 - * @see com.foxinmy.weixin4j.mp.model.Following - * @see com.foxinmy.weixin4j.mp.api.UserApi - */ - public Following getFollowing(String nextOpenId) throws WeixinException { - return userApi.getFollowing(nextOpenId); - } - - /** - * 获取用户全部的关注者列表 - *

- * 当公众号关注者数量超过10000时,可通过填写next_openid的值,从而多次拉取列表的方式来满足需求, - * 将上一次调用得到的返回中的next_openid值,作为下一次调用中的next_openid值 - *

- * - * @return 用户对象集合 - * @throws WeixinException - * @see 获取关注者列表 - * @see com.foxinmy.weixin4j.mp.model.Following - * @see com.foxinmy.weixin4j.mp.api.UserApi - * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#getFollowing(String)} - */ - public List getAllFollowing() throws WeixinException { - return userApi.getAllFollowing(); - } - - /** - * 设置用户备注名 - * - * @param openId - * 用户ID - * @param remark - * 备注名 - * @throws WeixinException - * @see 设置用户备注名 - * @see com.foxinmy.weixin4j.mp.api.UserApi - */ - public JsonResult remarkUserName(String openId, String remark) - throws WeixinException { - return userApi.remarkUserName(openId, remark); - } - - /** - * 创建分组 - * - * @param name - * 组名称 - * @return group对象 - * @throws WeixinException - * @see 创建分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.model.Group#toCreateJson() - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public Group createGroup(String name) throws WeixinException { - return groupApi.createGroup(name); - } - - /** - * 查询所有分组 - * - * @return 组集合 - * @throws WeixinException - * @see 查询所有分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public List getGroups() throws WeixinException { - return groupApi.getGroups(); - } - - /** - * 查询用户所在分组 - * - * @param openId - * 用户对应的ID - * @return 组ID - * @throws WeixinException - * @see 查询用户所在分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public int getGroupByOpenId(String openId) throws WeixinException { - return groupApi.getGroupByOpenId(openId); - } - - /** - * 修改分组名 - * - * @param groupId - * 组ID - * @param name - * 组名称 - * @throws WeixinException - * @see 修改分组名 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public JsonResult modifyGroup(int groupId, String name) - throws WeixinException { - return groupApi.modifyGroup(groupId, name); - } - - /** - * 移动用户到分组 - * - * @param groupId - * 组ID - * @param openId - * 用户对应的ID - * @throws WeixinException - * @see 移动分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public JsonResult moveGroup(int groupId, String openId) - throws WeixinException { - return groupApi.moveGroup(groupId, openId); - } - - /** - * 批量移动分组 - * - * @param groupId - * 组ID - * @param openIds - * 用户ID列表(不能超过50个) - * @throws WeixinException - * @see 批量移动分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public JsonResult moveGroup(int groupId, String... openIds) - throws WeixinException { - return groupApi.moveGroup(groupId, openIds); - } - - /** - * 删除用户分组,所有该分组内的用户自动进入默认分组. - * - * @param groupId - * 组ID - * @throws WeixinException - * @see 删除用户分组 - * @see com.foxinmy.weixin4j.mp.model.Group - * @see com.foxinmy.weixin4j.mp.api.GroupApi - */ - public JsonResult deleteGroup(int groupId) throws WeixinException { - return groupApi.deleteGroup(groupId); - } - - /** - * 自定义菜单 - * - * @param btnList - * 菜单列表 - * @throws WeixinException - * @see 创建自定义菜单 - * @see com.foxinmy.weixin4j.model.Button - * @see com.foxinmy.weixin4j.type.ButtonType - * @see com.foxinmy.weixin4j.mp.api.MenuApi - */ - public JsonResult createMenu(List