微信公众平台_发送被动响应消息接口 实体类转换为xml工具类
2014-07-01 11:07
344 查看
首先,微信公众平台发送被动响应消息接口官网wiki:
http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E8%A2%AB%E5%8A%A8%E5%93%8D%E5%BA%94%E6%B6%88%E6%81%AF
如,回复文本消息必须是如下格式:
回复图片消息格式:
不得不吐槽下,这个回复消息格式不是json格式也罢,甚至连xml格式都不是。用传统的JOX(PS:不想用DOM)是无法将实体类直接转成这个API要求的xml格式的,吐槽归吐槽,但人家TX店大欺客,你不用也得用。
下面讲下笔者这里的处理方法-->
首先,有一个rsp模板类:
文本类回复消息类,extends 模板类:
图片类回复消息类,extends 模板类:
下面是核心工具类:
这个是console输出结果:
可以看到传统的JOX转换来的xml是有header部分的,且多了个TextRspMsg节点,子节点都是小写(这里,JOX内部在转换为xml的时候会遵循Java命名格式,将所有的属性的首字符改成小写,所以,即使把实体类的字段属性故意写成大写也不行。)而用Bean2WeChatXml工具类转化来的xml就能完全满足API格式要求了,这也就是造这个轮子的意义所在。
完毕。
http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E8%A2%AB%E5%8A%A8%E5%93%8D%E5%BA%94%E6%B6%88%E6%81%AF
如,回复文本消息必须是如下格式:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content> </xml>
回复图片消息格式:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[image]]></MsgType> <Image> <MediaId><![CDATA[media_id]]></MediaId> </Image> </xml>
不得不吐槽下,这个回复消息格式不是json格式也罢,甚至连xml格式都不是。用传统的JOX(PS:不想用DOM)是无法将实体类直接转成这个API要求的xml格式的,吐槽归吐槽,但人家TX店大欺客,你不用也得用。
下面讲下笔者这里的处理方法-->
首先,有一个rsp模板类:
/** * 被动响应消息模板基类,其他Msg类需extends其 * 注:Msg类属性命名方式未遵循驼峰模式,因为需要和微信接口定义保持一致。 * @author will_awoke * @version 2014-6-24 * @see TemplateRspMsg * @since */ public class TemplateRspMsg { // 响应消息时,接收方帐号(收到的OpenID) protected String ToUserName; // 响应消息时,开发者微信号(公众平台原始ID) protected String FromUserName; // 消息创建时间 Long型 protected String CreateTime; // 消息类型 protected String MsgType; /** * 构造器 */ public TemplateRspMsg() { } //setter getter public String getMsgType() { return MsgType; } //protected for msgTypeSetter protected void setMsgType(String msgType) { MsgType = msgType; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getCreateTime() { return CreateTime; } public void setCreateTime(String createTime) { CreateTime = createTime; } }
文本类回复消息类,extends 模板类:
/** * 文本类响应消息 MsgType=text * @author will_awoke * @version 2014-6-24 * @see TextRspMsg * @since */ public class TextRspMsg extends TemplateRspMsg { //文本消息内容 private String Content; /** * 构造器,同时初始化MsgType */ public TextRspMsg() { setMsgType("text"); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("TextRspMsg [Content=").append(Content).append(", ToUserName=").append( ToUserName).append(", FromUserName=").append(FromUserName).append(", CreateTime=").append( CreateTime).append(", MsgType=").append(MsgType).append("]"); return builder.toString(); } //setter getter public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
图片类回复消息类,extends 模板类:
import java.util.HashMap; import java.util.Map; /** * 图片类型客服消息 * @author will_awoke * @version 2014-6-25 * @see ImageRspMsg * @since */ public class ImageRspMsg extends TemplateRspMsg { //用于拼装形如 <Image><MediaId><![CDATA[media_id]]></MediaId></Image>专有属性 private Map<String, Object> Image; /** * 构造器,同时初始化MsgType */ public ImageRspMsg() { setMsgType("image"); } /** * 格式化成符合微信API要求的实体 * @param ToUserName 普通用户openid * @param FromUserName 开发者微信号(公众平台原始ID) * @param MediaId 通过上传多媒体文件,得到的id。 * @return 符合API要求的实体 * @see */ public ImageRspMsg xmlFormatBean(String ToUserName, String FromUserName, String MediaId) { this.setToUserName(ToUserName); this.setFromUserName(FromUserName); //由于微信服务端需要的时间整形是以秒为单位的,故需要除以1000L this.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000L)); Map<String, Object> map = new HashMap<String, Object>(); map.put("MediaId", MediaId); this.setImage(map); return this; } //setter getter public Map<String, Object> getImage() { return Image; } public void setImage(Map<String, Object> image) { Image = image; } }
下面是核心工具类:
import java.lang.reflect.Field; import java.util.Iterator; import java.util.Map; import org.apache.commons.lang.StringUtils; import com.xx.wechat.model.rsp.ImageRspMsg; import com.xx.wechat.model.rsp.TextRspMsg; /** * * 将被动响应消息实体类转换成符合微信接口API要求的xml格式。 * 如: * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[image]]></MsgType> * <Image> * <MediaId><![CDATA[media_id]]></MediaId> * </Image> * </xml> * 注意:根节点是xml而非实体名,且无xml头文件,每个节点的首字母是大写。 * 而此功能是JOX转换不具有的,故造此轮子工具类 * 另请参见:wechat.model.rsp包 * * @author will_awoke * @version 2014-6-25 * @see Bean2WeChatXml * @since */ public class Bean2WeChatXml { /** * 将实体类转换成符合微信接口API要求的xml格式 * @param obj * @return * @throws IllegalArgumentException * @throws IllegalAccessException * @see */ @SuppressWarnings("rawtypes") public static String beanToXML(Object obj) throws IllegalArgumentException, IllegalAccessException { StringBuffer sb = new StringBuffer("<xml>\n"); Class clazz = obj.getClass(); Field[] fields = clazz.getDeclaredFields(); //父类Class Class superClass = clazz.getSuperclass(); Field[] superFields = superClass.getDeclaredFields(); //拼装自身的字段和字段值 String fieldName = null; Object mapObj = null; for (Field field : fields) { field.setAccessible(true); fieldName = field.getName();//获得字段名 mapObj = field.get(obj);//获得字段值 //如果字段是Map类型,形如ImageRspMsg类中Map字段 if (mapObj instanceof Map) { //迭代map集合 StringBuffer mapFieldValue = new StringBuffer(""); String key = ""; Map castMap = (Map)mapObj; Iterator iterator = castMap.keySet().iterator(); while (iterator.hasNext()) { //迭代 key = (String)iterator.next(); mapFieldValue.append("<").append(key).append(">"); //调用value的toString方法 mapFieldValue.append("<![CDATA[").append(castMap.get(key).toString()).append("]]>"); mapFieldValue.append("</").append(key).append(">\n"); } sb.append("<").append(fieldName).append(">\n"); sb.append(mapFieldValue); //map集合内的迭代结果,勿加CDATA sb.append("</").append(fieldName).append(">\n"); } //字段非Map类型,则按照String类型处理(获得value时直接调用toString方法) else { sb.append("<").append(fieldName).append(">"); sb.append("<![CDATA[").append(mapObj.toString()).append("]]>"); sb.append("</").append(fieldName).append(">\n"); } } //拼装父类的字段和字段值 String superFieldName = ""; for (Field field : superFields) { field.setAccessible(true); superFieldName = field.getName(); sb.append("<").append(superFieldName).append(">"); sb.append("<![CDATA[").append(field.get(obj).toString()).append("]]>"); sb.append("</").append(superFieldName).append(">\n"); } sb.append("</xml>"); return sb.toString(); } /** * @param args * @see */ public static void main(String[] args) throws Exception { TextRspMsg rsp = new TextRspMsg(); rsp.setToUserName("ToUserName"); rsp.setFromUserName("FromUserName"); rsp.setCreateTime(String.valueOf(System.currentTimeMillis())); rsp.setContent("您好!welcome to subscribe will's public ..."); System.out.println(JoxUtil.beanToXML(rsp)); System.out.println(beanToXML(rsp)); ImageRspMsg image = new ImageRspMsg(); image.xmlFormatBean("ToUserName", "FromUserName", "MediaId"); System.out.println("\n" + beanToXML(image)); } }
这个是console输出结果:
<?xml version="1.0" encoding="UTF-8"?> <TextRspMsg> <content>您好!welcome to subscribe will's public ...</content> <createTime>1404286867859</createTime> <fromUserName>FromUserName</fromUserName> <msgType>text</msgType> <toUserName>ToUserName</toUserName> </TextRspMsg> <xml> <Content><![CDATA[您好!welcome to subscribe will's public ...]]></Content> <ToUserName><![CDATA[ToUserName]]></ToUserName> <FromUserName><![CDATA[FromUserName]]></FromUserName> <CreateTime><![CDATA[1404286867859]]></CreateTime> <MsgType><![CDATA[text]]></MsgType> </xml> <xml> <Image> <MediaId><![CDATA[MediaId]]></MediaId> </Image> <ToUserName><![CDATA[ToUserName]]></ToUserName> <FromUserName><![CDATA[FromUserName]]></FromUserName> <CreateTime><![CDATA[1404286868]]></CreateTime> <MsgType><![CDATA[image]]></MsgType> </xml>
可以看到传统的JOX转换来的xml是有header部分的,且多了个TextRspMsg节点,子节点都是小写(这里,JOX内部在转换为xml的时候会遵循Java命名格式,将所有的属性的首字符改成小写,所以,即使把实体类的字段属性故意写成大写也不行。)而用Bean2WeChatXml工具类转化来的xml就能完全满足API格式要求了,这也就是造这个轮子的意义所在。
完毕。
相关文章推荐
- 微信公众平台-接收发送被动响应消息-PHP示例
- xml字符串和java实体类相互转换JaxbXmlUtil工具类 附java实体类生成soap接口报文案例
- 微信公众平台消息接口开发(2)你的服务器没有正确响应Token验证的解决方法
- 微信公众平台消息接口开发(29)校验签名与消息响应合并
- 微信公众平台开发【发送消息】被动回复消息
- 微信公众平台模板消息发送接口文档
- 使用Java语言开发微信公众平台(四)——图文消息的发送与响应
- 微信公众平台消息接口开发(29)校验签名与消息响应合并
- 微信公众平台开发【发送消息】被动回复消息
- 异常信息:CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88,这种状态已持续60秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作.这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积
- 微信公众平台 接口设置出现“你的服务器没有正确响应Token验证,请阅读消息接口使用指南”解决方案 Python
- cgi程序读取post发送的特殊字符,尤其适合于微信公众平台开发中发送被动消息
- 微信公众平台接口教程:获取用户发送的地理位置xml
- 微信公众平台模板消息发送接口文档
- 微信公众平台消息接口开发(29)校验签名与消息响应合并
- 微信公众平台开发(73) 客服接口发送客服消息
- 微信公众平台开发(73) 客服接口发送客服消息
- 微信公众平台开发(73) 客服接口发送客服消息
- 微信公众平台模板消息发送接口文档