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日

相关文章

  • 从一个git仓库迁移到另外一个git仓库

    从一个git仓库迁移到另外一个git仓库的完整攻略 在开发过程中,我们可能需要将一个git仓库迁移到另外一个git仓库,本文将为您提供从一个git仓库迁移到另外一个git仓库的完整攻略,包括以下内容: 克隆原始仓库 创建新仓库 将原始仓库推送到新仓库 示例说明 克隆原始仓库 首先,我们需要克隆原始库到本地。可以使用以下命令: git clone <原始…

    other 2023年5月6日
    00
  • MATLAB 的函数

    MATLAB 的函数 在MATLAB中,函数是一个用于接受输入并基于这些输入执行特定任务的代码块。在MATLAB中,您可以使用已经定义好的许多函数,并且您可以编写自己的函数来实现特定的目标。 内置函数 MATLAB自带了大量的内置函数,在MATLAB中可以通过运行help命令加上函数名来查看函数的帮助文档,例如: help sin 这将显示sine函数的帮助…

    其他 2023年3月28日
    00
  • js延迟加载的6种方式实例总结

    首先我们需要了解什么是js延迟加载。js延迟加载是指在网页中,等到网页加载完成后再加载js文件,以此提高网页加载速度和用户体验。 接下来,我们详细讲解一下js延迟加载的6种方式: defer属性 defer属性是script标签的一个属性,它告诉浏览器下载js文件的时候不会阻塞页面渲染过程,而是会等到页面渲染完成后再执行js文件。示例如下: <scri…

    other 2023年6月25日
    00
  • 电脑安装cad后word打不开无法初始化该怎么办?

    问题描述:在安装CAD软件后,打开Word可能会出现无法初始化的错误提示。 解决方案如下: 1.卸载不兼容的插件或升级插件版本 有时候Word可能会与CAD软件安装的某些插件不兼容,导致打开Word时出现无法初始化的错误。此时可以尝试卸载这些插件或将其升级到最新版本。 比如,有网友反映网上流传的“AcadInventor.dll”插件和Word2010不兼容…

    other 2023年6月20日
    00
  • C++中gSOAP的使用详解

    C++中gSOAP的使用详解 什么是gSOAP gSOAP是一个C语言开发的用于快速简便地创建Web服务的库。在使用gSOAP时,我们可以自动生成代码,这些代码可以用于在Web服务和客户端之间进行通信。gSOAP支持多种Web服务协议,包括SOAP和REST。此外,gSOAP还提供相关的工具,如WSDL编译器和XML解析器等。 gSOAP的安装 gSOAP的…

    other 2023年6月27日
    00
  • spring拓展之如何定义自己的namespace

    以下是使用标准的Markdown格式文本,详细讲解Spring拓展之如何定义自己的namespace的完整攻略: Spring拓展之如何定义自己的namespace 1. 创建自定义的NamespaceHandler实现类 创建一个实现了NamespaceHandler接口的类,用于处理自定义的命名空间。 示例代码: public class MyNames…

    other 2023年10月15日
    00
  • 如何在plsql/developer的命令窗口执行sql脚本

    如何在PL/SQL Developer的命令窗口执行SQL脚本 PL/SQL Developer是一款比较流行的Oracle数据库开发工具,除了拥有便捷的界面操作外,还可以通过命令窗口执行SQL脚本。下面就来介绍一下如何在PL/SQL Developer的命令窗口执行SQL脚本。 步骤一:打开命令窗口 首先打开PL/SQL Developer,选择一个连接到…

    其他 2023年3月29日
    00
  • gitlab更改root密码

    GitLab是一个基于Git的代码托管和协作平台,可以帮助团队更好地管理代码和项目。以下是GitLab更改root密码的完整攻略: 登录GitLab 首先需要登录GitLab,使用管理员账号登录。 进入用户管理页面 在GitLab的管理界面中,点击右上角的用户头像,选择“Admin Area”进入管理员区域。然后点击左侧菜单栏中的“Users”选项,进入用户…

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