zoukankan      html  css  js  c++  java
  • 玩玩微信公众号Java版之五:获取关注用户信息

      在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
    请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。
    UnionID机制说明:
      开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。 
    获取用户基本信息(包括UnionID机制)
    开发者可通过OpenID来获取用户基本信息。请使用https协议。
    接口调用请求说明
    http请求方式: GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
    参数说明
    参数 是否必须 说明
    access_token 调用接口凭证
    openid 普通用户的标识,对当前公众号唯一
    lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
     
    或者是批量获取用户基本信息
    批量获取用户基本信息
    开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。
    接口调用请求说明
    http请求方式: POST
    https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
    POST数据示例
    {
       "user_list": [
           {
               "openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
               "lang": "zh_CN"
           },
           {
               "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
               "lang": "zh_CN"
           }
       ]
    }
    参数说明
    参数 是否必须 说明
    openid 用户的标识,对当前公众号唯一
    lang 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN
     
    通过这2个接口,可以发现要获取用户信息必要要获取用户关注公众号的 openid,那么首先要获取对应的openid,涉及到另外一个接口:
    获取用户列表
    公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串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
     
    这样可以获取到公众号的关注着列表. 获取到openid后即可获取用户的明细信息。
     
    功能实现
    分析完接口参数及调用方式,下面就来进行实现吧~
    可以定义一个用户信息类,这样后续处理用户信息或存储到数据库均较方便,主要属性可按接口返回字段进行定义:
      1 /**
      2  * 微信用户信息类
      3  * @author Damon
      4  */
      5 public class UserInfo
      6 {
      7 
      8     // 用户的标识
      9     private String openId;
     10 
     11     // 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
     12     private int subscribe;
     13 
     14     // 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
     15     private int subscribetime;
     16 
     17     // 昵称
     18     private String nickname;
     19 
     20     // 用户的性别(1是男性,2是女性,0是未知)
     21     private int sex;
     22 
     23     // 用户所在国家
     24     private String country;
     25 
     26     // 用户所在省份
     27     private String province;
     28 
     29     // 用户所在城市
     30     private String city;
     31 
     32     // 用户的语言,简体中文为zh_CN
     33     private String language;
     34 
     35     // 用户头像
     36     private String headimgurl;
     37 
     38     private String remark;
     39 
     40     private int groupid;
     41 
     42     public String getOpenId()
     43     {
     44         return openId;
     45     }
     46 
     47     public void setOpenId(String openId)
     48     {
     49         this.openId = openId;
     50     }
     51 
     52     public int getSubscribe()
     53     {
     54         return subscribe;
     55     }
     56 
     57     public void setSubscribe(int subscribe)
     58     {
     59         this.subscribe = subscribe;
     60     }
     61 
     62     
     63     public int getSubscribetime()
     64     {
     65         return subscribetime;
     66     }
     67 
     68     public void setSubscribetime(int subscribetime)
     69     {
     70         this.subscribetime = subscribetime;
     71     }
     72 
     73     public String getNickname()
     74     {
     75         return nickname;
     76     }
     77 
     78     public void setNickname(String nickname)
     79     {
     80         this.nickname = nickname;
     81     }
     82 
     83     public int getSex()
     84     {
     85         return sex;
     86     }
     87 
     88     public void setSex(int sex)
     89     {
     90         this.sex = sex;
     91     }
     92 
     93     public String getCountry()
     94     {
     95         return country;
     96     }
     97 
     98     public void setCountry(String country)
     99     {
    100         this.country = country;
    101     }
    102 
    103     public String getProvince()
    104     {
    105         return province;
    106     }
    107 
    108     public void setProvince(String province)
    109     {
    110         this.province = province;
    111     }
    112 
    113     public String getCity()
    114     {
    115         return city;
    116     }
    117 
    118     public void setCity(String city)
    119     {
    120         this.city = city;
    121     }
    122 
    123     public String getLanguage()
    124     {
    125         return language;
    126     }
    127 
    128     public void setLanguage(String language)
    129     {
    130         this.language = language;
    131     }
    132 
    133     public String getHeadimgurl()
    134     {
    135         return headimgurl;
    136     }
    137 
    138     public void setHeadimgurl(String headimgurl)
    139     {
    140         this.headimgurl = headimgurl;
    141     }
    142 
    143     public String getRemark()
    144     {
    145         return remark;
    146     }
    147 
    148     public void setRemark(String remark)
    149     {
    150         this.remark = remark;
    151     }
    152 
    153     public int getGroupid()
    154     {
    155         return groupid;
    156     }
    157 
    158     public void setGroupid(int groupid)
    159     {
    160         this.groupid = groupid;
    161     }
    162 
    163 
    164 }
    View Code
     然后就是具体的实现方法了,其实很简单,就是先后调用2次接口就行了:
     首先的要调用获取用户openid的列表:
     1     /**
     2      * 获取公众号关注的用户openid
     3      * @return
     4      */
     5     public List<String> getUserOpenId(String access_token, String nextOpenid)
     6     {
     7         String path = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";
     8         path = path.replace("ACCESS_TOKEN", access_token).replace("NEXT_OPENID", nextOpenid);
     9         System.out.println("path:" + path);
    10 
    11         List<String> result = null;
    12         try
    13         {
    14             String strResp = WeChatUtil.doHttpsGet(path, "");
    15             System.out.println(strResp);
    16 
    17             Map map = WeChatUtil.jsonToMap(strResp);
    18             Map tmapMap = (Map) map.get("data");
    19 
    20             result = (List<String>) tmapMap.get("openid");
    21 
    22             System.out.println(result.toString());
    23 
    24         }
    25         catch (HttpException e)
    26         {
    27             // TODO Auto-generated catch block
    28             e.printStackTrace();
    29         }
    30         catch (IOException e)
    31         {
    32             // TODO Auto-generated catch block
    33             e.printStackTrace();
    34         }
    35 
    36         return result;
    37     }
    View Code

    获取到openi的信息后,也可以先存储起来(具体看项目需要了),或再等详细信息后才存储,

    对应的调用方法如下:
     1     /**
     2      * 通过用户openid 获取用户信息
     3      * @param userOpenids
     4      * @return
     5      */
     6     public List<UserInfo> getUserInfo(List<String> userOpenids)
     7     {
     8         // 1、获取access_token
     9         // 使用测试 wx9015ccbcccf8d2f5 02e3a6877fa5fdeadd78d0f6f3048245
    10         WeChatTokenService tWeChatTokenService = new WeChatTokenService();
    11         String tAccess_Token = tWeChatTokenService.getToken("wx9015ccbcccf8d2f5", "02e3a6877fa5fdeadd78d0f6f3048245").getToken();
    12 
    13         // 2、封装请求数据
    14         List user_list = new ArrayList<Map>();
    15         for (int i = 0; i < userOpenids.size(); i++)
    16         {
    17             String openid = userOpenids.get(i);
    18             Map tUserMap = new HashMap<String, String>();
    19             tUserMap.put("openid", openid);
    20             tUserMap.put("lang", "zh_CN");
    21             user_list.add(tUserMap);
    22         }
    23         System.out.println(user_list.toString());
    24         Map requestMap = new HashMap<String, List>();
    25         requestMap.put("user_list", user_list);
    26         String tUserJSON = JSONObject.fromObject(requestMap).toString();
    27 
    28         // 3、请求调用
    29         String result = getUserInfobyHttps(tAccess_Token, tUserJSON);
    30         System.out.println(result);
    31 
    32         // 4、解析返回将结果
    33         return parseUserInfo(result);
    34     }
    View Code

    其中详细方法实现如下:

     1     /**
     2      * 解析返回用户信息数据
     3      * @param userInfoJSON
     4      * @return
     5      */
     6     private List<UserInfo> parseUserInfo(String userInfoJSON)
     7     {
     8         List user_info_list = new ArrayList<UserInfo>();
     9 
    10         Map tMapData = WeChatUtil.jsonToMap(userInfoJSON);
    11 
    12         List<Map> tUserMaps = (List<Map>) tMapData.get("user_info_list");
    13 
    14         for (int i = 0; i < tUserMaps.size(); i++)
    15         {
    16             UserInfo tUserInfo = new UserInfo();
    17             tUserInfo.setSubscribe((Integer) tUserMaps.get(i).get("subscribe"));
    18             tUserInfo.setSex((Integer) tUserMaps.get(i).get("sex"));
    19             tUserInfo.setOpenId((String) tUserMaps.get(i).get("openid"));
    20             tUserInfo.setNickname((String) tUserMaps.get(i).get("nickname"));
    21             tUserInfo.setLanguage((String) tUserMaps.get(i).get("language"));
    22             tUserInfo.setCity((String) tUserMaps.get(i).get("city"));
    23             tUserInfo.setProvince((String) tUserMaps.get(i).get("province"));
    24             tUserInfo.setCountry((String) tUserMaps.get(i).get("country"));
    25             tUserInfo.setHeadimgurl((String) tUserMaps.get(i).get("headimgurl"));
    26             tUserInfo.setSubscribetime((Integer) tUserMaps.get(i).get("subscribe_time"));
    27             tUserInfo.setRemark((String) tUserMaps.get(i).get("remark"));
    28             tUserInfo.setGroupid((Integer) tUserMaps.get(i).get("groupid"));
    29             user_info_list.add(tUserInfo);
    30         }
    31 
    32         return user_info_list;
    33     }
    34 
    35     /**
    36      * 调用HTTPS接口,获取用户详细信息
    37      * @param access_token
    38      * @param requestData
    39      * @return
    40      */
    41     private String getUserInfobyHttps(String access_token, String requestData)
    42     {
    43         // 返回报文
    44         String strResp = "";
    45         String path = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN";
    46         path = path.replace("ACCESS_TOKEN", access_token);
    47 
    48         try
    49         {
    50             strResp = WeChatUtil.doHttpsPost(path, requestData);
    51         }
    52         catch (HttpException e)
    53         {
    54             // 发生致命的异常,可能是协议不对或者返回的内容有问题
    55             System.out.println("Please check your provided http address!" + e);
    56             e.printStackTrace();
    57         }
    58         catch (IOException e)
    59         {
    60             // 发生网络异常
    61         }
    62         catch (Exception e)
    63         {
    64             System.out.println(e);
    65         }
    66         finally
    67         {}
    68         return strResp;
    69     }
    View Code

    测试方法如下:

    1     public static void main(String[] args)
    2     {
    3         WeChatUserService tChatUserService = new WeChatUserService();
    4         tChatUserService.getUserInfo(tChatUserService.getUserOpenId(new WeChatTokenService().getToken("appid", "appSceret").getToken(), ""));
    5     }
    View Code

    最终获取数据结果:
     

     可用把最终过去的用户信息存到数据库,后面的就由大家去发挥啦!

  • 相关阅读:
    SourceTree使用教程(六)--回滚版本到某次提交
    SourceTree使用教程(四)---冲突解决
    Git 分支合并后回退的几种情况分析
    HTTP认证之基本认证——Basic(二) _
    C#3.0中自动属性和对象初始化器
    C# 3.0新特征之创建和初始化集合对象
    SQL 用多个条件进行排序;以及根据一个条件的多个值,进行排序
    如何修改 .NET Core Kestrel 下的端口
    存储过程
    mysql临时表用法分析【查询结果可存在临时表中】
  • 原文地址:https://www.cnblogs.com/cooldamon/p/7216886.html
Copyright © 2011-2022 走看看