Java获取微信企业号中的手机号码

在开发的项目中,有工作流审批功能,有些岗位的人员并不是一直在办公室的,这就需要在手机端审批。手机端是在企业号中的应用实现的,登录时需要获取企业员工的手机号,具体代码如下:

import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@Component
@ConfigurationProperties("wechat")
public final class WeChatUtil {

private final static Logger LOGGER = LoggerFactory.getLogger(WeChatUtil.class);

private final static String GET_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={0}&corpsecret={1}";

private final static String GET_USER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={0}&code={1}";

private final static String GET_USER_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token={0}";

private String corpId;

private String secret;

/**
* 获取AccessToken
*
* @return { "access_token": "accesstoken000001", "expires_in": 7200 }
*/
public String getAccessToken() {
String url = MessageFormat.format(GET_ACCESS_TOKEN, corpId, secret);
LOGGER.info("url:{}", url);
String rs = httpGet(url);
LOGGER.info("获取AccessToken时返回的数据:{}", rs);
return rs;
}

/**
* 根据code获取成员信息
*
* @param accessToken
* @param code
* @return { "UserId":"USERID", "DeviceId":"DEVICEID", "user_ticket":
* "USER_TICKET","expires_in":7200 }
*/
public String getUserInfo(String accessToken, String code) {
String url = MessageFormat.format(GET_USER_INFO, accessToken, code);
String response = httpGet(url);
LOGGER.info("根据code获取成员信息 {}", response);
return response;
}

/**
* 获取员工详细信息
*
* @param accessToken
* @param userTicket
* @return { "userid":"lisi", "name":"李四", "department":[3], "position":
* "后台工程师", "mobile":"15050495892", "gender":1,
* "email":"xxx@xx.com",
* "avatar":"http://shp.qpic.cn/bizmp/xxxxxxxxxxx/0"}
*/
public String getUserDetail(String accessToken, String userTicket) {
String url = MessageFormat.format(GET_USER_DETAIL, accessToken);
String response = null;
Map<String, String> maps = new HashMap<String, String>();
maps.put("user_ticket", userTicket);
response = httpPost(url, maps);
return response;
}

/**
* 获取员工手机号
*
* @param code
* @return
*/
public String getMobile(String code) {

// 获取AccessToken
String jsonAccessToken = getAccessToken();
JSONObject jsonObjAccessToken = JSON.parseObject(jsonAccessToken);
String accessToken = jsonObjAccessToken.getString("access_token");

// 获取UserInfo
String jsonUserInfo = getUserInfo(accessToken, code);
JSONObject jsonObjUserInfo = JSON.parseObject(jsonUserInfo);
String userTicket = jsonObjUserInfo.getString("user_ticket");

// UserDetail
String jsonUserDetail = getUserDetail(accessToken, userTicket);
JSONObject jsonObjUserDetail = JSON.parseObject(jsonUserDetail);
String mobile = jsonObjUserDetail.getString("mobile");
return mobile;
}

public String getCorpId() {
return corpId;
}

public void setCorpId(String corpId) {
this.corpId = corpId;
}

public String getSecret() {
return secret;
}

public void setSecret(String secret) {
this.secret = secret;
}

private String httpGet(String url) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpGet get = new HttpGet(url);
response = httpClient.execute(get);
int status = response.getStatusLine().getStatusCode();

LOGGER.info("http状态码: {}", status);
if (status == 200) {

HttpEntity entity = response.getEntity();
String stringEntity = EntityUtils.toString(entity);

return stringEntity;
} else {
LOGGER.warn("url:{},get请求异常,返回的状态码是:{}", url, status);
}
} catch (IOException e) {
LOGGER.warn("url:{},get请求异常。{}", url, e.getMessage());
} finally {
try {
httpClient.close();
response.close();
} catch (IOException e) {
LOGGER.warn(e.getMessage());
}
}
return null;
}

private String httpPost(String url, Map<String, String> maps) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

if (maps != null && maps.size() > 0) {
String content = JSON.toJSONString(maps);
StringEntity entity = new StringEntity(content, ContentType.create("application/json", "UTF-8"));
post.setEntity(entity);
}

response = httpClient.execute(post);
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String stringEntity = EntityUtils.toString(entity);
return stringEntity;
} else {
LOGGER.warn("url:{},post请求异常,返回的状态码是:{}", url, status);
}
} catch (IOException e) {
LOGGER.warn("url:{},post请求异常。{}", url, e.getMessage());
} finally {
try {
httpClient.close();
response.close();
} catch (IOException e) {
LOGGER.warn(e.getMessage());
}
}
return null;
}

@Override
public String toString() {
return "WeChatUtil [corpId=" + corpId + ", secret=" + secret + "]";
}

}

这里面有2个成员属性:corpId,secret。你可以直接给他俩赋值,我因为用了SpringBoot,所以通过@ConfigurationProperties从属性文件中读取属性值。

application.properties

wechat.corpId=wxc0b47763abea****
wechat.secret=vJKxb17klTsRdYncXuscbNOw6ncm1GgxZ4uZ_oDN7cWn9H8tABuDcgJk3oXs****

调用示例:

String code = request.getParameter("code");
LOGGER.info("code:{}", code);

String mobile = weChatUtil.getMobile(code);
LOGGER.info("mobile:{}", mobile);

下面简单说一下执行过程:

第一步:

进入企业号的应用后,点击底部菜单,这时跳转到一个授权的URL,URL示例:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc0b47763abea****&redirect_uri=http://vx.school1024.com/api/wechat/login&response_type=code&scope=snsapi_privateinfo&agentid=2&state=school1024#wechat_redirect。

点击同意授权后,会重定向到redirect_uri参数指定的url,并附带code参数。

第二步:

redirect_uri参数指定的url对应的Controller通过request获取url中携带的code。

第三步:

根据code调用WeChatUtil里的getMobile方法,方法里会和微信服务接口交互几次,最终获取到手机号,然后你就可以根据手机号做各种操作了,但有个前提是你的手机号和你系统中的用户要绑定了才行。


我这里用获取的手机号做了登录功能,shrio加了一个微信手机号登录的Realm。这样微信端的登录和PC端就没什么区别了。

分享到