微信小程序获取手机号,前端+后端接口
官方文档
需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,通过 @getphonenumber事件回调获取到动态令牌code,然后把code发送给服务器。
org.apache.httpcomponents
httpclient
4.5.2
org.projectlombok
lombok
1.18.20
com.alibaba
fastjson
1.2.28
用于向指定 URL 发送json格式参数的POST方法的请求
import org.apache.http.Consts;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
public class HttpClient {
/**
* 向指定 URL 发送json格式参数的POST方法的请求
*
* @param url 发送请求的 URL
* @param json json格式请求参数
* @return 所代表远程资源的响应结果
*/
public static String postJson(String url, String json, Map headMap) {
String returnStr;
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
try {
HttpPost post = new HttpPost(url);
post.setConfig(RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build());
httpClient = HttpClientBuilder.create().build();
StringEntity s = new StringEntity(json, Consts.UTF_8);
s.setContentType("application/json");
if (headMap != null && headMap.size() > 0) {
Set keySet = headMap.keySet();
for (String key : keySet) {
post.addHeader(key, headMap.get(key));
}
}
post.setEntity(s);
httpResponse = httpClient.execute(post);
BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(),
StandardCharsets.UTF_8.name()));
StringBuilder stringBuffer = new StringBuilder(100);
String str;
while ((str = reader.readLine()) != null) {
stringBuffer.append(str);
}
returnStr = stringBuffer.toString();
reader.close();
return returnStr;
} catch (SocketTimeoutException e) {
System.out.println("地址: [{}]|参数: [{}] 读取超时"+ url+"::"+ json);
return "";
} catch (ConnectTimeoutException e) {
System.out.println("地址: [{}]|参数: [{}] 连接超时"+ url+"::"+ json);
return "";
} catch (Exception e) {
System.out.println("地址: [{}]|参数: [{}] 请求异常: [{}]"+ url+"::"+ json+"::"+ e);
return "";
} finally {
HttpClientUtils.closeQuietly(httpResponse);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
官方文档
获取小程序全局唯一后台接口调用凭据(access_token)。调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存。
自定义封装一个获取access_token的工具类
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
// 小程序全局唯一后台接口调用凭据
public class AccessToken {
// access_token
private static String access_token;
// access_token过期时间
private static long expiration;
// 获取小程序全局唯一后台接口调用凭据
public static String getAccessToken() {
// 判断access_token是否过期
if (System.currentTimeMillis() < expiration) {//没过期 继续用
return access_token;
} else {//过期了 重新获取
// 请求参数
Map map = new HashMap<>();
map.put("grant_type", "client_credential");// 固定值无需改变
map.put("appid", "wxa43df9443851eb55"); // 你自己的微信小程序appid
map.put("secret", "b9e8c7646c18bb34fef06a5be6a6f77c");// 你自己的微信小程序密钥
// 发送请求 得到结果
String res = HttpClientUtil.doGet("https://api.weixin.qq.com/cgi-bin/token", map);
// 解析请求结果
JSONObject resJson = JSONObject.parseObject(res);
// 获取到的凭证
access_token = resJson.get("access_token").toString();
// 凭证有效时间,单位:秒。目前是7200秒之内的值。
int expires_in = Integer.valueOf(resJson.get("expires_in").toString());
// 计算出过期时间的时间戳
expiration = System.currentTimeMillis() + expires_in * 1000;
return access_token;
}
}
}
官方文档
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.utilds.AccessToken;
import com.example.demo.utilds.HttpClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class PhoneController {
// 获取用户手机号
@GetMapping("/getPhone")
public String getPhone(String code) {
System.out.println("小程序发来的code值:" + code);
// 调用封装的AccessToken类获取access_token
String access_token = AccessToken.getAccessToken();
System.out.println("access_token:" + access_token);
// 准备请求
// 请求url 拼接上access_token
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + access_token;
// 请求参数
Map map = new HashMap<>(1);
map.put("code", code);
// 发起请求 注意请求参数map要转成json字符串
String res = HttpClient.postJson(url, JSON.toJSONString(map), null);
// 解析请求结果 拿到手机号
JSONObject jsonObject = JSONObject.parseObject(res);
String phone_info = jsonObject.get("phone_info").toString();
JSONObject jsonPhone_info = JSONObject.parseObject(phone_info);
String phoneNumber = jsonPhone_info.get("phoneNumber").toString();
System.out.println("用户手机号:"+phoneNumber);
return phoneNumber;
}
}