微信公众平台开发之单图文和多图文消息的发送(第20篇)

2017年08月24日 10:40 | 1866次浏览 作者原创 版权保护

好多初学者对于微信公众号的图文消息比较中意,因为图文消息看起来整洁,美观,给人的可视化眼球感觉比较舒服,让人点击的愿望比较强烈,所以在这里呢介绍两种图文消息,单图文消息和多图文消息的回复

咱们首先看看微信公众平台官方文档对图文消息的参数的定义。

参数ArticleCount图文消息的个数,目前被限制在10个以内。这个值必须有否则消息不予与显示。

PicUrl是图片地址,本案例中用了四个图片,把这四个图片上传到服务器上,最好在电脑的浏览器中测试打开图片地址,验证是否正确读取。

第一、准备四张图片,分别为test1.png、test2.png、test3.png、test4.png,然后上传到服务器目录下

第二、servelet的doPost方法编写,当用户向公众号发送123的时候回复用户单图文,发送456的时候回复多图文

/**
	 * 处理微信服务器发来的消息
	 * 实例源码在文章顶部有下载连接
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		System.out.println("V型知识库原创www.vxzsk.com");
        // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        try{
        //xml请求解析
        Map<String, String> requestMap = MessageUtil.parseXml(request);//接收微信发过来的xml格式
        //发送方帐号(open_id)
        String fromUserName = requestMap.get("FromUserName");
        //公众帐号
        String toUserName = requestMap.get("ToUserName");
        //消息类型
        String msgType = requestMap.get("MsgType");
        //消息创建时间
        String createTime = requestMap.get("CreateTime");
        //微信服务器post过来的内容
        String weixinContent = requestMap.get("Content");
        System.out.println("公众号用户发送过来的文本消息内容:"+weixinContent);
        //向微信发送图文消息
        String respMessage =null;
        if(weixinContent.equals("123")){//用户通过关注微信公众号发送123文本内容 单图文消息
                respMessage = "<xml>"
                +"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"
                +"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"
                +"<CreateTime>12345678</CreateTime>"
                +"<MsgType><![CDATA[news]]></MsgType>"
                +"<ArticleCount>1</ArticleCount>"
                +"<Articles>"
                +"<item>"
                +"<Title><![CDATA[我是图片1的标题-单图文消息]]></Title> "
                +"<Description><![CDATA[图片1内容]]></Description>"
                +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test1.png]]></PicUrl>"//项目图片地址
                +"<Url><![CDATA[http://www.vxzsk.com?openid="+toUserName+"]]></Url>"//自己工程项目地址 例如:http://ip/项目名/queryList.do?openid=toUserName
                +"</item>"
                
                +"</Articles>"
                +"</xml>";
        
        }else if(weixinContent.equals("456")){//多图文消息
        	    respMessage = "<xml>"
                    +"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"
                    +"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"
                    +"<CreateTime>12345678</CreateTime>"
                    +"<MsgType><![CDATA[news]]></MsgType>"
                    +"<ArticleCount>4</ArticleCount>" //四个
                    +"<Articles>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片1的标题]]></Title> "
                    +"<Description><![CDATA[图片1内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test1.png]]></PicUrl>"//项目图片地址
                    +"<Url><![CDATA[http://www.vxzsk.com?openid="+toUserName+"]]></Url>"//自己工程项目地址 例如:http://ip/项目名/queryList.do?openid=toUserName
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片2的标题]]></Title>"
                    +"<Description><![CDATA[图片2内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test2.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片3的标题]]></Title>"
                    +"<Description><![CDATA[图片3内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test3.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片4的标题]]></Title>"
                    +"<Description><![CDATA[图片4内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test4.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"</Articles>"
                    +"</xml>";
        }
        System.out.println("回复图文消息成功----------------------");
        
     // 响应回复消息
        PrintWriter out = response.getWriter();
        out.print(respMessage);
        out.close();
         
        }catch(Exception e){
            e.printStackTrace();
        }
        }

1、用户向微信公众号发送123

2、用户向微信公众号发送456

1)我们可以发现,在多图文消息中,默认第一张图片为图文消息的第一条,最好图片大小640*320,剩下的图片大小可设置80*80最佳。

2)图文消息中,图片的连接地址并非一定要是内部连接地址,也可以是外部连接地址,图文消息的Url也就是跳转地址可以是内部连接地址,也可以是外部连接地址,例如代码案例中我设置的是百度的地址。

3)图文消息的描述,标题可以使用换行符("\n"),这样使得标题,描述更简洁整齐宜读。

4)单图文的描述才会显示,多图文的描述是不被显示的。

5)根据微信官方文档如参数说明Url跳转地址可以为空,但是最好不要为空,因为如果为空的话,android机器点击无反应,但是在ios系统下会跳转到一个空白页面,用户体验非常不好。

第三、完整代码如下

WeChatServlet

package com.test;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.test.message.MessageUtil;

/**
 * 核心请求处理类
 * @author V型知识库 www.vxzsk.com
 *
 * doGet方法里 有个weixinTest,这个是公众管理平台里面自己设置的token 大家根据自己的token替换
 */
public class WeChatServlet extends HttpServlet {
		
	private static final long serialVersionUID = 1508798736675904038L;
	
