• [042] 微信公众帐号开发教程第18篇-应用实例之音乐搜索


    引言及内容概要

    微信公众平台支持向用户回复音乐消息,用户收到音乐消息后,点击就可以播放音乐。通过音乐消息,公众账号能够实现音乐搜索(歌曲点播)功能,即用户输入想听的音乐名称,公众账号返回相应的音乐(歌曲)。读者能够关注xiaoqrobot体验该功能,操作指南及使用例如以下所看到的。

    考虑到歌曲名称有反复的情况,用户还能够同一时候指定歌曲名称、演唱者搜索歌曲。以下就为读者具体介绍歌曲点播功能的实现过程。

    音乐消息说明

    微信公众平台开发人员文档中提到,向用户回复音乐消息须要构造例如以下格式的XML数据。

    1. <xml>  
    2.     <ToUserName><![CDATA[toUser]]></ToUserName>  
    3.     <FromUserName><![CDATA[fromUser]]></FromUserName>  
    4.     <CreateTime>12345678</CreateTime>  
    5.     <MsgType><![CDATA[music]]></MsgType>  
    6.     <Music>  
    7.         <Title><![CDATA[TITLE]]></Title>  
    8.         <Description><![CDATA[DESCRIPTION]]></Description>  
    9.         <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>  
    10.         <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>  
    11.         <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>  
    12.     </Music>  
    13. </xml>  
    <xml>
    	<ToUserName><![CDATA[toUser]]></ToUserName>
    	<FromUserName><![CDATA[fromUser]]></FromUserName>
    	<CreateTime>12345678</CreateTime>
    	<MsgType><![CDATA[music]]></MsgType>
    	<Music>
    		<Title><![CDATA[TITLE]]></Title>
    		<Description><![CDATA[DESCRIPTION]]></Description>
    		<MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
    		<HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
    		<ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
    	</Music>
    </xml>

    上面XML中,须要注意的是<Music>节点中的参数,说明例如以下:

    1)参数Title:标题,本例中能够设置为歌曲名称;

    2)参数Description:描写叙述,本例中能够设置为歌曲的演唱者;

    3)参数MusicUrl:普通品质的音乐链接;

    4)参数HQMusicUrl:高品质的音乐链接,在WIFI环境下会优先使用该链接播放音乐;

    5)参数ThumbMediaId:缩略图的媒体ID,通过上传多媒体文件获得;它指向的是一张图片,终于会作为音乐消息左側绿色方形区域的背景图片。
    上述5个参数中,最为重要的是MusicUrl和HQMusicUrl,这也是本文的重点,怎样依据歌曲名称获得歌曲的链接。假设读者仅仅能得到歌曲的一个链接,能够将MusicUrl和HQMusicUrl设置成一样的。至于ThumbMediaId参数,必须是通过微信认证的服务号才干得到,普通的服务号与订阅号能够忽略该参数,也就是说,在回复给微信server的XML中能够不包括ThumbMediaId参数。

    百度音乐搜索API介绍

    上面提到,给用户回复音乐消息最关键在于怎样依据歌曲名称获得歌曲的链接,我们必须找一个现成的音乐搜索API,除非读者自己有音乐server,或者仅仅向用户回复固定的几首音乐。百度有一个非公开的音乐搜索API,之所以说非公开,是由于笔者沒有在百度官网的不论什么地方看到有关该API的介绍,但这并不影响读者对本例的学习,我们仍然能够调用它。百度音乐搜索API的请求地址例如以下:

    1. http://box.zhangmen.baidu.com/x?op=12&count=1&title=TITLE$$AUTHOR$$$$  
    http://box.zhangmen.baidu.com/x?op=12&count=1&title=TITLE$$AUTHOR$$$$

    http://box.zhangmen.baidu.com为百度音乐盒的首页地址,上面的链接中不用管参数op和count,重点关注TITLE和AUTHOR,TITLE表示歌曲名称,AUTHOR表示演唱者,AUTHOR能够为空,参数TITLE和AUTHOR须要进行URL编码(UTF-8或GB2312均可)。比如,要搜索歌曲零点乐队的“相信自己”,能够像以下这样:

    1. // GB2312编码的音乐搜索链接  
    2. http://box.zhangmen.baidu.com/x?op=12&count=1&title=%CF%E0%D0%C5%D7%D4%BC%BA$$%C1%E3%B5%E3%C0%D6%B6%D3$$$$  
    3. // UTF-8编码的音乐搜索链接  
    4. http://box.zhangmen.baidu.com/x?op=12&count=1&title=%E7%9B%B8%E4%BF%A1%E8%87%AA%E5%B7%B1$$%E9%9B%B6%E7%82%B9%E4%B9%90%E9%98%9F$$$$  
    // GB2312编码的音乐搜索链接
    http://box.zhangmen.baidu.com/x?op=12&count=1&title=%CF%E0%D0%C5%D7%D4%BC%BA$$%C1%E3%B5%E3%C0%D6%B6%D3$$$$
    // UTF-8编码的音乐搜索链接
    http://box.zhangmen.baidu.com/x?op=12&count=1&title=%E7%9B%B8%E4%BF%A1%E8%87%AA%E5%B7%B1$$%E9%9B%B6%E7%82%B9%E4%B9%90%E9%98%9F$$$$

    通过浏览器訪问上面的地址,返回的是例如以下格式的XML数据:

    1. <result>  
    2.     <count>1</count>  
    3.     <url>  
    4.         <encode>  
    5.             <![CDATA[http://zhangmenshiting.baidu.com/data2/music/44277542/ZWZla2xra2pfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjZWhvnWlpYmRtZmltcGplZFqin5t1YWBobW5qcGxia2NmZ2twbzE$]]>  
    6.         </encode>  
    7.         <decode>  
    8.             <![CDATA[44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931&mid=0.59949419022597]]>  
    9.         </decode>  
    10.         <type>8</type>  
    11.         <lrcid>64644</lrcid>  
    12.         <flag>1</flag>  
    13.     </url>  
    14.     <durl>  
    15.         <encode>  
    16.             <![CDATA[http://zhangmenshiting2.baidu.com/data2/music/44277530/ZWZla2xramhfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjaGhvnZ5qlGRpbpedamJla1qin5t1YWBobW5qcGxia2NmZ2twbzE$]]>  
    17.         </encode>  
    18.         <decode>  
    19.             <![CDATA[44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138&mid=0.59949419022597]]>  
    20.         </decode>  
    21.         <type>8</type>  
    22.         <lrcid>64644</lrcid>  
    23.         <flag>1</flag>  
    24.     </durl>  
    25.     <p2p>  
    26.         <hash>022bc0fbf66cd19bea96db49634419dc2600393f</hash>  
    27.         <url>  
    28.             <![CDATA[ ]]>  
    29.         </url>  
    30.         <type>mp3</type>  
    31.         <size>5236902</size>  
    32.         <bitrate>192</bitrate>  
    33.     </p2p>  
    34. </result>  
    <result>
    	<count>1</count>
    	<url>
    		<encode>
    			<![CDATA[http://zhangmenshiting.baidu.com/data2/music/44277542/ZWZla2xra2pfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjZWhvnWlpYmRtZmltcGplZFqin5t1YWBobW5qcGxia2NmZ2twbzE$]]>
    		</encode>
    		<decode>
    			<![CDATA[44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931&mid=0.59949419022597]]>
    		</decode>
    		<type>8</type>
    		<lrcid>64644</lrcid>
    		<flag>1</flag>
    	</url>
    	<durl>
    		<encode>
    			<![CDATA[http://zhangmenshiting2.baidu.com/data2/music/44277530/ZWZla2xramhfn6NndK6ap5WXcJVob5puZ2trbWprmnBjZ2xolpeZa2drZmWZmZmdl2hjaGhvnZ5qlGRpbpedamJla1qin5t1YWBobW5qcGxia2NmZ2twbzE$]]>
    		</encode>
    		<decode>
    			<![CDATA[44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138&mid=0.59949419022597]]>
    		</decode>
    		<type>8</type>
    		<lrcid>64644</lrcid>
    		<flag>1</flag>
    	</durl>
    	<p2p>
    		<hash>022bc0fbf66cd19bea96db49634419dc2600393f</hash>
    		<url>
    			<![CDATA[ ]]>
    		</url>
    		<type>mp3</type>
    		<size>5236902</size>
    		<bitrate>192</bitrate>
    	</p2p>
    </result>

    返回结果中的主要参数解释例如以下:

    1)<count> 表示搜索到的音乐数;

    2)<url>中包括了普通品质的音乐链接,<durl>中包括了高品质音乐的链接;

    3)<encode>中包括了加密后的音乐链接,实际上仅仅是对音乐名称进行了加密,<decode>中包括了解密后的音乐名称。因此,要获取音乐的链接就须要重点分析<encode>和<decode>中的内容,以下会专门为读者进行介绍。

    4)<type>表示音乐文件的类型,如rm、wma、mp3等;

    5)<lrcid>是歌词的ID,<url>中的歌词ID为64644,那么怎样得到歌词呢?本例并不关心歌词,仅仅是附带提一下。歌词的地址例如以下:

    1. http://box.zhangmen.baidu.com/bdlrc/646/64644.lrc  
    http://box.zhangmen.baidu.com/bdlrc/646/64644.lrc

    当中,http://box.zhangmen.baidu.com/bdlrc/是固定值;646为歌词所在文件夹名,计算方法为歌词ID(64644)除以100,取整数部分;64644.lrc是歌词文件名称。

    以下来看怎样从<encode>和<decode>中得到音乐链接。为了便于说明,笔者将上面搜索结果中的<url>和<durl>部分抽取出来,并进行了标注,例如以下图所看到的。

    上图中,1和2拼接起来是普通品质音乐的链接,3和4拼接起来是高品质音乐的链接。也就是说,普通品质和高品质的音乐链接例如以下:

    1. // 普通品质音乐链接  
    2. http://zhangmenshiting.baidu.com/data2/music/44277542/44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931  
    3. // 高品质音乐链接  
    4. http://zhangmenshiting2.baidu.com/data2/music/44277530/44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138  
    // 普通品质音乐链接
    http://zhangmenshiting.baidu.com/data2/music/44277542/44277542.mp3?xcode=a39c6698955c82594aab36931dcbef60139f180191368931
    // 高品质音乐链接
    http://zhangmenshiting2.baidu.com/data2/music/44277530/44277530.mp3?xcode=a39c6698955c82594aab36931dcbef60439ff9b159af2138

    参数xcode能够理解为随机验证码,每次搜索得到的值都不一样,假设不带该参数会报未授权异常“401 Authorization Required”。须要注意的是,xcode是有时间限制的,超过限制再訪问链接会报异常:{"Error":{"code":"2","Message":"object not exists","LogId":"3456414897"}}。在xcode有效的前提下,通过浏览器訪问上面的音乐链接,会提示下载音乐。

    编程调用百度音乐搜索API

    知道怎样从API返回结果中得到音乐链接后,就能够编敲代码来实现了。笔者将发送HTTP请求、URL编码、解析XML等操作所有封装在BaiduMusicService类中,该类的代码例如以下:

    1. import java.io.InputStream;  
    2. import java.io.UnsupportedEncodingException;  
    3. import java.net.HttpURLConnection;  
    4. import java.net.URL;  
    5. import java.util.List;  
    6. import org.dom4j.Document;  
    7. import org.dom4j.Element;  
    8. import org.dom4j.io.SAXReader;  
    9. import org.liufeng.course.message.resp.Music;  
    10.  * 百度音乐搜索API操作类 
    11.  * @author liufeng 
    12.  * @date 2013-12-09 
    13. public class BaiduMusicService {  
    14.      * 依据名称和作者搜索音乐 
    15.      * @param musicTitle 音乐名称 
    16.      * @param musicAuthor 音乐作者 
    17.      * @return Music 
    18.     public static Music searchMusic(String musicTitle, String musicAuthor) {  
    19.         // 百度音乐搜索地址  
    20.         String requestUrl = "http://box.zhangmen.baidu.com/x?op=12&count=1&title={TITLE}$${AUTHOR}$$$$";  
    21.         // 对音乐名称、作者进URL编码  
    22.         requestUrl = requestUrl.replace("{TITLE}", urlEncodeUTF8(musicTitle));  
    23.         requestUrl = requestUrl.replace("{AUTHOR}", urlEncodeUTF8(musicAuthor));  
    24.         // 处理名称、作者中间的空格  
    25.         requestUrl = requestUrl.replaceAll("\+", "%20");  
    26.         // 查询并获取返回结果  
    27.         InputStream inputStream = httpRequest(requestUrl);  
    28.         // 从返回结果中解析出Music  
    29.         Music music = parseMusic(inputStream);  
    30.         // 假设music不为null,设置标题和描写叙述  
    31.         if (null != music) {  
    32.             music.setTitle(musicTitle);  
    33.             // 假设作者不为"",将描写叙述设置为作者  
    34.             if (!"".equals(musicAuthor))  
    35.                 music.setDescription(musicAuthor);  
    36.                 music.setDescription("来自百度音乐");  
    37.         return music;  
    38.      * UTF-8编码 
    39.      * @param source 
    40.      * @return 
    41.     private static String urlEncodeUTF8(String source) {  
    42.         String result = source;  
    43.             result = java.net.URLEncoder.encode(source, "UTF-8");  
    44.         } catch (UnsupportedEncodingException e) {  
    45.             e.printStackTrace();  
    46.         return result;  
    47.      * 发送http请求取得返回的输入流 
    48.      * @param requestUrl 请求地址 
    49.      * @return InputStream 
    50.     private static InputStream httpRequest(String requestUrl) {  
    51.         InputStream inputStream = null;  
    52.             URL url = new URL(requestUrl);  
    53.             HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();  
    54.             httpUrlConn.setDoInput(true);  
    55.             httpUrlConn.setRequestMethod("GET");  
    56.             httpUrlConn.connect();  
    57.             // 获得返回的输入流  
    58.             inputStream = httpUrlConn.getInputStream();  
    59.         } catch (Exception e) {  
    60.             e.printStackTrace();  
    61.         return inputStream;  
    62.      * 解析音乐参数 
    63.      * @param inputStream 百度音乐搜索API返回的输入流 
    64.      * @return Music 
    65.     @SuppressWarnings("unchecked")  
    66.     private static Music parseMusic(InputStream inputStream) {  
    67.         Music music = null;  
    68.             // 使用dom4j解析xml字符串  
    69.             SAXReader reader = new SAXReader();  
    70.             Document document = reader.read(inputStream);  
    71.             // 得到xml根元素  
    72.             Element root = document.getRootElement();  
    73.             // count表示搜索到的歌曲数  
    74.             String count = root.element("count").getText();  
    75.             // 当搜索到的歌曲数大于0时  
    76.             if (!"0".equals(count)) {  
    77.                 // 普通品质  
    78.                 List<Element> urlList = root.elements("url");  
    79.                 // 高品质  
    80.                 List<Element> durlList = root.elements("durl");  
    81.                 // 普通品质的encode、decode  
    82.                 String urlEncode = urlList.get(0).element("encode").getText();  
    83.                 String urlDecode = urlList.get(0).element("decode").getText();  
    84.                 // 普通品质音乐的URL  
    85.                 String url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode;  
    86.                 if (-1 != urlDecode.lastIndexOf("&"))  
    87.                     url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode.substring(0, urlDecode.lastIndexOf("&"));  
    88.                 // 默认情况下,高音质音乐的URL 等于 普通品质音乐的URL  
    89.                 String durl = url;  
    90.                 // 推断高品质节点是否存在  
    91.                 Element durlElement = durlList.get(0).element("encode");  
    92.                 if (null != durlElement) {  
    93.                     // 高品质的encode、decode  
    94.                     String durlEncode = durlList.get(0).element("encode").getText();  
    95.                     String durlDecode = durlList.get(0).element("decode").getText();  
    96.                     // 高品质音乐的URL  
    97.                     durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode;  
    98.                     if (-1 != durlDecode.lastIndexOf("&"))  
    99.                         durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode.substring(0, durlDecode.lastIndexOf("&"));  
    100.                 music = new Music();  
    101.                 // 设置普通品质音乐链接  
    102.                 music.setMusicUrl(url);  
    103.                 // 设置高品质音乐链接  
    104.                 music.setHQMusicUrl(durl);  
    105.         } catch (Exception e) {  
    106.             e.printStackTrace();  
    107.         return music;  
    108.     // 測试方法  
    109.     public static void main(String[] args) {  
    110.         Music music = searchMusic("相信自己", "零点乐队");  
    111.         System.out.println("音乐名称:" + music.getTitle());  
    112.         System.out.println("音乐描写叙述:" + music.getDescription());  
    113.         System.out.println("普通品质链接:" + music.getMusicUrl());  
    114.         System.out.println("高品质链接:" + music.getHQMusicUrl());  
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import org.liufeng.course.message.resp.Music;
    
    /**
     * 百度音乐搜索API操作类
     * 
     * @author liufeng
     * @date 2013-12-09
     */
    public class BaiduMusicService {
    	/**
    	 * 依据名称和作者搜索音乐
    	 * 
    	 * @param musicTitle 音乐名称
    	 * @param musicAuthor 音乐作者
    	 * @return Music
    	 */
    	public static Music searchMusic(String musicTitle, String musicAuthor) {
    		// 百度音乐搜索地址
    		String requestUrl = "http://box.zhangmen.baidu.com/x?op=12&count=1&title={TITLE}$${AUTHOR}$$$$";
    		// 对音乐名称、作者进URL编码
    		requestUrl = requestUrl.replace("{TITLE}", urlEncodeUTF8(musicTitle));
    		requestUrl = requestUrl.replace("{AUTHOR}", urlEncodeUTF8(musicAuthor));
    		// 处理名称、作者中间的空格
    		requestUrl = requestUrl.replaceAll("\+", "%20");
    
    		// 查询并获取返回结果
    		InputStream inputStream = httpRequest(requestUrl);
    		// 从返回结果中解析出Music
    		Music music = parseMusic(inputStream);
    
    		// 假设music不为null,设置标题和描写叙述
    		if (null != music) {
    			music.setTitle(musicTitle);
    			// 假设作者不为"",将描写叙述设置为作者
    			if (!"".equals(musicAuthor))
    				music.setDescription(musicAuthor);
    			else
    				music.setDescription("来自百度音乐");
    		}
    		return music;
    	}
    
    	/**
    	 * UTF-8编码
    	 * 
    	 * @param source
    	 * @return
    	 */
    	private static String urlEncodeUTF8(String source) {
    		String result = source;
    		try {
    			result = java.net.URLEncoder.encode(source, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    		}
    		return result;
    	}
    
    	/**
    	 * 发送http请求取得返回的输入流
    	 * 
    	 * @param requestUrl 请求地址
    	 * @return InputStream
    	 */
    	private static InputStream httpRequest(String requestUrl) {
    		InputStream inputStream = null;
    		try {
    			URL url = new URL(requestUrl);
    			HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
    			httpUrlConn.setDoInput(true);
    			httpUrlConn.setRequestMethod("GET");
    			httpUrlConn.connect();
    			// 获得返回的输入流
    			inputStream = httpUrlConn.getInputStream();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return inputStream;
    	}
    
    	/**
    	 * 解析音乐参数
    	 * 
    	 * @param inputStream 百度音乐搜索API返回的输入流
    	 * @return Music
    	 */
    	@SuppressWarnings("unchecked")
    	private static Music parseMusic(InputStream inputStream) {
    		Music music = null;
    		try {
    			// 使用dom4j解析xml字符串
    			SAXReader reader = new SAXReader();
    			Document document = reader.read(inputStream);
    			// 得到xml根元素
    			Element root = document.getRootElement();
    			// count表示搜索到的歌曲数
    			String count = root.element("count").getText();
    			// 当搜索到的歌曲数大于0时
    			if (!"0".equals(count)) {
    				// 普通品质
    				List<Element> urlList = root.elements("url");
    				// 高品质
    				List<Element> durlList = root.elements("durl");
    
    				// 普通品质的encode、decode
    				String urlEncode = urlList.get(0).element("encode").getText();
    				String urlDecode = urlList.get(0).element("decode").getText();
    				// 普通品质音乐的URL
    				String url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode;
    				if (-1 != urlDecode.lastIndexOf("&"))
    					url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode.substring(0, urlDecode.lastIndexOf("&"));
    
    				// 默认情况下,高音质音乐的URL 等于 普通品质音乐的URL
    				String durl = url;
    
    				// 推断高品质节点是否存在
    				Element durlElement = durlList.get(0).element("encode");
    				if (null != durlElement) {
    					// 高品质的encode、decode
    					String durlEncode = durlList.get(0).element("encode").getText();
    					String durlDecode = durlList.get(0).element("decode").getText();
    					// 高品质音乐的URL
    					durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode;
    					if (-1 != durlDecode.lastIndexOf("&"))
    						durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode.substring(0, durlDecode.lastIndexOf("&"));
    				}
    				music = new Music();
    				// 设置普通品质音乐链接
    				music.setMusicUrl(url);
    				// 设置高品质音乐链接
    				music.setHQMusicUrl(durl);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return music;
    	}
    
    	// 測试方法
    	public static void main(String[] args) {
    		Music music = searchMusic("相信自己", "零点乐队");
    		System.out.println("音乐名称:" + music.getTitle());
    		System.out.println("音乐描写叙述:" + music.getDescription());
    		System.out.println("普通品质链接:" + music.getMusicUrl());
    		System.out.println("高品质链接:" + music.getHQMusicUrl());
    	}
    }

    以下对代码进行简单的说明:

    1)代码中的Music类是对音乐消息的封装(不包括ThumbMediaId参数),读者能够在本系列教程的第4篇中找到该类的定义;

    2)执行上述代码须要引入dom4j的JAR包,笔者使用的是dom4j-1.6.1.jar;

    3)searchMusic()方法是提供给外部调用的,在CoreService类中会调用该方法获得音乐消息须要的Music相关的4个参数(Title、Description、MusicUrl和HQMusicUrl);

    4)parseMusic()方法用于解析XML,读者能够结合代码中的凝视和之前对XML的分析进行理解,这里就不再赘述了。

    5)116行、127行中的get(0)表示返回多条音乐结果时默认取第一条。

    公众账号后台的实现

    在公众账号后台的CoreService类中,须要对用户发送的文本消息进行推断,假设是以“歌曲”两个字开头,就觉得用户是在使用“歌曲点播”功能,此时须要对“歌曲”两个字之后的内容进行推断,假设包括“@”符号,就表示须要按演唱者搜索,否则不指定演唱者。CoreService类的完整代码例如以下:

    1. package org.liufeng.course.service;  
    2. import java.util.Date;  
    3. import java.util.Map;  
    4. import javax.servlet.http.HttpServletRequest;  
    5. import org.liufeng.course.message.resp.Music;  
    6. import org.liufeng.course.message.resp.MusicMessage;  
    7. import org.liufeng.course.message.resp.TextMessage;  
    8. import org.liufeng.course.util.MessageUtil;  
    9.  * 核心服务类 
    10.  * @author liufeng 
    11.  * @date 2013-12-10 
    12. public class CoreService {  
    13.      * 处理微信发来的请求 
    14.      * @param request 
    15.      * @return 
    16.     public static String processRequest(HttpServletRequest request) {  
    17.         // 返回给微信server的xml消息  
    18.         String respXml = null;  
    19.         // 文本消息内容  
    20.         String respContent = null;  
    21.             // xml请求解析  
    22.             Map<String, String> requestMap = MessageUtil.parseXml(request);  
    23.             // 发送方帐号(open_id)  
    24.             String fromUserName = requestMap.get("FromUserName");  
    25.             // 公众帐号  
    26.             String toUserName = requestMap.get("ToUserName");  
    27.             // 消息类型  
    28.             String msgType = requestMap.get("MsgType");  
    29.             // 回复文本消息  
    30.             TextMessage textMessage = new TextMessage();  
    31.             textMessage.setToUserName(fromUserName);  
    32.             textMessage.setFromUserName(toUserName);  
    33.             textMessage.setCreateTime(new Date().getTime());  
    34.             textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);  
    35.             // 文本消息  
    36.             if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {  
    37.                 // 文本消息内容  
    38.                 String content = requestMap.get("Content").trim();  
    39.                 // 假设以“歌曲”2个字开头  
    40.                 if (content.startsWith("歌曲")) {  
    41.                     // 将歌曲2个字及歌曲后面的+、空格、-等特殊符号去掉  
    42.                     String keyWord = content.replaceAll("^歌曲[\+ ~!@#%^-_=]?", "");  
    43.                     // 假设歌曲名称为空  
    44.                     if ("".equals(keyWord)) {  
    45.                         respContent = getUsage();  
    46.                     } else {  
    47.                         String[] kwArr = keyWord.split("@");  
    48.                         // 歌曲名称  
    49.                         String musicTitle = kwArr[0];  
    50.                         // 演唱者默觉得空  
    51.                         String musicAuthor = "";  
    52.                         if (2 == kwArr.length)  
    53.                             musicAuthor = kwArr[1];  
    54.                         // 搜索音乐  
    55.                         Music music = BaiduMusicService.searchMusic(musicTitle, musicAuthor);  
    56.                         // 未搜索到音乐  
    57.                         if (null == music) {  
    58.                             respContent = "对不起,沒有找到你想听的歌曲<" + musicTitle + ">。";  
    59.                         } else {  
    60.                             // 音乐消息  
    61.                             MusicMessage musicMessage = new MusicMessage();  
    62.                             musicMessage.setToUserName(fromUserName);  
    63.                             musicMessage.setFromUserName(toUserName);  
    64.                             musicMessage.setCreateTime(new Date().getTime());  
    65.                             musicMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_MUSIC);  
    66.                             musicMessage.setMusic(music);  
    67.                             respXml = MessageUtil.musicMessageToXml(musicMessage);  
    68.             // 未搜索到音乐时返回使用指南  
    69.             if (null == respXml) {  
    70.                 if (null == respContent)  
    71.                     respContent = getUsage();  
    72.                 textMessage.setContent(respContent);  
    73.                 respXml = MessageUtil.textMessageToXml(textMessage);  
    74.         } catch (Exception e) {  
    75.             e.printStackTrace();  
    76.         return respXml;  
    77.      * 歌曲点播使用指南 
    78.      * @return 
    79.     public static String getUsage() {  
    80.         StringBuffer buffer = new StringBuffer();  
    81.         buffer.append("歌曲点播操作指南").append(" ");  
    82.         buffer.append("回复:歌曲+歌名").append(" ");  
    83.         buffer.append("比如:歌曲存在").append(" ");  
    84.         buffer.append("或者:歌曲存在@汪峰").append(" ");  
    85.         buffer.append("回复“?”显示主菜单");  
    86.         return buffer.toString();  
    package org.liufeng.course.service;
    
    import java.util.Date;
    import java.util.Map;
    import javax.servlet.http.HttpServletRequest;
    import org.liufeng.course.message.resp.Music;
    import org.liufeng.course.message.resp.MusicMessage;
    import org.liufeng.course.message.resp.TextMessage;
    import org.liufeng.course.util.MessageUtil;
    
    /**
     * 核心服务类
     * 
     * @author liufeng
     * @date 2013-12-10
     */
    public class CoreService {
    	/**
    	 * 处理微信发来的请求
    	 * 
    	 * @param request
    	 * @return
    	 */
    	public static String processRequest(HttpServletRequest request) {
    		// 返回给微信server的xml消息
    		String respXml = null;
    		// 文本消息内容
    		String respContent = null;
    		try {
    			// xml请求解析
    			Map<String, String> requestMap = MessageUtil.parseXml(request);
    			// 发送方帐号(open_id)
    			String fromUserName = requestMap.get("FromUserName");
    			// 公众帐号
    			String toUserName = requestMap.get("ToUserName");
    			// 消息类型
    			String msgType = requestMap.get("MsgType");
    
    			// 回复文本消息
    			TextMessage textMessage = new TextMessage();
    			textMessage.setToUserName(fromUserName);
    			textMessage.setFromUserName(toUserName);
    			textMessage.setCreateTime(new Date().getTime());
    			textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
    
    			// 文本消息
    			if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {
    				// 文本消息内容
    				String content = requestMap.get("Content").trim();
    				// 假设以“歌曲”2个字开头
    				if (content.startsWith("歌曲")) {
    					// 将歌曲2个字及歌曲后面的+、空格、-等特殊符号去掉
    					String keyWord = content.replaceAll("^歌曲[\+ ~!@#%^-_=]?", "");
    					// 假设歌曲名称为空
    					if ("".equals(keyWord)) {
    						respContent = getUsage();
    					} else {
    						String[] kwArr = keyWord.split("@");
    						// 歌曲名称
    						String musicTitle = kwArr[0];
    						// 演唱者默觉得空
    						String musicAuthor = "";
    						if (2 == kwArr.length)
    							musicAuthor = kwArr[1];
    
    						// 搜索音乐
    						Music music = BaiduMusicService.searchMusic(musicTitle, musicAuthor);
    						// 未搜索到音乐
    						if (null == music) {
    							respContent = "对不起,沒有找到你想听的歌曲<" + musicTitle + ">。";
    						} else {
    							// 音乐消息
    							MusicMessage musicMessage = new MusicMessage();
    							musicMessage.setToUserName(fromUserName);
    							musicMessage.setFromUserName(toUserName);
    							musicMessage.setCreateTime(new Date().getTime());
    							musicMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_MUSIC);
    							musicMessage.setMusic(music);
    							respXml = MessageUtil.musicMessageToXml(musicMessage);
    						}
    					}
    				}
    			}
    			// 未搜索到音乐时返回使用指南
    			if (null == respXml) {
    				if (null == respContent)
    					respContent = getUsage();
    				textMessage.setContent(respContent);
    				respXml = MessageUtil.textMessageToXml(textMessage);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return respXml;
    	}
    
    	/**
    	 * 歌曲点播使用指南
    	 * 
    	 * @return
    	 */
    	public static String getUsage() {
    		StringBuffer buffer = new StringBuffer();
    		buffer.append("歌曲点播操作指南").append("
    
    ");
    		buffer.append("回复:歌曲+歌名").append("
    ");
    		buffer.append("比如:歌曲存在").append("
    ");
    		buffer.append("或者:歌曲存在@汪峰").append("
    
    ");
    		buffer.append("回复“?”显示主菜单");
    		return buffer.toString();
    	}
    }

    上述代码的逻辑比較简单,用户发送“歌曲+名称”或者“歌曲+名称@演唱者”就能搜索歌曲,搜索不到时会提示用户,假设发送其它内容回复歌曲点播功能的使用方法。

    PS:CSDN2013年度博客之星评选活动已经拉开序幕,2013年12月14日開始投票,请为柳峰(用户名:lyq8479)投上您的宝贵一票,谢谢!

    投票地址:http://vote.blog.csdn.net/blogstaritem/blogstar2013/lyq8479

    转帖请注明本文出自柳峰的博客(http://blog.csdn.net/lyq8479),请尊重他人的辛勤劳动成果,谢谢!

  • 相关阅读:
    PHP MySQL 插入多条数据
    PHP MySQL 插入数据
    PHP MySQL 创建数据表
    PHP MySQL 创建数据库
    PHP 连接 MySQL
    PHP MySQL 简介
    PHP JSON
    12_短信发送器_发送短信实现
    11_短信发送器_快速回复页面实现
    10_短信发送器_获取电话号码
  • 原文地址:https://www.cnblogs.com/mfryf/p/3598797.html
Copyright © 2020-2023  润新知