java版微信公众平台后台接入

下面是“Java版微信公众平台后台接入”的完整攻略。

什么是微信公众平台后台接入

微信公众平台后台接入,又称为微信公众号开发,指的是将自己的服务与微信公众平台对接,实现在微信公众号中提供各种服务的开发行为。接入微信公众平台后,就能够使用微信公众平台提供的各种能力,比如自定义菜单、消息推送、客服消息、素材管理等。

步骤

1. 注册成为微信公众号开发者

首先需要在微信公众平台注册成为开发者,然后进入开发者中心获取开发者ID和开发者密钥。注册地址:https://mp.weixin.qq.com/

2. 构建本地开发环境

需要安装Java开发环境(JDK)、Maven(项目管理工具)和一个Java Web框架,比如Spring MVC。

3. 接入微信公众平台

3.1 配置服务器URL和token

在微信公众平台开发者中心,设置服务器URL和token,使得微信公众平台能够向开发者服务器发送请求。将token和微信服务器传送过来的参数进行比较从而验证微信服务器的身份信息。

示例:

服务器URL:http://example.com/weixin

token:MyToken

3.2 验证开发者服务器与微信服务器通信

  1. 在公众平台开发者中心,可以设置接口配置信息,输入服务器配置URL和Token,微信服务器会向开发者服务器验证身份。首先进入“开发者中心”,然后进入“基本配置”,将服务器“URL”和“Token”填入,保存即可完成服务器配置。

  2. 验证token接口。微信服务器在配置服务器后会首先尝试访问token接口,比较token的值是否和设置的值相同,从而确认身份信息。验证方法需要在开发者服务器上编写一个Controller,代码如下:

public class TokenController {
    // 与开发者中心的Token一致
    public static final String TOKEN = "MyToken";

    // 处理微信服务器发来的GET请求,进行身份验证
    @RequestMapping(value = "/", method = RequestMethod.GET)
    @ResponseBody
    public String validate(@RequestParam(value = "signature") String signature,
                           @RequestParam(value = "timestamp") String timestamp,
                           @RequestParam(value = "nonce") String nonce,
                           @RequestParam(value = "echostr") String echostr) {
        String[] arr = {TOKEN, timestamp, nonce};
        // 将Token、timestamp、nonce三个参数进行字典序排序
        Arrays.sort(arr);

        StringBuilder sb = new StringBuilder();
        for (String s : arr) {
            sb.append(s);
        }

        // 对三个参数字符串拼接成一个字符串进行SHA1加密
        String result = DigestUtils.sha1Hex(sb.toString());
        // 将加密后的字符串与signature进行比较
        if (result.equals(signature)) {
            // 验证成功后返回echostr,表示验证成功
            return echostr;
        } else {
            // 验证失败返回空
            return "";
        }
    }
}
  1. 以SpringMVC为例,将该Controller配置到web.xml文件中。
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/weixin</url-pattern>
</servlet-mapping>

4. 接收和回复消息

当用户向公众号发送消息时,微信服务器把消息传递到开发者服务器,开发者服务器接收消息后进行处理并返回响应给微信服务器,微信服务器再把响应返回给用户。

4.1 配置消息接收URL

和配置服务器URL和token一样,在微信公众平台开发者中心设置接收消息的URL。

URL:http://example.com/weixin/message

4.2 接收消息

将微信服务器发来的XML数据进行解析,将消息内容封装成Msg对象。根据不同类型的消息进行处理,比如回复文本消息、回复图片消息等。

示例:

public class MessageController {
    @RequestMapping(value = "/message", method = RequestMethod.POST)
    @ResponseBody
    public String receive(HttpServletRequest request) {
        Msg msg = parseRequestMessage(request);

        String respXml = "";
        switch (msg.getMsgType()) {
            case "text":
                respXml = buildTextResponseXml(msg, "你好,我是机器人!");
                break;
            case "image":
                respXml = buildImageResponseXml(msg, "media_id");
                break;
            default:
                break;
        }

        return respXml;
    }

