批量获取微信公众号用户openID及用户信息
发表时间:2020-10-19
发布人:葵宇科技
浏览次数:56
本文代码基于微信开发文档-用户管理-获取用户列表一节开发
在使用代码之前请确认你已阅读并理解上面文档提到的相关知识。
文章目录
- 1、工具类的构建
- 2、数据实体类的构建
- 3、批量获取用户openid
- 4、批量获取用户信息
1、工具类的构建
首先创建如下代码到RestTemplateUtil.java文件中,RestTemplateUtil这个类将帮助我们解析微信服务器发送过来的数据
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
public class RestTemplateUtil {
public static RestTemplate getInstance() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());
return restTemplate;
}
}
class WxMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
public WxMappingJackson2HttpMessageConverter(){
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.TEXT_HTML);
setSupportedMediaTypes(mediaTypes);
}
}
获取微信公众号access_token的函数,需要使用fastjson工具包,LOGGER为日志输出类,注意:如果不是测试公众号的话,请确保请求的IP地址在公众号IP白名单中,否则无法获取access_token,access_token一般7200秒后过期。
/**
* @param appid 微信公众号appid
* @param secret 微信公众号sectet
* @return 微信公众号access_token
*/
public String getWxAccessToken(String appid, String secret){
RestTemplate restTemplate = RestTemplateUtil.getInstance();
try {
JSONObject jsonObject = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/token?" +
"grant_type=client_credential&appid=%s&secret=%s", appid, secret), JSONObject.class);
if(jsonObject.get("access_token") == null){
throw new Exception(jsonObject.get("errcode").toString() + ":" + jsonObject.get("errmsg"));
}else {
return jsonObject.get("access_token").toString();
}
}catch (Exception e){
LOGGER.error(e.getMessage());
}
return "";
}
2、数据实体类的构建
需要准备三个实体类,一个保存openID列表,一个保存用户信息,一个保存用户信息列表,保存openID的实体类看起来如下所示:
相对应的,我们构造出如下实体类:
public class WxUsersListEntity {
int total;
int count;
openidList data;
String next_openid;
public class openidList{
List<String> openid;
//get and set method
...
}
//get and set method
...
}
同理:
保存用户信息的实体类看起来像这样:
相对应的,我们构造出如下实体类:
public class WxUserMsgEntity {
public int subscribe;
public String openid;
public String nickname;
public String headimgurl;
public String unionid;
//get and set method
...
}
你可以只挑你感兴趣的内容来保存,这里我只保存以上5条信息。这里提示一下,如果你需要将用户信息保存到数据库,格外注意nickname,他是utf8mb4编码。如果要将nickname保存到数据库,你有两种选择:
- 将数据库修改到支持utf8mb4来保存,参考这里
- 过滤掉nickname中的emoji表情来保存,参考这里
最后是保存用户信息列表的类,他看起来是这样:
所以构造的实体类是这样:
public class WxUserMsgList{
public List<WxUserMsgEntity> user_info_list;
//get and set method
...
}
3、批量获取用户openid
准备好以上的内容后,就可以开始按照微信文档中的逻辑编写代码了。首先我们来获取用户的openid列表,该函数返回的是一个保存所有用户openid的List。
public List<String> getUsersOpenID(String access_token){
RestTemplate restTemplate = RestTemplateUtil.getInstance();
List<String> usersOpenID = new ArrayList<>();
WxUsersListEntity wxUsersListEntity = new WxUsersListEntity();
//获取所有微信用户的openID
wxUsersListEntity = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/get?" +
"access_token=%s",access_token), WxUsersListEntity.class);
usersOpenID.addAll(wxUsersListEntity.getData().getOpenid());
while(wxUsersListEntity.getCount() == 10000){
wxUsersListEntity = restTemplate.getForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/get?" +
"access_token=%s&next_openid=%s", access_token, wxUsersListEntity.getNext_openid()), WxUsersListEntity.class);
if(wxUsersListEntity.getCount() == 0) {
break;
}else {
usersOpenID.addAll(wxUsersListEntity.getData().getOpenid());
}
}
return usersOpenID;
}
4、批量获取用户信息
之后根据用户openid的List去获取用户的信息,函数如下:
/**
* 根据列表中的openID返回用户信息,最大不超过100(因为微信服务器最多一次只支持拉取100条)
* @param openIDs
* @return 微信用户信息列表
*/
public List<WxUserMsgEntity> getUsersMsg(List<String> openIDs, String access_token) throws Exception {
if(openIDs.size() > 100) { throw new Exception("openIDs too long, must less or equals 100");}
JSONObject request = new JSONObject();
JSONArray openidList = new JSONArray();
for(String s:openIDs){
JSONObject openId = new JSONObject();
openId.put("lang", "zh_CN");
openId.put("openid", s);
openidList.add(openId);
}
request.put("user_list", openidList);
RestTemplate restTemplate = RestTemplateUtil.getInstance();
WxUserMsgList list = restTemplate.postForObject(String.format("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s", access_token),
request, WxUserMsgList.class);
return list.getUser_info_list();
}
在3,4步中使用getForObject
和postForObject
函数的时候,我没有考虑获取出错的情况,但是我在获取access_token的函数中给出了处理出错情况的示例,即:先将数据接收到JSONObject中,判断是否有我们需要的字段,没有的话说明出现了错误。如果没有出错,你可以使用JSONObject的public <T> T toJavaObject(Class<T> clazz)
函数将JSONObject转为数据实体类处理。
以上我们就完成了批量获取微信用户openID及用户信息的目标,如果使用过程中出现问题,可以在文章下评论,我会及时回复,让后来者不踩坑。