微信公众平台_发送被动响应消息接口 实体类转换为xml工具类

前端之家收集整理的这篇文章主要介绍了微信公众平台_发送被动响应消息接口 实体类转换为xml工具类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


首先,微信公众平台发送被动响应消息接口官网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


如,回复文本消息必须是如下格式:

<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;
    }

}


下面是核心工具类:

@H_301_61@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格式要求了,这也就是造这个轮子的意义所在。


完毕。

猜你在找的XML相关文章