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

一、获取用户列表

公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串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;
    }

}

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

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

原文地址:https://www.cnblogs.com/xulijun137/p/12213476.html