微信公众号数据交互原理图解,接入开发模式代码展示java

BSO 2020-09-07 10:03:42 java常见问答 4698

学习java是一个漫长的过程,这需要学习的人投入大量的精力和时间沉浸其中,才能有所得。今天主要为大家介绍一下,微信公众号数据交互原理图解,以及展示接入开发模式和响应的代码。

1.首先我们应该准备:微信公众号和外网映射工具(开发调试)。并且与微信的对接的URL应该可以满足两个条件,一是在公网上能够访问,二是只支持80端口;如下图所示:

微信公众号数据交互原理图解

微信公众号数据交互原理图解

然后进入微信公众号平台,再进入开发者中心,在开发者中心中找到开发者文档,实现代码展示如下:

package org.gpf.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.gpf.util.CheckUtil;
/**
 * 接收微信服务器发送的4个参数并返回echostr
 */
public class WeixinServlet extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        // 接收微信服务器以Get请求发送的4个参数
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        PrintWriter out = response.getWriter();
        if (CheckUtil.checkSignature(signature, timestamp, nonce))
        {
            out.print(echostr); // 校验通过,原样返回echostr参数内容
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        doGet(request, response);
    }
}

校验工具类代码展示如下:

package org.gpf.util;
import java.util.Arrays;
import org.apache.commons.codec.digest.DigestUtils;
/**
 * 校验的工具类
 */
public class CheckUtil
{
    private static final String token = "weixin";
    public static boolean checkSignature(String signature, String timestamp, String nonce)
    {
        String[] arr = new String[]
        {
            token
            , timestamp
            , nonce
        };
        // 排序
        Arrays.sort(arr);
        // 生成字符串
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++)
        {
            content.append(arr[i]);
        }
        // sha 1加密
        String temp = getSHA 1String(content.toString());
        return temp.equals(signature); // 与微信传递过来的签名进行比较
    }
    private static String getSHA 1String(String data)
    {
        return DigestUtils.sha 1Hex(data); // 使用commons codec生成sha 1字符串
    }
}

Servlet配置代码展示如下:

servlet >
    <servlet-name>WeixinServlet</servlet-name> <
    servlet - class > org.gpf.servlet.WeixinServlet < /servlet-class> <
    /servlet> <
    servlet - mapping >
    <servlet-name>WeixinServlet</servlet-name> <
    url - pattern > /wx.do</url - pattern >
    </servlet-mapping>

接下来通过映射工具将本地的服务器映射到公网,从公网访问Servlet。图片展示如下:

微信公众号接入开发模式

需要注意的是,开发模式和编辑模式是互斥的,如果启动了开发模式,那么自定义菜单和自动回复将失效。

2.然后是消息的接收和响应

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。所以需要更改我们的Servlet中的doPost方法,因为微信服务器与我们的服务器之间是通过XML传递数据的,所以需要实现消息实体与XML之间的互相转换。可以采用第三方jar包XStream完成。

处理微信服务器与本机服务器进行交互的Servlet代码展示如下:

package org.gpf.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.DocumentException;
import org.gpf.po.TextMeaasge;
import org.gpf.util.CheckUtil;
import org.gpf.util.MessageUtil;
/**
 * 微信消息的接收和响应
 */
public class WeixinServlet extends HttpServlet
{
    /**
     * 接收微信服务器发送的4个参数并返回echostr
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        // 接收微信服务器以Get请求发送的4个参数
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        PrintWriter out = response.getWriter();
        if (CheckUtil.checkSignature(signature, timestamp, nonce))
        {
            out.print(echostr); // 校验通过,原样返回echostr参数内容
        }
    }
    /**
     * 接收并处理微信客户端发送的请求
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/xml;charset=utf-8");
        PrintWriter out = response.getWriter();
        try
        {
            Map < String, String > map = MessageUtil.xmlToMap(request);
            String toUserName = map.get("ToUserName");
            String fromUserName = map.get("FromUserName");
            String msgType = map.get("MsgType");
            String content = map.get("Content");
            String message = null;
            if ("text".equals(msgType))
            { // 对文本消息进行处理
                TextMeaasge text = new TextMeaasge();
                text.setFromUserName(toUserName); // 发送和回复是反向的
                text.setToUserName(fromUserName);
                text.setMsgType("text");
                text.setCreateTime(new Date()
                    .getTime());
                text.setContent("你发送的消息是:" + content);
                message = MessageUtil.textMessageToXML(text);
                System.out.println(message);
            }
            out.print(message); // 将回应发送给微信服务器
        }
        catch (DocumentException e)
        {
            e.printStackTrace();
        }
        finally
        {
            out.close();
        }
    }
}

按照微信的接口文档编写的文本消息实体类代码展示如下:

package org.gpf.util;
import java.io.IOException;
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.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.gpf.po.TextMeaasge;
import com.thoughtworks.xstream.XStream;
/**
 * 实现消息的格式转换(Map类型和XML的互转)
 */
public class MessageUtil
{
    /**
     * 将XML转换成Map集合
     */
    public static Map < String, String > xmlToMap(HttpServletRequest request) throws IOException, DocumentException
    {
        Map < String, String > map = new HashMap < String, String > ();
        SAXReader reader = new SAXReader(); // 使用dom4j解析xml
        InputStream ins = request.getInputStream(); // 从request中获取输入流
        Document doc = reader.read(ins);
        Element root = doc.getRootElement(); // 获取根元素
        List < Element > list = root.elements(); // 获取所有节点
        for (Element e: list)
        {
            map.put(e.getName(), e.getText());
            System.out.println(e.getName() + "--->" + e.getText());
        }
        ins.close();
        return map;
    }
    /**
     * 将文本消息对象转换成XML
     */
    public static String textMessageToXML(TextMeaasge textMessage)
    {
        XStream xstream = new XStream(); // 使用XStream将实体类的实例转换成xml格式    
        xstream.alias("xml", textMessage.getClass()); // 将xml的默认根节点替换成“xml”
        return xstream.toXML(textMessage);
    }
}

以上就是关于微信公众号数据交互原理图解,以及接入开发模式的代码展示。想要了解更多java基础,敬请关注奇Q工具网。

推荐阅读:

java微信公众号平台开发,搭建和介绍

java微信公众号平台开发,建立及接口配置展示

在java中如何用Apche CXF开发webservice,实际操作展示