微信公众平台自动回复wechatlib.jar的生成及wechatlib解析

来源:互联网 发布:淘宝支付宝限额怎么改 编辑:程序博客网 时间:2024/05/16 08:01
微信公众平台出来有一段时日了,官方提供的自动回复的接口调用大致是这么些类型(text/image/location/link),每个项目都如此拷贝代码,在笔者看来比较麻烦,今天乘着点闲暇的时间特意将这些内容打成jar包,以方便日后的调用。
 
前期准备:
1)jdk1.7
2)eclipse(juno)
3)tomcat7.0.39
这些都准备好了后,我们开始解析wechatlib的原代码
 
wechatlib内容解析
结构图
  
 
  1.jar包解释
    dom4j-1.6.1.jar将request中得到微信服务器发送给我们的xml格式的消息(xml格式)进行解析,然后将解析得到的结果存入HashMap
    xstream-1.3.1.jar将响应的消息java类转换成xml格式
  2.源码解析
    a.请求消息封装(xidian.wq.wechatlib.entity.receive)
    请求消息的基类
复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:ReceiveBaseMessage   8 * 类描述:接收消息基类(普通用户发送信息给公众帐号)   9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:12:57  11 * @version       12 */13 public class ReceiveBaseMessage {14     // 开发者微信号  15     private String ToUserName;  16     // 发送方帐号(OpenID)  17     private String FromUserName;  18     // 消息创建时间 (整型)  19     private long CreateTime;  20     // 消息类型(text/image/location/link)  21     private String MsgType;  22     // 消息id,64位整型  23     private long MsgId;  24   25     public String getToUserName() {  26         return ToUserName;  27     }  28   29     public void setToUserName(String toUserName) {  30         ToUserName = toUserName;  31     }  32   33     public String getFromUserName() {  34         return FromUserName;  35     }  36   37     public void setFromUserName(String fromUserName) {  38         FromUserName = fromUserName;  39     }  40   41     public long getCreateTime() {  42         return CreateTime;  43     }  44   45     public void setCreateTime(long createTime) {  46         CreateTime = createTime;  47     }  48   49     public String getMsgType() {  50         return MsgType;  51     }  52   53     public void setMsgType(String msgType) {  54         MsgType = msgType;  55     }  56   57     public long getMsgId() {  58         return MsgId;  59     }  60   61     public void setMsgId(long msgId) {  62         MsgId = msgId;  63     }  64 }
复制代码

  请求消息中的文本消息

复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3 /**   4 *    5 * 项目名称:wechatlib   6 * 类名称:TextMessage   7 * 类描述:文本消息  8 * 创建人:WQ   9 * 创建时间:2013-10-3 下午4:13:06  10 * @version       11 */12 public class TextMessage extends ReceiveBaseMessage{13     // 消息内容  14     private String Content;  15   16     public String getContent() {  17         return Content;  18     }  19   20     public void setContent(String content) {  21         Content = content;  22     }  23 } 
复制代码

  请求消息中的图片消息

复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:ImageMessage   8 * 类描述:图片消息   9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:12:19  11 * @version       12 */13 public class ImageMessage extends ReceiveBaseMessage{14     // 图片链接  15     private String PicUrl;  16   17     public String getPicUrl() {  18         return PicUrl;  19     }  20   21     public void setPicUrl(String picUrl) {  22         PicUrl = picUrl;  23     }  24 }
复制代码

  请求消息中的地理位置消息

复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:LocationMessage   8 * 类描述:地理位置消息   9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:12:45  11 * @version       12 */13 public class LocationMessage extends ReceiveBaseMessage{14     // 地理位置维度  15     private String Location_X;  16     // 地理位置经度  17     private String Location_Y;  18     // 地图缩放大小  19     private String Scale;  20     // 地理位置信息  21     private String Label;  22   23     public String getLocation_X() {  24         return Location_X;  25     }  26   27     public void setLocation_X(String location_X) {  28         Location_X = location_X;  29     }  30   31     public String getLocation_Y() {  32         return Location_Y;  33     }  34   35     public void setLocation_Y(String location_Y) {  36         Location_Y = location_Y;  37     }  38   39     public String getScale() {  40         return Scale;  41     }  42   43     public void setScale(String scale) {  44         Scale = scale;  45     }  46   47     public String getLabel() {  48         return Label;  49     }  50   51     public void setLabel(String label) {  52         Label = label;  53     } 54 }
复制代码

  请求消息中的链接消息

复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3 /**   4 *    5 * 项目名称:wechatlib   6 * 类名称:LinkMessage   7 * 类描述:链接消息    8 * 创建人:WQ   9 * 创建时间:2013-10-3 下午4:12:33  10 * @version       11 */12 public class LinkMessage {13     // 消息标题  14     private String Title;  15     // 消息描述  16     private String Description;  17     // 消息链接  18     private String Url;  19   20     public String getTitle() {  21         return Title;  22     }  23   24     public void setTitle(String title) {  25         Title = title;  26     }  27   28     public String getDescription() {  29         return Description;  30     }  31   32     public void setDescription(String description) {  33         Description = description;  34     }  35   36     public String getUrl() {  37         return Url;  38     }  39   40     public void setUrl(String url) {  41         Url = url;  42     }  43 }
复制代码

  请求消息中的语音消息

复制代码
 1 package xidian.wq.wechatlib.entity.receive; 2  3 /**   4 *    5 * 项目名称:wechatlib   6 * 类名称:VoiceMessage   7 * 类描述:音频消息    8 * 创建人:WQ   9 * 创建时间:2013-10-3 下午4:13:18  10 * @version       11 */12 public class VoiceMessage {13     // 媒体ID  14     private String MediaId;  15     // 语音格式  16     private String Format;  17   18     public String getMediaId() {  19         return MediaId;  20     }  21   22     public void setMediaId(String mediaId) {  23         MediaId = mediaId;  24     }  25   26     public String getFormat() {  27         return Format;  28     }  29   30     public void setFormat(String format) {  31         Format = format;  32     }  33 }
复制代码

 

  b.回复消息封装(xidian.wq.wechatlib.entity.send)

  回复消息的基类

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3 /**   4 *    5 * 项目名称:wechatlib   6 * 类名称:SendBaseMessage   7 * 类描述:回复消息基类(公众帐号回复消息给普通用户)   8 * 创建人:WQ   9 * 创建时间:2013-10-3 下午4:11:46  10 * @version       11 */12 public class SendBaseMessage {13     // 接收方帐号(OpenID)  14     private String ToUserName;  15     // 开发者微信号  16     private String FromUserName;  17     // 消息创建时间 (整型)  18     private long CreateTime;  19     // 消息类型(text/music/news)  20     private String MsgType;  21   22     public String getToUserName() {  23         return ToUserName;  24     }  25   26     public void setToUserName(String toUserName) {  27         ToUserName = toUserName;  28     }  29   30     public String getFromUserName() {  31         return FromUserName;  32     }  33   34     public void setFromUserName(String fromUserName) {  35         FromUserName = fromUserName;  36     }  37   38     public long getCreateTime() {  39         return CreateTime;  40     }  41   42     public void setCreateTime(long createTime) {  43         CreateTime = createTime;  44     }  45   46     public String getMsgType() {  47         return MsgType;  48     }  49   50     public void setMsgType(String msgType) {  51         MsgType = msgType;  52     }  53 }
复制代码

  回复消息中的文本消息

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3 /**   4 *    5 * 项目名称:wechatlib   6 * 类名称:TextMessage   7 * 类描述:文本消息    8 * 创建人:WQ   9 * 创建时间:2013-10-3 下午4:12:00  10 * @version       11 */12 public class TextMessage extends SendBaseMessage{13      // 消息内容  14     private String Content;  15   16     public String getContent() {  17         return Content;  18     }  19   20     public void setContent(String content) {  21         Content = content;  22     }  23 } 
复制代码

  回复消息中的音乐消息

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:MusicMessage   8 * 类描述:音乐消息  9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:11:19  11 * @version       12 */13 public class MusicMessage extends SendBaseMessage{14     // 音乐  15     private Music Music;  16   17     public Music getMusic() {  18         return Music;  19     }  20   21     public void setMusic(Music music) {  22         Music = music;  23     }  24 }
复制代码

  音乐消息中的music类

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:Music   8 * 类描述:音乐model  9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:11:03  11 * @version       12 */13 public class Music {14     // 音乐名称  15     private String Title;  16     // 音乐描述  17     private String Description;  18     // 音乐链接  19     private String MusicUrl;  20     // 高质量音乐链接,WIFI环境优先使用该链接播放音乐  21     private String HQMusicUrl;  22   23     public String getTitle() {  24         return Title;  25     }  26   27     public void setTitle(String title) {  28         Title = title;  29     }  30   31     public String getDescription() {  32         return Description;  33     }  34   35     public void setDescription(String description) {  36         Description = description;  37     }  38   39     public String getMusicUrl() {  40         return MusicUrl;  41     }  42   43     public void setMusicUrl(String musicUrl) {  44         MusicUrl = musicUrl;  45     }  46   47     public String getHQMusicUrl() {  48         return HQMusicUrl;  49     }  50   51     public void setHQMusicUrl(String musicUrl) {  52         HQMusicUrl = musicUrl;  53     }  54 }
复制代码

  回复消息中的图文消息

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3 import java.util.List; 4  5  6 /**   7 *    8 * 项目名称:wechatlib   9 * 类名称:NewsMessage  10 * 类描述:图文消息  11 * 创建人:WQ  12 * 创建时间:2013-10-3 下午4:11:32  13 * @version       14 */15 public class NewsMessage extends SendBaseMessage{16     // 图文消息个数,限制为10条以内  17     private int ArticleCount;  18     // 多条图文消息信息,默认第一个item为大图  19     private List<Article> Articles;  20   21     public int getArticleCount() {  22         return ArticleCount;  23     }  24   25     public void setArticleCount(int articleCount) {  26         ArticleCount = articleCount;  27     }  28   29     public List<Article> getArticles() {  30         return Articles;  31     }  32   33     public void setArticles(List<Article> articles) {  34         Articles = articles;  35     }  36 }
复制代码

  图文消息中的article类

 

复制代码
 1 package xidian.wq.wechatlib.entity.send; 2  3  4 /**   5 *    6 * 项目名称:wechatlib   7 * 类名称:Article   8 * 类描述:图文model   9 * 创建人:WQ  10 * 创建时间:2013-10-3 下午4:10:51  11 * @version       12 */13 public class Article {14     // 图文消息名称  15     private String Title;  16     // 图文消息描述  17     private String Description;  18     // 图片链接,支持JPG、PNG格式,较好的效果为大图600*300,小图80*80,限制图片链接的域名需要与开发者填写的基本资料中的Url一致  19     private String PicUrl;  20     // 点击图文消息跳转链接  21     private String Url;  22   23     public String getTitle() {  24         return Title;  25     }  26   27     public void setTitle(String title) {  28         Title = title;  29     }  30   31     public String getDescription() {  32         return null == Description ? "" : Description;  33     }  34   35     public void setDescription(String description) {  36         Description = description;  37     }  38   39     public String getPicUrl() {  40         return null == PicUrl ? "" : PicUrl;  41     }  42   43     public void setPicUrl(String picUrl) {  44         PicUrl = picUrl;  45     }  46   47     public String getUrl() {  48         return null == Url ? "" : Url;  49     }  50   51     public void setUrl(String url) {  52         Url = url;  53     }  54 }
复制代码

 

 

  c.基础设置(xidian.wq.wechatlib.utils)

  消息处理工具类

复制代码
  1 package xidian.wq.wechatlib.utils;  2   3 import java.io.InputStream;  4 import java.io.Writer;  5 import java.util.HashMap;  6 import java.util.List;  7 import java.util.Map;  8   9 import javax.servlet.http.HttpServletRequest; 10  11 import org.dom4j.Document; 12 import org.dom4j.Element; 13 import org.dom4j.io.SAXReader; 14  15 import xidian.wq.wechatlib.entity.send.Article; 16 import xidian.wq.wechatlib.entity.send.MusicMessage; 17 import xidian.wq.wechatlib.entity.send.NewsMessage; 18 import xidian.wq.wechatlib.entity.send.TextMessage; 19  20 import com.thoughtworks.xstream.XStream; 21 import com.thoughtworks.xstream.core.util.QuickWriter; 22 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 23 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; 24 import com.thoughtworks.xstream.io.xml.XppDriver; 25  26 /**   27 *    28 * 项目名称:wechatlib   29 * 类名称:MessageUtil   30 * 类描述:消息处理工具类   31 * 创建人:WQ   32 * 创建时间:2013-10-3 下午4:08:40   33 * @version        34 */ 35 public class MessageUtil { 36      /**  37      * 返回消息类型:文本  38      */   39     public static final String SEND_TEXT = "text";   40    41     /**  42      * 返回消息类型:音乐  43      */   44     public static final String SEND_MUSIC = "music";   45    46     /**  47      * 返回消息类型:图文  48      */   49     public static final String SEND_NEWS = "news";   50    51     /**  52      * 请求消息类型:文本  53      */   54     public static final String RECRIVE_TEXT = "text";   55    56     /**  57      * 请求消息类型:图片  58      */   59     public static final String RECRIVE_IMAGE = "image";   60    61     /**  62      * 请求消息类型:链接  63      */   64     public static final String RECRIVE_LINK = "link";   65    66     /**  67      * 请求消息类型:地理位置  68      */   69     public static final String RECRIVE_LOCATION = "location";   70    71     /**  72      * 请求消息类型:音频  73      */   74     public static final String RECRIVE_VOICE = "voice";   75    76     /**  77      * 请求消息类型:推送  78      */   79     public static final String RECRIVE_EVENT = "event";   80    81     /**  82      * 事件类型:subscribe(订阅)  83      */   84     public static final String RECRIVE_SUBSCRIBE = "subscribe";   85    86     /**  87      * 事件类型:unsubscribe(取消订阅)  88      */   89     public static final String RECRIVE_UNSUBSCRIBE = "unsubscribe";   90    91     /**  92      * 事件类型:CLICK(自定义菜单点击事件)  93      */   94     public static final String RECRIVE_CLICK = "CLICK";   95    96     /**  97      * 解析微信发来的请求(XML)  98      *   99      * @param request 100      * @return 101      * @throws Exception 102      */  103     @SuppressWarnings("unchecked")  104     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {  105         // 将解析结果存储在HashMap中  106         Map<String, String> map = new HashMap<String, String>();   107         // 从request中取得输入流  108         InputStream inputStream = request.getInputStream();  109         // 读取输入流  110         SAXReader reader = new SAXReader();  111         Document document = reader.read(inputStream);  112         // 得到xml根元素  113         Element root = document.getRootElement();  114         // 得到根元素的所有子节点  115         List<Element> elementList = root.elements();  116         // 遍历所有子节点  117         for (Element e : elementList)  118             map.put(e.getName(), e.getText());  119         // 释放资源  120         inputStream.close();  121         inputStream = null;   122         return map;  123     }  124   125     /** 126      * 文本消息对象转换成xml 127      *  128      * @param textMessage 文本消息对象 129      * @return xml 130      */  131     public static String textMessageToXml(TextMessage textMessage) {  132         xstream.alias("xml", textMessage.getClass());  133         return xstream.toXML(textMessage);  134     }  135   136     /** 137      * 音乐消息对象转换成xml 138      *  139      * @param musicMessage 音乐消息对象 140      * @return xml 141      */  142     public static String musicMessageToXml(MusicMessage musicMessage) {  143         xstream.alias("xml", musicMessage.getClass());  144         return xstream.toXML(musicMessage);  145     }  146   147     /** 148      * 图文消息对象转换成xml 149      *  150      * @param newsMessage 图文消息对象 151      * @return xml 152      */  153     public static String newsMessageToXml(NewsMessage newsMessage) {  154         xstream.alias("xml", newsMessage.getClass());  155         xstream.alias("item", new Article().getClass());  156         return xstream.toXML(newsMessage);  157     }  158   159     160     /** 161      * 扩展xstream,使其支持CDATA块 162      *  163      * @date 2013-05-19 164      */  165     private static XStream xstream = new XStream(new XppDriver() {  166         public HierarchicalStreamWriter createWriter(Writer out) {  167             return new PrettyPrintWriter(out) {  168                 // 对所有xml节点的转换都增加CDATA标记  169                 boolean cdata = true;    170                 @SuppressWarnings("unchecked")  171                 public void startNode(String name, Class clazz) {  172                     super.startNode(name, clazz);  173                 }  174                 protected void writeText(QuickWriter writer, String text) {  175                     if (cdata) {  176                         writer.write("<![CDATA[");  177                         writer.write(text);  178                         writer.write("]]>");  179                     } else {  180                         writer.write(text);  181                     }  182                 }  183             };  184         }  185     });  186 }    
复制代码

  url配置请求校验工具类  

复制代码
 1 package xidian.wq.wechatlib.utils; 2  3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.Arrays; 6  7 import java.security.MessageDigest; 8 import java.security.NoSuchAlgorithmException; 9 import java.util.Arrays;10     11 12 /**  13 *   14 * 项目名称:wechatlib  15 * 类名称:SignUtil  16 * 类描述:url配置请求校验工具类   17 * 创建人:WQ  18 * 创建时间:2013-10-3 下午4:09:14  19 * @version       20 */21 public class SignUtil {  22     // 与接口配置信息中的Token要一致  23     private static String token = "fromsedion";    24     /** 25      * 验证签名 26      *  27      * @param signature  微信加密签名28      * @param timestamp  时间戳29      * @param nonce      随机数30      * @return 31      */  32     public static boolean checkSignature(String signature, String timestamp, String nonce) {  33         String[] arr = new String[] { token, timestamp, nonce };  34         // 将token、timestamp、nonce三个参数进行字典序排序  35         Arrays.sort(arr);  36         StringBuilder content = new StringBuilder();  37         for (int i = 0; i < arr.length; i++) {  38             content.append(arr[i]);  39         }  40         MessageDigest md = null;  41         String tmpStr = null;  42   43         try {  44             md = MessageDigest.getInstance("SHA-1");  45             // 将三个参数字符串拼接成一个字符串进行sha1加密  46             byte[] digest = md.digest(content.toString().getBytes());  47             tmpStr = byteToStr(digest);  48         } catch (NoSuchAlgorithmException e) {  49             e.printStackTrace();  50         }  51   52         content = null;  53         // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信  54         return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  55     }  56   57     /** 58      * 将字节数组转换为十六进制字符串 59      *  60      * @param byteArray 61      * @return 62      */  63     private static String byteToStr(byte[] byteArray) {  64         String strDigest = "";  65         for (int i = 0; i < byteArray.length; i++) {  66             strDigest += byteToHexStr(byteArray[i]);  67         }  68         return strDigest;  69     }  70   71     /** 72      * 将字节转换为十六进制字符串 73      *  74      * @param mByte 75      * @return 76      */  77     private static String byteToHexStr(byte mByte) {  78         char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  79         char[] tempArr = new char[2];  80         tempArr[0] = Digit[(mByte >>> 4) & 0X0F];  81         tempArr[1] = Digit[mByte & 0X0F];    82         String s = new String(tempArr);  83         return s;  84     }  85 }
复制代码

  

  d.service回复信息处理(xidian.wq.wechatlib.ways.send)

复制代码
 1 package xidian.wq.wechatlib.ways.send; 2 import java.util.Date; 3 import java.util.List; 4  5 import xidian.wq.wechatlib.entity.send.Article; 6 import xidian.wq.wechatlib.entity.send.NewsMessage; 7 import xidian.wq.wechatlib.entity.send.TextMessage; 8 import xidian.wq.wechatlib.utils.MessageUtil; 9 10 /**  11 *   12 * 项目名称:wechatlib  13 * 类名称:SendService  14 * 类描述: 回复信息类型的封装15 * 创建人:WQ  16 * 创建时间:2013-10-3 下午4:07:59  17 * @version       18 */19 public class SendService {20     /**21      * 回复文本消息22      * @param fromusername 粉丝openid23      * @param tousername 微信公众号24      * @param respContent 回复信息25      * @return26      */27     public static String sendTextmessage(String fromusername,String tousername,String respContent){28         //初始化回复信息29         String respmessage;30         //回复文本消息  31         TextMessage textMessage = new TextMessage(); 32         //发送方帐号(一个OpenID)33         textMessage.setToUserName(fromusername); 34         //开发者微信号 35         textMessage.setFromUserName(tousername);  36         //消息创建时间 (整型) 37         textMessage.setCreateTime(new Date().getTime()); 38         //消息类型text 39         textMessage.setMsgType(MessageUtil.SEND_TEXT);  40         //回复的消息内容,长度不超过2048字节 41         textMessage.setContent(respContent);   42         //转为xml格式43         respmessage = MessageUtil.textMessageToXml(textMessage);44         //返回回复信息45         return respmessage; 46     }47        48     /**49      * 图文消息设置50      * @param fromusername 粉丝openid51      * @param tousername   开发者微信公众账号52      * @param newslist     图文消息list53      * @return54      */55     public static String sendNewsmessage(String fromusername,String tousername,List<Article> newslist){  56         //初始化回复信息57         String respmessage;  58         //创建图文消息  59         NewsMessage newsMessage=new NewsMessage();       60         //发送方帐号(一个OpenID)61         newsMessage.setToUserName(fromusername); 62         //开发者微信号 63         newsMessage.setFromUserName(tousername); 64         //消息创建时间 (整型)65         newsMessage.setCreateTime(new Date().getTime());  66         //消息类型news 67         newsMessage.setMsgType(MessageUtil.SEND_NEWS);68         //图文消息个数,限制为10条以内 69         newsMessage.setArticleCount(newslist.size());70         //多条图文消息信息,默认第一个item为大图71         newsMessage.setArticles(newslist);72         //转成xml形式73         respmessage = MessageUtil.newsMessageToXml(newsMessage);74         //回复信息75         return respmessage;  76     }77 }
复制代码

 

 

打包


以上即是所要打的jar包包含的所有类,接下去讲解打包:

因为项目中要将外部引用的jar包(dom4j-1.6.1.jar和xstream-1.3.1.jar)打进jar包,所以笔者准备了fat-jar(sourcefprge.net下的一个开源工具),下载地址为http://pan.baidu.com/s/1CCtSf也可以到http://sourcefprge.net/projects/fjep下载,将下载好的net.sf.fjep.fatjar_0.0.31.jar拷贝到eclipse目录下的plugins目录下,然后重启eclipse,准备完成。

 

点击项目wechatlib,右键选中Build Fat Jar

                      

选择需要用到的jar和文件

                                    

点击finish即可

如果你急需用到wechatlib,可直接在此处下载http://pan.baidu.com/share/link?uk=1730904624&shareid=1479736624


 
菜鸟胖子总结如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号codenewbie支持胖子!若有不妥之处,欢迎指点。

转帖请注明本文出自胖子的博客(http://www.cnblogs.com/Codenewbie),请尊重他人的辛勤劳动成果,谢谢!

原创粉丝点击