	/**
	 * 确认请求来自微信服务器
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("V型知识库原创www.vxzsk.com");
		// 微信加密签名
		String signature = request.getParameter("signature");
		System.out.println("微信加密签名signature:-----------------------"+signature);
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		System.out.println("时间戳timestamp:-----------------------"+timestamp);
		// 随机数
		String nonce = request.getParameter("nonce");
		System.out.println("随机数nonce:-----------------------"+nonce);
		// 随机字符串
		String echostr = request.getParameter("echostr");
		System.out.println("随机字符串echostr:-----------------------"+echostr);
		//System.out.println("token-----------------------:"+token);
		
		PrintWriter out = response.getWriter();
		// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
		if (SignUtil.checkSignature("weixinTest", signature, timestamp, nonce)) {
			out.print(echostr);
			//System.out.println("这是:"+echostr);
		}
		out.close();
		out = null;
	}

	/**
	 * 处理微信服务器发来的消息
	 * 实例源码在文章顶部有下载连接
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
		System.out.println("V型知识库原创www.vxzsk.com");
        // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        try{
        //xml请求解析
        Map<String, String> requestMap = MessageUtil.parseXml(request);//接收微信发过来的xml格式
        //发送方帐号(open_id)
        String fromUserName = requestMap.get("FromUserName");
        //公众帐号
        String toUserName = requestMap.get("ToUserName");
        //消息类型
        String msgType = requestMap.get("MsgType");
        //消息创建时间
        String createTime = requestMap.get("CreateTime");
        //微信服务器post过来的内容
        String weixinContent = requestMap.get("Content");
        System.out.println("公众号用户发送过来的文本消息内容:"+weixinContent);
        //向微信发送图文消息
        String respMessage =null;
        if(weixinContent.equals("123")){//用户通过关注微信公众号发送123文本内容 单图文消息
                respMessage = "<xml>"
                +"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"
                +"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"
                +"<CreateTime>12345678</CreateTime>"
                +"<MsgType><![CDATA[news]]></MsgType>"
                +"<ArticleCount>1</ArticleCount>"
                +"<Articles>"
                +"<item>"
                +"<Title><![CDATA[我是图片1的标题-单图文消息]]></Title> "
                +"<Description><![CDATA[图片1内容]]></Description>"
                +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test1.png]]></PicUrl>"//项目图片地址
                +"<Url><![CDATA[http://www.vxzsk.com?openid="+toUserName+"]]></Url>"//自己工程项目地址 例如:http://ip/项目名/queryList.do?openid=toUserName
                +"</item>"
                
                +"</Articles>"
                +"</xml>";
        
        }else if(weixinContent.equals("456")){//多图文消息
        	    respMessage = "<xml>"
                    +"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"
                    +"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"
                    +"<CreateTime>12345678</CreateTime>"
                    +"<MsgType><![CDATA[news]]></MsgType>"
                    +"<ArticleCount>4</ArticleCount>" //四个
                    +"<Articles>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片1的标题]]></Title> "
                    +"<Description><![CDATA[图片1内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test1.png]]></PicUrl>"//项目图片地址
                    +"<Url><![CDATA[http://www.vxzsk.com?openid="+toUserName+"]]></Url>"//自己工程项目地址 例如:http://ip/项目名/queryList.do?openid=toUserName
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片2的标题]]></Title>"
                    +"<Description><![CDATA[图片2内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test2.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片3的标题]]></Title>"
                    +"<Description><![CDATA[图片3内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test3.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"<item>"
                    +"<Title><![CDATA[我是图片4的标题]]></Title>"
                    +"<Description><![CDATA[图片4内容]]></Description>"
                    +"<PicUrl><![CDATA[https://www.vxzsk.com/image/test4.png]]></PicUrl>"
                    +"<Url><![CDATA[http://www.baidu.com]]></Url>"
                    +"</item>"
                    +"</Articles>"
                    +"</xml>";
        }
        System.out.println("回复图文消息成功----------------------");
        
     // 响应回复消息
        PrintWriter out = response.getWriter();
        out.print(respMessage);
        out.close();
         
        }catch(Exception e){
            e.printStackTrace();
        }
        }
}

SignUtil

package com.test;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/***
 * 
 * @author V型知识库 www.vxzsk.com
 * 
 * 
 */
public class SignUtil {
		
	/**
	* 验证签名
	* 
	* @param signature
	* @param timestamp
	* @param nonce
	* @return
	*/
	public static boolean checkSignature(String token, String signature, String timestamp, String nonce) { 		
		String[] arr = new String[] { token, timestamp, nonce };
		// 将token、timestamp、nonce三个参数进行字典序排序
		Arrays.sort(arr);
		StringBuilder content = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		MessageDigest md = null;
		String tmpStr = null;
		try {
		md = MessageDigest.getInstance("SHA-1");
		// 将三个参数字符串拼接成一个字符串进行sha1加密
		byte[] digest = md.digest(content.toString().getBytes());
		tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
		}
		content = null;
		// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
		return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
	}
	/**
	* 将字节数组转换为十六进制字符串	
	* @param byteArray
	* @return
	*/
	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
		strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}
	/**
	* 将字节转换为十六进制字符串
	* @param mByte
	* @return
	*/
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];
		String s = new String(tempArr);
		return s;
	}
}

MessageUtil

package com.test.message;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/***
 * 
 * @author V型知识库 www.vxzsk.com
 *
 * 
 */
public class MessageUtil {
	/**
	 * 请求消息类型:推送
	 */
	public static final String REQ_MESSAGE_TYPE_EVENT = "event";

	/**
	 * 事件类型:subscribe(订阅)
	 */
	public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

	/**
	 * 事件类型:unsubscribe(取消订阅)
	 */
	public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

	/**
	 * 事件类型:CLICK(自定义菜单点击事件)
	 */
	public static final String EVENT_TYPE_CLICK = "CLICK";
    /**
     * 解析微信发来的请求(XML)
     * 
     * @param request
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();
        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
         
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();
        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        // 释放资源
        inputStream.close();
        inputStream = null;
        return map;
    }
}

dom4j.jar自行下载

此文章本站原创,地址 https://www.vxzsk.com/139.html   转载请注明出处!谢谢!

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程