• 微信公众号开发之获取用户列表和用户基本信息(五)


    一、获取用户列表

    公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。

    接口调用请求说明

    http请求方式: GET(请使用https协议)
    https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
    
    参数是否必须说明
    access_token 调用接口凭证
    next_openid 第一个拉取的OPENID,不填默认从头开始拉取

    返回说明

    正确时返回JSON数据包:

    {
        "total":2,
        "count":2,
        "data":{
        "openid":["OPENID1","OPENID2"]},
        "next_openid":"NEXT_OPENID"
    }
    
    参数说明
    total 关注该公众账号的总用户数
    count 拉取的OPENID个数,最大值为10000
    data 列表数据,OPENID的列表
    next_openid 拉取列表的最后一个用户的OPENID

     我们定义一个方法获取用户列表

    package com.xu.wemall.components.weixin;
    
    import com.alibaba.fastjson.JSONObject;
    import com.xu.wemall.commons.constants.URIConstant;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    @Slf4j
    @Component
    public class WxUserUtil {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private AccessTokenUtil accessTokenUtil;
    
        /**
         *获取帐号的关注者列表
         * @return
         */
        public JSONObject getUserList(String nextOpenid){
    
            String accessToken = accessTokenUtil.getAccessToken();
            if(accessToken != null){
                log.info("URL{}",URIConstant.USER_LIST_URL);
                String url = URIConstant.USER_LIST_URL.replace("ACCESS_TOKEN", accessToken);
    
                if(nextOpenid != null){
                    url = URIConstant.USER_LIST_URL + "&next_openid="+ nextOpenid;
                }
                log.info("USER_LIST_URL:{}",url);
    
                //发起POST请求创建菜单
                JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class);
    
                return jsonObject;
            }
            return null;
        }
    
    }
    

    在controller中调用这个方法

    package com.xu.wemall.controller.weixin;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.xu.wemall.commons.constants.WXConstant;
    import com.xu.wemall.components.weixin.WxUserUtil;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    import springfox.documentation.annotations.ApiIgnore;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.net.URLEncoder;
    
    /**
     * 类名称: LoginController
     * 类描述: 与微信对接登陆验证
     *
     * @author RonnieXu
     * 创建时间:2017年12月5日上午10:52:13
     */
    @Slf4j
    @RestController
    @Api(tags = "微信用户接口")
    @RequestMapping(value = "/wxuser")
    public class WxUserController {
    
        @Autowired
        private WxUserUtil wxUserUtil;
    
        @Autowired
        private RestTemplate restTemplate;
    
        @ApiIgnore
        @RequestMapping(value="/login", method = RequestMethod.GET)
        public void wxLogin(HttpServletResponse response) throws IOException {
            //请求获取code的回调地址
            //用线上环境的域名或者用内网穿透,不能用ip
            String callBack = "http://jialeyuan.nat300.top/wxAuth/callBack";
    
            //请求地址
            String url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
                    "?appid=" + WXConstant.TEST_APPID +
                    "&redirect_uri=" + URLEncoder.encode(callBack,"utf-8") +
                    "&response_type=code" +
                    "&scope=snsapi_userinfo" +
                    "&state=STATE#wechat_redirect";
            //重定向
            response.sendRedirect(url);
        }
    
        // 回调方法
        @ApiIgnore
        @RequestMapping(value ="/callBack", method = RequestMethod.GET)
        public void wxCallBack(HttpServletRequest request,HttpServletResponse response) throws IOException {
            String code = request.getParameter("code");
    
            //获取access_token
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                    "?appid=" + WXConstant.TEST_APPID +
                    "&secret=" + WXConstant.TEST_APPSECRET +
                    "&code=" + code +
                    "&grant_type=authorization_code";
    
            String result = restTemplate.getForObject(url, String.class);
    
            System.out.println("请求获取access_token:" + result);
            //返回结果的json对象
            JSONObject resultObject = JSON.parseObject(result);
    
            //请求获取userInfo
            String infoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=" + resultObject.getString("access_token") +
                    "&openid=" + resultObject.getString("openid") +
                    "&lang=zh_CN";
    
            String resultInfo = restTemplate.getForObject(infoUrl, String.class);
    
            //此时已获取到userInfo,再根据业务进行处理
            log.info("请求获取userInfo:{}", resultInfo);
    
        }
    
        /**
         * 获取关注公众号的用户列表
         */
        @ApiOperation(value = "获取关注公众号的用户列表")
        @RequestMapping(value = "/getUserList", method = RequestMethod.GET)
        @ApiImplicitParams({
                @ApiImplicitParam(name="nextOpenid",value="第一个拉取的OPENID,不填默认从头开始拉取", paramType="query",dataType="String"),
        })
        public JSONObject getUserList(String nextOpenid) {
    
            JSONObject result = wxUserUtil.getUserList(nextOpenid);
            log.info("user_list:{}", result.toJSONString());
            return result;
    
        }
    
    }
    

    我们测试一下,看看我们获取到的关注我们公众号的用户列表

     

    二、获取用户详情

    在微信开发过程中,我们有时候需要获取用户的一些基础信息,尤其比如微信公众号和头像地址。获取用户信息主要是通过以下接口:

    接口调用请求说明
    http请求方式: GET
    https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

    通过这个接口里的参数 可以看到我们需要先获得access_token、openid这两个参数,access_token之前的文章已经说过了,openid是用户的微信公众号唯一标识

    参数说明

    参数是否必须说明
    access_token 调用接口凭证
    openid 普通用户的标识,对当前公众号唯一
    lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

    openid在用户关注我们的公众号时候就可以获取到,不过在那里openid叫FromUserName

    如果接口响应成功,则返回如下:

    返回说明

    正常情况下,微信会返回下述JSON数据包给公众号:

    {
        "subscribe": 1, 
        "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", 
        "nickname": "Band", 
        "sex": 1, 
        "language": "zh_CN", 
        "city": "广州", 
        "province": "广东", 
        "country": "中国", 
        "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
        "subscribe_time": 1382694957,
        "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
        "remark": "",
        "groupid": 0,
        "tagid_list":[128,2],
        "subscribe_scene": "ADD_SCENE_QR_CODE",
        "qr_scene": 98765,
        "qr_scene_str": ""
    }

    参数说明

    参数说明
    subscribe 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
    openid 用户的标识,对当前公众号唯一
    nickname 用户的昵称
    sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
    city 用户所在城市
    country 用户所在国家
    province 用户所在省份
    language 用户的语言,简体中文为zh_CN
    headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
    subscribe_time 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
    unionid 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
    remark 公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
    groupid 用户所在的分组ID(兼容旧的用户分组接口)
    tagid_list 用户被打上的标签ID列表
    subscribe_scene 返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENE_PROFILE_ LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他
    qr_scene 二维码扫码场景(开发者自定义)
    qr_scene_str 二维码扫码场景描述(开发者自定义)

    这里先贴出所有的依赖  

    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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.xu</groupId>
        <artifactId>wemall</artifactId>
        <version>v0.6.1-beta-build20190718</version>
        <packaging>jar</packaging>
    
        <name>wemall</name>
        <description>this is a wemall project</description>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.1.RELEASE</version>
            <relativePath/>
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <swagger-ui.version>2.9.2</swagger-ui.version>
            <swagger2.version>2.9.2</swagger2.version>
        </properties>
    
        <dependencies>
            <!-- spring-boot -->
            <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>
    
            <!-- 使thymeleaf支持h5标签 -->
            <dependency>
                <groupId>net.sourceforge.nekohtml</groupId>
                <artifactId>nekohtml</artifactId>
                <version>1.9.22</version>
            </dependency>
    
            <!-- log related -->
            <dependency> <!-- exclude掉spring-boot的默认log配置 -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <!--aspectj-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <!-- 表示开发的时候引入,发布的时候不会加载此包 -->
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.3.2</version>
            </dependency>
    
            <!-- mybatis-plus begin -->
            <!--mybatis-plus自动的维护了mybatis以及mybatis-spring的依赖,在springboot中这三者不能同时的出现,避免版本的冲突,表示:跳进过这个坑-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.1.0</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>3.1.0</version>
            </dependency>
    
            <!--swagger2-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${swagger-ui.version}</version>
            </dependency>
    
            <!--排除并新增1.5swagger-annotations和swagger-models
                为了解决swagger2中example注解导致的input空字符串异常错误-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${swagger2.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-annotations</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>io.swagger</groupId>
                        <artifactId>swagger-models</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>1.5.21</version>
            </dependency>
    
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
                <version>1.5.21</version>
            </dependency>
    
            <!-- 引入Druid依赖,阿里巴巴所提供的数据源 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.29</version>
            </dependency>
    
            <!-- 提供mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.16</version>
            </dependency>
    
            <!--jsonwebtoken-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
            <!--jsonwebtoken-->
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.46</version>
            </dependency>
    
            <!--热部署-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>springloaded</artifactId>
                <version>1.2.8.RELEASE</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
    
            <!--redis配置-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <!-- websocket -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
    
            <dependency>
                <groupId>com.thoughtworks.xstream</groupId>
                <artifactId>xstream</artifactId>
                <version>1.4.9</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.3.2</version>
            </dependency>
    
            <!-- alibaba的easyexcel -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>1.1.2-beta4</version>
            </dependency>
    
            <!-- pdf实现 -->
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.5.10</version>
            </dependency>
    
            <!-- pdf字体包 -->
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
    
            <!-- activemq消息队列 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-activemq</artifactId>
                <version>2.0.4.RELEASE</version>
            </dependency>
    
            <!--netty-->
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.16.Final</version>
            </dependency>
    
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>2.0.31-beta</version>
                <scope>test</scope>
            </dependency>
    
            <!-- freemarker自定义模板,生成代码模板时候需要这个-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
    
            <!--redisson-->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.5.7</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <includeSystemScope>true</includeSystemScope>
                        <fork>true</fork><!--该配置必须-->
                        <executable>true</executable>
                        <excludeDevtools>false</excludeDevtools>
                        <mainClass>com.xu.wemall.wemallApplication</mainClass>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.4.2</version>
                    <configuration>
                        <skipTests>true</skipTests>
                    </configuration>
                </plugin>
    
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.3</version>
                    <configuration>
                        <encoding>utf-8</encoding>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
    
            </plugins>
        </build>
    
    </project>
    

    首先,我们定义一个 微信用户POJO  

    WxUser.java
    package com.xu.wemall.entry;
    
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableName;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.experimental.Accessors;
    import org.springframework.format.annotation.DateTimeFormat;
    
    import java.time.LocalDateTime;
    
    /**
     * <p>
     * 
     * </p>
     *
     * @author RonnieXu
     * @since 2019-12-19
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    @Accessors(chain = true)
    @TableName("sys_wx_user")
    @ApiModel(value="微信对象", description="微信对象")
    public class WxUser extends BaseEntity<WxUser> {
    
        private static final long serialVersionUID = 1L;
    
        @ApiModelProperty(value="用户的标识,对当前公众号唯一")
        private String openid;
    
        @ApiModelProperty(value="用户的昵称")
        private String nickname;
    
        @ApiModelProperty(value="用户的性别,值为1时是男性,值为2时是女性,值为0时是未知")
        private Integer sex;
    
        @ApiModelProperty(value="用户所在城市")
        private String city;
    
        @ApiModelProperty(value="用户所在国家")
        private String country;
    
        @ApiModelProperty(value="用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选," +
                "0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。")
        private String headimgurl;
    
        @ApiModelProperty(value="用户所在省份")
        private String province;
    
        @ApiModelProperty(value="用户的语言,简体中文为zh_CN")
        private String language;
    
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @TableField(value = "subscribe_time")
        @ApiModelProperty(value="用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间")
        private LocalDateTime subscribe_time;
    
        @ApiModelProperty(value="只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段")
        private String unionid;
    
        @ApiModelProperty(value="公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注")
        private String remark;
    
        @ApiModelProperty(value="用户所在的分组ID(兼容旧的用户分组接口)")
        private String groupid;
    
        @TableField(value = "tagid_list")
        @ApiModelProperty(value="用户被打上的标签ID列表")
        private String tagid_list;
    
        /**
         * 返回用户关注的渠道来源,
         * ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION
         * 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,
         * ADD_SCENE_PROFILE_ LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,
         * ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他
         */
        @TableField(value = "subscribe_scene")
        @ApiModelProperty(value="返回用户关注的渠道来源")
        private String subscribe_scene;
    
        @TableField(value = "qr_scene")
        @ApiModelProperty(value="二维码扫码场景(开发者自定义)")
        private String qr_scene;
    
        @TableField(value = "qr_scene_str")
        @ApiModelProperty(value="二维码扫码场景描述(开发者自定义)")
        private String qr_scene_str;
    
    }
    

    定义一个component
    WeiXinUserUtil.java
    package com.xu.wemall.components.weixin;
    
    import com.alibaba.fastjson.JSONObject;
    import com.xu.wemall.commons.constants.URIConstant;
    import com.xu.wemall.entry.WxUser;
    import com.xu.wemall.pojo.menu.Button;
    import com.xu.wemall.pojo.menu.ComplexButton;
    import com.xu.wemall.pojo.menu.Menu;
    import com.xu.wemall.pojo.menu.ViewButton;
    import com.xu.wemall.service.IWxUserService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    @Slf4j
    @Component
    public class WeiXinUserUtil {
    
        @Autowired
        private IWxUserService iWxUserService;
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private AccessTokenUtil accessTokenUtil;
    
        public JSONObject handdleWeixinUserInfo(String openId){
    
            String accessToken = accessTokenUtil.getAccessToken();
            if(accessToken != null){
                log.info("URL{}",URIConstant.OPENID_USERINFO_URL);
                String url = URIConstant.OPENID_USERINFO_URL.replace("ACCESS_TOKEN", accessToken)
                        .replace("OPENID",openId);
                log.info("OPENID_USERINFO_URL:{}",url);
    
                //发起POST请求创建菜单
                JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class);
    
                //表示订阅了该公众号
                if(jsonObject.getIntValue("subscribe") == 1){
                    //保存
                    WxUser wxUser = JSONObject.parseObject(jsonObject.toJSONString(),WxUser.class);
                    boolean result = iWxUserService.saveOrUpdate(wxUser);
                }
    
                return jsonObject;
            }
            return null;
        }
    
    }
    

    最后看看我们的controller中代码,如果我们调用成功就可以获取到用户的相关信息,我们就持续化到自己数据库

    WeiXinController.java
    package com.xu.wemall.controller.weixin;
    
    import com.alibaba.fastjson.JSONObject;
    import com.xu.wemall.commons.utils.CheckUtil;
    import com.xu.wemall.commons.utils.UploadUtil;
    import com.xu.wemall.components.weixin.MessageUtil;
    import com.xu.wemall.components.weixin.WeiXinUserUtil;
    import io.swagger.annotations.Api;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.PrintWriter;
    import java.util.Map;
    
    /**
     * 类名称: LoginController
     * 类描述: 与微信对接登陆验证
     *
     * @author yuanjun
     * 创建时间:2017年12月5日上午10:52:13
     */
    @Slf4j
    @RestController
    @Api(tags = "接入验证接口")
    @RequestMapping(value = "/weChart")
    public class WeiXinController {
    
        @Autowired
        private WeiXinUserUtil weiXinUserUtil;
    
        @Autowired
        private UploadUtil uploadUtil;
    
        @Autowired
        private MessageUtil messageUtil;
    
        @RequestMapping(value = "/connect", method = RequestMethod.GET)
        public String connect(@RequestParam(value = "signature") String signature,
                              @RequestParam(value = "timestamp") String timestamp,
                              @RequestParam(value = "nonce") String nonce,
                              @RequestParam(value = "echostr") String echostr) {
    
            log.info("-----开始校验签名-----");
            PrintWriter out = null;
            if (CheckUtil.checkSignature(signature, timestamp, nonce)) {
                log.info("-----签名校验通过-----");
                return echostr;
            } else {
                log.info("-----校验签名失败-----");
                return null;
            }
    
        }
    
        @RequestMapping(value = "connect", method = RequestMethod.POST)
        public String dopost(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
            response.setCharacterEncoding("utf-8");
    
            //将微信请求xml转为map格式,获取所需的参数
            Map<String, String> map = MessageUtil.parseXml(request);
            String ToUserName = map.get("ToUserName");
            String FromUserName = map.get("FromUserName");
            String MsgType = map.get("MsgType");
            String Content = map.get("Content");
            String Event = map.get("Event");
    
            if(MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(MsgType)){
    
                if(MessageUtil.EVENT_TYPE_SUBSCRIBE.equals(Event)){
                    String xmlString = messageUtil.subscribeForText(ToUserName,FromUserName);
    
                    //关注了公众号,调用接口获得用户的详细信息并保存到后台
                    JSONObject jsonObject = weiXinUserUtil.handdleWeixinUserInfo(FromUserName);
                    log.info("获取用户的详细信息:{}",jsonObject.toJSONString());
    
                    return xmlString;
    
                }else if(MessageUtil.EVENT_TYPE_UNSUBSCRIBE.equals(Event)){
    
                    String xmlString = messageUtil.unsubscribeForText(ToUserName,FromUserName);
                    return xmlString;
    
                }
    
            }
    
            //处理文本类型,实现输入1,回复相应的封装的内容
            if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(MsgType)) {
                String xmlString = messageUtil.replyForText(ToUserName,FromUserName,"你发送的是:" + Content);
                log.info(xmlString);
                return xmlString;
    
            }
    
            if (MessageUtil.REQ_MESSAGE_TYPE_IMAGE.equals(MsgType)) {
    
                String filePath = "C:\Users\RonnieXu\Pictures\2.jpg";
                String xmlString = messageUtil.replyForImage(ToUserName,FromUserName,filePath);
                return xmlString;
            }
    
            return null;
        }
    
    }
    

    当有用户关注该公众号的时候,我们就能利用接口获取用户信息了,

    获取用户的信息就到这里了,其他相关的内容请参考微信公众号开发文档获取更多的内容,谢谢各位客官捧场。

  • 相关阅读:
    SpringBoot 发送邮件
    @Component 爆红
    Java 调用OpenCV获取图像数据,发送Redis并从Redis获取数据显示
    xxx.bat windows Bat文件启动cmd命令运行jar包
    队列
    paramiko连接服务器
    matplotlib模块画坐标图
    获取当前时间
    jsonpath和打印模板
    提取图片中的文字
  • 原文地址:https://www.cnblogs.com/xulijun137/p/12213476.html
Copyright © 2020-2023  润新知