微信公众号上完成获取用户openid-----详细教程

本文从零开始到获取用户openid并存到数据库
运用到SpringBoot+mybatis+RestTemplate

准备条件

需要一个公众号

在这里插入图片描述

需要简单配置一下,在左方菜单最下方----开发–基本配置—白名单这里填写电脑现自身的ip(本项目本地跑)

获取ip:https://www.ip138.com/

在这里插入图片描述
查看微信公众平台开发文档
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

获取access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

接口调用请求说明

https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET`

官方的接口调式工具测试,走一遍获取用户列表流程

微信公众平台接口调试工具:https://mp.weixin.qq.com/debug/cgi-bin/apiinfo?t=index&type=%E5%9F%BA%E7%A1%80%E6%94%AF%E6%8C%81&form=%E8%8E%B7%E5%8F%96access_token%E6%8E%A5%E5%8F%A3%20/token
在这里插入图片描述

失败请查阅文档,了解详情

在这里插入图片描述

获取用户列表

公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。例如:
公众账号A拥有23000个关注的人,想通过拉取关注接口获取所有关注的人,那么分别请求url如下:https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN 返回结果:
{
“total”:23000,
“count”:10000,
“data”:{"
openid":[
“OPENID1”,
“OPENID2”,
…,
“OPENID10000”
]
},
“next_openid”:“OPENID10000”
}https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID1返回结果:
{
“total”:23000,
“count”:10000,
“data”:{
“openid”:[
“OPENID10001”,
“OPENID10002”,
…,
“OPENID20000”
]
},
“next_openid”:“OPENID20000”
}https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID2返回结果(关注者列表已返回完时,返回next_openid为空):
{
“total”:23000,
“count”:3000,
“data”:{"
“openid”:[
“OPENID20001”,
“OPENID20002”,
…,
“OPENID23000”
]
},
“next_openid”:“OPENID23000”
}

接口调用请求说明

http请求方式: GET(请使用https协议)
https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

在这里插入图片描述
失败请查阅文档,了解详情
在这里插入图片描述

以上都成功,我们开始写代码

所有注释都已经在代码中标识,就不做多阐述,逻辑很简单,直接贴上详细代码

项目目录结构和数据库设计

在这里插入图片描述

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>template</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>template</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
application.yml -----填写自己的数据库信息
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC&useSSL=false
    username: 
    password: 

mybatis:
  mapper-locations: classpath*:mapper/*Mapper.xml

server:
  port: 8888
Constast—更换自己相应的数据
package com.example.template.common;

import lombok.Data;

/**
 * 微信参数
 */
@Data
public class Constast {
    //开发者ID
    public static final String AppId="wx1###########bfe";
    //开发者密码
    public static final String AppSecret="49######################667";
    //接口凭证access_token
    private String access_token;
    //凭证时效
    private int expires_in;
    //我的openid
    public static final String HuHaoAppId="oP######################wM";
    //模板template_id
    public static final String TemplateId="88d######################4ULcs";
    //违章查询路径
    public  static final String PagePath="pages/###########index?routeKey=PC01_RE############################################tagid=104.233.5";
    //违章查询的AppId
    public static final String XcxAppId="wx0###########f5b2";
}
WeixinUserListVo
package com.example.template.vo;

import lombok.Data;

@Data
public class WeixinUserListVo {
    private Integer total;//关注该公众账号的总用户数

    private Integer count;//拉取的OPENID个数,最大值为10000

    private WxOpenidInfo data;//列表数据,OPENID的列表

    private String next_openid;//拉取列表的最后一个用户的OPENID

    private int errcode;//错误编码

    private String errmsg = "ok";//错误提示
}
WxOpenidInfo
package com.example.template.vo;

import lombok.Data;
import java.util.List;

@Data
public class WxOpenidInfo {
    private List<String> openid;
}
TemplateController
package com.example.template.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.template.common.Constast;
import com.example.template.service.TemplateService;
import com.example.template.vo.WeixinUserListVo;
import com.example.template.vo.WxOpenidInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/a")
public class TemplateController {

    private static final Logger logger = LoggerFactory.getLogger(TemplateController.class);

    @Autowired
    private TemplateService templateService;

    //获取access_token,access_token是公众号的全局唯一接口调用凭据
    public static Constast getAccessToken() {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> map = new HashMap<>();
        map.put("AppId", Constast.AppId);
        map.put("AppSecret", Constast.AppSecret);
        //调用微信公众号接口
        ResponseEntity<String> forEntity = restTemplate.getForEntity("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={AppId}&secret={AppSecret}", String.class, map);
        String body = forEntity.getBody();
        JSONObject jsonObject = JSON.parseObject(body);
        String access_token = jsonObject.getString("access_token");
        String expires_in = jsonObject.getString("expires_in");//时效--7200s
        Constast constast = new Constast();
        constast.setAccess_token(access_token);
        return constast;
    }

    //获取用户列表的openid
    @RequestMapping("/a")
    public WeixinUserListVo getUserOpenIdList() {
        //获取最新的access_token
        String accessToken = TemplateController.getAccessToken().getAccess_token();
        RestTemplate restTemplate = new RestTemplate();
        WeixinUserListVo openIdList = null;
        synchronized (this) {
            try {
                //循环获取用户openid列表--一次获取10000
                String nextOpenid = null;
                do {
                    //微信公众号获取用户列表信息接口地址
                    String requestUrl = null;
                    if (StringUtils.isBlank(nextOpenid)) {
                        requestUrl = new StringBuffer().append("https://api.weixin.qq.com/cgi-bin/user/get?access_token=").append(accessToken).toString();
                    } else {
                        requestUrl = new StringBuffer().append("https://api.weixin.qq.com/cgi-bin/user/get?access_token=")
                                .append(accessToken).append("&next_openid=").append(nextOpenid).toString();
                    }
                    openIdList = restTemplate.getForObject(requestUrl, WeixinUserListVo.class);
                    if (openIdList != null && openIdList.getErrcode() == 0) {
                        //获取用户关注列表对象
                        WxOpenidInfo data = openIdList.getData();
                        if (data != null) {
                            //获取当前循环的openid--10000条
                            List<String> openid = data.getOpenid();
                            if (openid != null && openid.size() > 0) {
                                for (int i = 0; i < openid.size(); i += 100) {
                                    int toIndex = 100;
                                    if (i + 100 > openid.size()) {
                                        // 注意下标问题
                                        toIndex = openid.size() - i;
                                    }
                                    //循环100次,每次拿到openid列表中的集合下标;例如:(0,100),(100,200)
                                    List<String> sendList = openid.subList(i, i + toIndex);
                                    //每次insert---100条
                                    int num = templateService.insertForeach(sendList);
                                }
                            }
                        }
                        //拉取列表的最后一个用户的OPENID
                        nextOpenid = openIdList.getNext_openid();
                        System.out.println(nextOpenid);
                    } else {
                        openIdList.setErrcode(40000);
                        openIdList.setErrmsg("获取关注用户列表失败");
                        return openIdList;
                    }
                } while (openIdList.getCount() > 0);
            } catch (Exception e) {
                openIdList.setErrcode(40000);
                openIdList.setErrmsg("获取用户列表失败");
                return openIdList;
            }
        }
        return openIdList;
    }
}
TemplateServiceImpl
package com.example.template.service.impl;

import com.example.template.mapper.TemplateMapper;
import com.example.template.service.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
@Transactional
public class TemplateServiceImpl implements TemplateService {

    @Autowired
    private TemplateMapper templateMapper;

    @Override
    public int insertForeach(List list) {
        int i = templateMapper.insertForeach(list);
        return i;
    }
}
TemplateService
package com.example.template.service;

import java.util.List;

public interface TemplateService {

    int insertForeach(List list);
}
TemplateMapper
package com.example.template.mapper;

import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface TemplateMapper {

    int insertForeach(List list);
}
TemplateMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.template.mapper.TemplateMapper">
    <insert id="insertForeach" parameterType="java.util.List" useGeneratedKeys="false">
        insert into template (openid)
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (#{item})
        </foreach>
    </insert>
</mapper>
启动项目:http://localhost:8888/a/a
模板消息:微信公众号完成模板消息-----详细教程
  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值