    private Msg parseRequestMessage(HttpServletRequest request) {
        // 解析XML数据
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(request.getInputStream());
            Element root = doc.getDocumentElement();

            String toUserName = root.getElementsByTagName("ToUserName").item(0).getTextContent();
            String fromUserName = root.getElementsByTagName("FromUserName").item(0).getTextContent();
            String createTime = root.getElementsByTagName("CreateTime").item(0).getTextContent();
            String msgType = root.getElementsByTagName("MsgType").item(0).getTextContent();
            String content = root.getElementsByTagName("Content").item(0).getTextContent();
            String msgId = root.getElementsByTagName("MsgId").item(0).getTextContent();

            return new Msg(toUserName, fromUserName, createTime, msgType, content, msgId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private String buildTextResponseXml(Msg msg, String text) {
        // 生成回复XML
        WxOutTextMessage outMsg = new WxOutTextMessage();
        outMsg.setContentType("text");
        outMsg.setToUserName(msg.getFromUserName());
        outMsg.setFromUserName(msg.getToUserName());
        outMsg.setCreateTime(new Date().getTime());
        outMsg.setContent(text);

        return outMsg.toXml();
    }

    private String buildImageResponseXml(Msg msg, String mediaId) {
        // 生成回复XML
        WxOutImageMessage outMsg = new WxOutImageMessage();
        outMsg.setContentType("image");
        outMsg.setToUserName(msg.getFromUserName());
        outMsg.setFromUserName(msg.getToUserName());
        outMsg.setCreateTime(new Date().getTime());
        outMsg.setMediaId(mediaId);

        return outMsg.toXml();
    }
}

4.3 回复消息

根据用户发送的消息内容,确定需要回复的消息类型和内容,生成对应类型的消息XML数据。示例中,给出回复文本消息和回复图片消息的代码。

5. 其他功能实现

通过公众号开发者文档,了解微信公众平台提供的其他能力,如自定义菜单、模板消息、微信支付等,并在自己的服务中实现。

示例

示例代码:https://github.com/qianmingzhe/weixin-java-demo

示例1

实现对用户发送的文本信息自动回复。

  1. 编写一个 Controller,用于处理接收到的消息请求。
@Controller
@RequestMapping("/weixin")
public class WeixinController {
    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody String handleGetRequest(@RequestParam(value = "signature") String signature,
                                                  @RequestParam(value = "timestamp") String timestamp,
                                                  @RequestParam(value = "nonce") String nonce,
                                                  @RequestParam(value = "echostr") String echostr) {
        if (checkSignature(signature, timestamp, nonce)) {
            return echostr;
        } else {
            return "";
        }
    }

    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody String handlePostRequest(HttpServletRequest request) {
        try {
            BufferedReader reader = request.getReader();
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();

            String xml = sb.toString();
            requestMsgHandler(xml);
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    private void requestMsgHandler(String xml) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("xml", RequestMessage.class);
        RequestMessage msg = (RequestMessage) xstream.fromXML(xml);

        String msgType = msg.getMsgType();
        String content = msg.getContent();
        if ("text".equals(msgType)) {
            String replyXml = buildResponseXml(msg, "你好");
            System.out.println(replyXml);
        }
    }

    private String buildResponseXml(RequestMessage request, String content) {
        ResponseMessage response = new ResponseMessage();
        response.setToUserName(request.getFromUserName());
        response.setFromUserName(request.getToUserName());
        response.setCreateTime(System.currentTimeMillis());
        response.setMsgType("text");
        response.setContent(content);

        XStream xstream = new XStream(new DomDriver());
        xstream.alias("xml", ResponseMessage.class);
        return xstream.toXML(response);
    }

    private boolean checkSignature(String signature, String timestamp, String nonce) {
        List<String> fields = Arrays.asList("my_token", timestamp, nonce);
        Collections.sort(fields);
        String str = StringUtils.join(fields, "");
        String hex = DigestUtils.sha1Hex(str);
        return hex.equals(signature);
    }
}

  1. 配置菜单功能,用户点击菜单可以直接发送消息给公众号。

示例2

实现用户关注自动回复,关注后推送欢迎语。

  1. 编写一个 Controller,用于处理接收到的消息请求。
@Controller
@RequestMapping("/weixin")
public class WeixinController {
    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody String handleGetRequest(@RequestParam(value = "signature") String signature,
                                                  @RequestParam(value = "timestamp") String timestamp,
                                                  @RequestParam(value = "nonce") String nonce,
                                                  @RequestParam(value = "echostr") String echostr) {
        if (checkSignature(signature, timestamp, nonce)) {
            return echostr;
        } else {
            return "";
        }
    }

    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody String handlePostRequest(HttpServletRequest request) {
        try {
            BufferedReader reader = request.getReader();
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();

            String xml = sb.toString();
            requestMsgHandler(xml);
            return "";
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    private void requestMsgHandler(String xml) {
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("xml", RequestMessage.class);
        RequestMessage msg = (RequestMessage) xstream.fromXML(xml);

        if ("event".equals(msg.getMsgType()) && "subscribe".equals(msg.getEvent())) {
            String replyXml = buildResponseXml(msg, "欢迎关注我的公众号");
            System.out.println(replyXml);
        }
    }

    private String buildResponseXml(RequestMessage request, String content) {
        ResponseMessage response = new ResponseMessage();
        response.setToUserName(request.getFromUserName());
        response.setFromUserName(request.getToUserName());
        response.setCreateTime(System.currentTimeMillis());
        response.setMsgType("text");
        response.setContent(content);

        XStream xstream = new XStream(new DomDriver());
        xstream.alias("xml", ResponseMessage.class);
        return xstream.toXML(response);
    }

    private boolean checkSignature(String signature, String timestamp, String nonce) {
        List<String> fields = Arrays.asList("my_token", timestamp, nonce);
        Collections.sort(fields);
        String str = StringUtils.join(fields, "");
        String hex = DigestUtils.sha1Hex(str);
        return hex.equals(signature);
    }
}

  1. 配置菜单功能,用户点击菜单可以直接发送消息给公众号。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java版微信公众平台后台接入 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 求32位机器上unsigned int的最大值及int的最大值的解决方法

    求32位机器上unsigned int的最大值及int的最大值的解决方法 在32位机器上,unsigned int的最大值可以通过以下步骤求得: 确定机器上整数类型的位数:32位机器上,整数类型的位数为32位。 计算unsigned int的最大值:由于unsigned int是无符号整数类型,它的取值范围是从0到2^32-1。因此,unsigned int…

    other 2023年7月28日
    00
  • Java继承构造器使用过程解析

    Java继承构造器使用过程解析 在Java中,继承是一种重要的面向对象编程概念。继承是指子类从父类继承属性和方法。在继承中,子类可以使用其父类的属性和方法,同时也可以添加新的属性和方法。 在Java中,构造器是一种用于初始化对象的特殊方法。Java中的继承涉及到构造器的使用,这里将详细介绍Java继承构造器使用过程。 父类构造器 在Java中,每个类都有一个…

    other 2023年6月26日
    00
  • 红旗Linux桌面版 6.0 sp1下载地址

    红旗Linux桌面版 6.0 sp1下载地址攻略 红旗Linux桌面版 6.0 sp1是一款基于Linux操作系统的桌面版发行版。以下是详细的下载攻略: 步骤一:访问官方网站 首先,打开您的网络浏览器,并访问红旗Linux官方网站。您可以在搜索引擎中输入“红旗Linux官方网站”来找到正确的网址。 步骤二:导航到下载页面 在红旗Linux官方网站上,寻找一个…

    other 2023年8月4日
    00
  • xhost配置的是当前终端环境变量display

    xhost配置的是当前终端环境变量display 概述 在 Linux/Unix 系统中,xhost 命令用于控制 X Windows 系统下的访问控制,通过设置该命令可以限制远程主机访问当前主机的 X 服务。同时,它还可以配置当前终端环境变量 display,从而控制 X11 系统的显示。 语法 xhost 命令的通用语法如下所示: xhost [+|-]…

    其他 2023年3月28日
    00
  • iso文件怎么打开?

    ISO文件是一种光盘映像文件,通常用于存储光盘上的数据和内容。要打开ISO文件,我们需要使用虚拟光驱软件,以模拟光盘在计算机中的运行。以下是详细的攻略: 步骤1:下载和安装虚拟光驱软件 我们可以选择市面上比较知名的一些虚拟光驱软件,例如 DAEMON Tools、PowerISO、Alcohol 120% 等。这里以 DAEMON Tools 为例进行讲解。…

    其他 2023年4月16日
    00
  • redis(开发与运维):39—内存之内存消耗分析

    Redis开发与运维:内存之内存消耗分析 在Redis中,内存是非常重要的资源。在使用Redis时,我们需要了解Redis如何使用内存,以便更好地管理内存资源。本攻略将介绍Redis中内存消耗的分析方法,并提供两个示例。 内存消耗分析方法 在Redis中,我们可以使用以下命令分析内存消耗: INFO memory命令:该命令用于获取Redis实例的内存使用情…

    other 2023年5月9日
    00
  • 自己封装的一个简单的倒计时功能实例

    让我们来详细讲解如何封装一个简单的倒计时功能实例。 步骤1:创建函数 首先,我们需要创建一个名为 countdown 的函数,并包含两个参数:seconds 和 callback。其中,seconds 表示倒计时总秒数,callback 是一个回调函数,用于在倒计时结束时执行。 “`js function countdown(seconds, callba…

    other 2023年6月25日
    00
  • SpringBoot整合WebService的实现示例

    针对“SpringBoot整合WebService的实现示例”,我们可以按照以下步骤进行整合。 1. 添加依赖 在项目的pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部