当前位置:   article > 正文

微信小程序(旧): java实现获取手机号方式_java 微信小程序获取手机号

java 微信小程序获取手机号

目录

1. 现在比较简单的方式

-> 接口名

---> 功能描述

-> 调用方式

---> HTTPS 调用

---> 第三方调用

---> 请求参数

---> 返回参数

2. 实现方式

1. 加入fastjson依赖 

2. http请求类

3. Json串工具类

4.接口方法

3.另外介绍一点access_token


1. 现在比较简单的方式

统一封装最新文章地址(可跳过): 微信小程序02: 使用手机号快速验证获取手机号(新版)

下面(旧版)的可以直接使用, 上面的文章(最新)进行了同一封装

-> 接口名

getPhoneNumber

---> 功能描述

该接口需配合手机号快速填写组件能力一起使用,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到动态令牌code,再调用该接口将code换取用户手机号。

注意:每个code只能使用一次,code的有效期为5min。

-> 调用方式

---> HTTPS 调用

  1. POST https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN

---> 第三方调用

  • 调用方式以及出入参和HTTPS相同,仅是调用的token不同

  • 该接口所属的权限集id为:18

  • 服务商获得其中之一权限集授权后,可通过使用authorizer_access_token代商家进行调用

---> 请求参数

属性类型必填说明
access_tokenstring接口调用凭证,该参数为 URL 参数,非 Body 参数。使用access_token或者authorizer_access_token
codestring手机号获取凭证

---> 返回参数

属性类型说明
errcodenumber错误码
errmsgstring错误信息
phone_infoobject用户手机号信息
属性类型说明
phoneNumberstring用户绑定的手机号(国外手机号会有区号)
purePhoneNumberstring没有区号的手机号
countryCodestring区号
watermarkobject数据水印
属性类型说明
timestampnumber用户获取手机号操作的时间戳
appidstring小程序appid

2. 实现方式

1. 加入fastjson依赖 

  1.   <dependency>
  2.             <groupId>com.alibaba</groupId>
  3.             <artifactId>fastjson</artifactId>
  4.             <version>1.2.75</version>
  5.         </dependency>

2. http请求类

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.apache.http.client.config.RequestConfig;
  3. import org.apache.http.client.entity.UrlEncodedFormEntity;
  4. import org.apache.http.client.methods.CloseableHttpResponse;
  5. import org.apache.http.client.methods.HttpGet;
  6. import org.apache.http.client.methods.HttpPost;
  7. import org.apache.http.entity.ContentType;
  8. import org.apache.http.entity.StringEntity;
  9. import org.apache.http.impl.client.CloseableHttpClient;
  10. import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
  11. import org.apache.http.impl.client.HttpClients;
  12. import org.apache.http.message.BasicHeader;
  13. import org.apache.http.message.BasicNameValuePair;
  14. import org.apache.http.util.EntityUtils;
  15. import org.slf4j.MDC;
  16. import org.springframework.http.HttpStatus;
  17. import org.springframework.util.CollectionUtils;
  18. import java.io.IOException;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. import java.util.Map;
  22. /**
  23. * HTTP/HTTPS 请求封装: GET / POST
  24. * 默认失败重试3次
  25. * @author admin
  26. */
  27. @Slf4j
  28. public class HttpClientSslUtils {
  29. /**
  30. * 默认的字符编码格式
  31. */
  32. private static final String DEFAULT_CHAR_SET = "UTF-8";
  33. /**
  34. * 默认连接超时时间 (毫秒)
  35. */
  36. private static final Integer DEFAULT_CONNECTION_TIME_OUT = 2000;
  37. /**
  38. * 默认socket超时时间 (毫秒)
  39. */
  40. private static final Integer DEFAULT_SOCKET_TIME_OUT = 3000;
  41. /** socketTimeOut上限 */
  42. private static final Integer SOCKET_TIME_OUT_UPPER_LIMIT = 10000;
  43. /** socketTimeOut下限 */
  44. private static final Integer SOCKET_TIME_OUT_LOWER_LIMIT = 1000;
  45. private static CloseableHttpClient getHttpClient() {
  46. RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(DEFAULT_SOCKET_TIME_OUT)
  47. .setConnectTimeout(DEFAULT_CONNECTION_TIME_OUT).build();
  48. return HttpClients.custom().setDefaultRequestConfig(requestConfig)
  49. .setRetryHandler(new DefaultHttpRequestRetryHandler()).build();
  50. }
  51. private static CloseableHttpClient getHttpClient(Integer socketTimeOut) {
  52. RequestConfig requestConfig =
  53. RequestConfig.custom().setSocketTimeout(socketTimeOut).setConnectTimeout(DEFAULT_CONNECTION_TIME_OUT)
  54. .build();
  55. return HttpClients.custom().setDefaultRequestConfig(requestConfig)
  56. .setRetryHandler(new DefaultHttpRequestRetryHandler()).build();
  57. }
  58. public static String doPost(String url, String requestBody) throws Exception {
  59. return doPost(url, requestBody, ContentType.APPLICATION_JSON);
  60. }
  61. public static String doPost(String url, String requestBody, Integer socketTimeOut) throws Exception {
  62. return doPost(url, requestBody, ContentType.APPLICATION_JSON, null, socketTimeOut);
  63. }
  64. public static String doPost(String url, String requestBody, ContentType contentType) throws Exception {
  65. return doPost(url, requestBody, contentType, null);
  66. }
  67. public static String doPost(String url, String requestBody, List<BasicHeader> headers) throws Exception {
  68. return doPost(url, requestBody, ContentType.APPLICATION_JSON, headers);
  69. }
  70. public static String doPost(String url, String requestBody, ContentType contentType, List<BasicHeader> headers)
  71. throws Exception {
  72. return doPost(url, requestBody, contentType, headers, getHttpClient());
  73. }
  74. public static String doPost(String url, String requestBody, ContentType contentType, List<BasicHeader> headers,
  75. Integer socketTimeOut) throws Exception {
  76. if (socketTimeOut < SOCKET_TIME_OUT_LOWER_LIMIT || socketTimeOut > SOCKET_TIME_OUT_UPPER_LIMIT) {
  77. log.error("socketTimeOut非法");
  78. throw new Exception();
  79. }
  80. return doPost(url, requestBody, contentType, headers, getHttpClient(socketTimeOut));
  81. }
  82. /**
  83. * 通用Post远程服务请求
  84. * @param url
  85. * 请求url地址
  86. * @param requestBody
  87. * 请求体body
  88. * @param contentType
  89. * 内容类型
  90. * @param headers
  91. * 请求头
  92. * @return String 业务自行解析
  93. * @throws Exception
  94. */
  95. public static String doPost(String url, String requestBody, ContentType contentType, List<BasicHeader> headers,
  96. CloseableHttpClient client) throws Exception {
  97. // 构造http方法,设置请求和传输超时时间,重试3次
  98. CloseableHttpResponse response = null;
  99. long startTime = System.currentTimeMillis();
  100. try {
  101. HttpPost post = new HttpPost(url);
  102. if (!CollectionUtils.isEmpty(headers)) {
  103. for (BasicHeader header : headers) {
  104. post.setHeader(header);
  105. }
  106. }
  107. StringEntity entity =
  108. new StringEntity(requestBody, ContentType.create(contentType.getMimeType(), DEFAULT_CHAR_SET));
  109. post.setEntity(entity);
  110. response = client.execute(post);
  111. if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
  112. log.error("业务请求返回失败:{}", EntityUtils.toString(response.getEntity()));
  113. throw new Exception();
  114. }
  115. String result = EntityUtils.toString(response.getEntity());
  116. return result;
  117. } finally {
  118. releaseResourceAndLog(url, requestBody, response, startTime);
  119. }
  120. }
  121. /**
  122. * 暂时用于智慧园区业务联调方式
  123. * @param url 业务请求url
  124. * @param param 业务参数
  125. * @return
  126. * @throws Exception
  127. */
  128. public static String doPostWithUrlEncoded(String url,
  129. Map<String, String> param) throws Exception {
  130. // 创建Httpclient对象
  131. CloseableHttpClient httpClient = getHttpClient();
  132. CloseableHttpResponse response = null;
  133. long startTime = System.currentTimeMillis();
  134. try {
  135. // 创建Http Post请求
  136. HttpPost httpPost = new HttpPost(url);
  137. // 创建参数列表
  138. if (param != null) {
  139. List<org.apache.http.NameValuePair> paramList = new ArrayList<>();
  140. for (String key : param.keySet()) {
  141. paramList.add(new BasicNameValuePair(key, param.get(key)));
  142. }
  143. // 模拟表单
  144. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, DEFAULT_CHAR_SET);
  145. httpPost.setEntity(entity);
  146. }
  147. // 执行http请求
  148. response = httpClient.execute(httpPost);
  149. if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
  150. log.error("业务请求返回失败:{}" , EntityUtils.toString(response.getEntity()));
  151. throw new Exception();
  152. }
  153. String resultString = EntityUtils.toString(response.getEntity(), DEFAULT_CHAR_SET);
  154. return resultString;
  155. } finally {
  156. releaseResourceAndLog(url, param == null ? null : param.toString(), response, startTime);
  157. }
  158. }
  159. private static void releaseResourceAndLog(String url, String request, CloseableHttpResponse response, long startTime) {
  160. if (null != response) {
  161. try {
  162. response.close();
  163. recordInterfaceLog(startTime, url, request);
  164. } catch (IOException e) {
  165. log.error(e.getMessage());
  166. }
  167. }
  168. }
  169. public static String doGet(String url) throws Exception {
  170. return doGet(url, ContentType.DEFAULT_TEXT);
  171. }
  172. public static String doGet(String url, ContentType contentType) throws Exception {
  173. return doGet(url, contentType, null);
  174. }
  175. public static String doGet(String url, List<BasicHeader> headers) throws Exception {
  176. return doGet(url, ContentType.DEFAULT_TEXT, headers);
  177. }
  178. /**
  179. * 通用Get远程服务请求
  180. * @param url
  181. * 请求参数
  182. * @param contentType
  183. * 请求参数类型
  184. * @param headers
  185. * 请求头可以填充
  186. * @return String 业务自行解析数据
  187. * @throws Exception
  188. */
  189. public static String doGet(String url, ContentType contentType, List<BasicHeader> headers) throws Exception {
  190. CloseableHttpResponse response = null;
  191. long startTime = System.currentTimeMillis();
  192. try {
  193. CloseableHttpClient client = getHttpClient();
  194. HttpGet httpGet = new HttpGet(url);
  195. if (!CollectionUtils.isEmpty(headers)) {
  196. for (BasicHeader header : headers) {
  197. httpGet.setHeader(header);
  198. }
  199. }
  200. if(contentType != null){
  201. httpGet.setHeader("Content-Type", contentType.getMimeType());
  202. }
  203. response = client.execute(httpGet);
  204. if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
  205. log.error("业务请求返回失败:{}", EntityUtils.toString(response.getEntity()));
  206. throw new Exception();
  207. }
  208. String result = EntityUtils.toString(response.getEntity());
  209. return result;
  210. } finally {
  211. releaseResourceAndLog(url, null, response, startTime);
  212. }
  213. }
  214. private static void recordInterfaceLog(long startTime, String url, String request) {
  215. long endTime = System.currentTimeMillis();
  216. long timeCost = endTime - startTime;
  217. MDC.put("totalTime", String.valueOf(timeCost));
  218. MDC.put("url", url);
  219. MDC.put("logType", "third-platform-service");
  220. log.info("HttpClientSslUtils 远程请求:{} 参数:{} 耗时:{}ms", url, request, timeCost);
  221. }
  222. }

3. Json串工具类

  1. import com.alibaba.fastjson.TypeReference;
  2. import com.fasterxml.jackson.annotation.JsonInclude;
  3. import com.fasterxml.jackson.core.JsonProcessingException;
  4. import com.fasterxml.jackson.databind.DeserializationFeature;
  5. import com.fasterxml.jackson.databind.JsonNode;
  6. import com.fasterxml.jackson.databind.ObjectMapper;
  7. import com.fasterxml.jackson.databind.SerializationFeature;
  8. import lombok.extern.slf4j.Slf4j;
  9. import org.springframework.util.StringUtils;
  10. import java.text.SimpleDateFormat;
  11. @Slf4j
  12. public class JsonUtil {
  13. /**
  14. * 定义映射对象
  15. */
  16. public static ObjectMapper objectMapper = new ObjectMapper();
  17. /**
  18. * 日期格式化
  19. */
  20. private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
  21. static {
  22. //对象的所有字段全部列入
  23. objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
  24. //取消默认转换timestamps形式
  25. objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
  26. //忽略空Bean转json的错误
  27. objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
  28. //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
  29. objectMapper.setDateFormat(new SimpleDateFormat(DATE_FORMAT));
  30. //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
  31. objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  32. }
  33. /**
  34. * string转JsonNode
  35. *
  36. * @param jsonString
  37. * @return com.fasterxml.jackson.databind.JsonNode
  38. */
  39. public static JsonNode stringToJsonNode(String jsonString) throws JsonProcessingException {
  40. return objectMapper.readTree(jsonString);
  41. }
  42. /**
  43. * 对象转json字符串
  44. *
  45. * @param obj
  46. * @param <T>
  47. */
  48. public static <T> String objToString(T obj) {
  49. if (obj == null) {
  50. return null;
  51. }
  52. try {
  53. return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
  54. } catch (JsonProcessingException e) {
  55. log.warn("Parse Object to String error : {}", e.getMessage());
  56. return null;
  57. }
  58. }
  59. /**
  60. * 对象转格式化的字符串字符串
  61. *
  62. * @param obj
  63. * @param <T>
  64. * @return
  65. */
  66. public static <T> String objToPrettyString(T obj) {
  67. if (obj == null) {
  68. return null;
  69. }
  70. try {
  71. return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
  72. } catch (JsonProcessingException e) {
  73. log.warn("Parse Object to String error : {}", e.getMessage());
  74. return null;
  75. }
  76. }
  77. /**
  78. * json字符串转对象
  79. *
  80. * @param jsonString
  81. * @param cls
  82. * @param <T>
  83. */
  84. public static <T> T stringToObj(String jsonString, Class<T> cls) {
  85. if (StringUtils.isEmpty(jsonString) || cls == null) {
  86. return null;
  87. }
  88. try {
  89. return cls.equals(String.class) ? (T) jsonString : objectMapper.readValue(jsonString, cls);
  90. } catch (JsonProcessingException e) {
  91. log.warn("Parse String to Object error : {}", e.getMessage());
  92. return null;
  93. }
  94. }
  95. }

4.接口方法

  1. @PostMapping("/getPhone")
  2. public ResultResponse getPhone(@RequestBody @Valid WxMiniGetPhone param) {
  3. JSONObject wxJson;
  4. // 获取token
  5. String token_url = null;
  6. /**
  7. * appid切换
  8. */
  9. if (param.getWxAppletType() == 1) {
  10. token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", bAppID, bAppSecret);
  11. } else if (param.getWxAppletType() == 2) {
  12. token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", aAppId, aSecret);
  13. } else {
  14. throw new UserServiceException("异常");
  15. }
  16. try {
  17. JSONObject token = JSON.parseObject(HttpClientSslUtils.doGet(token_url));
  18. if (token == null) {
  19. log.info("获取token失败");
  20. return null;
  21. }
  22. String accessToken = token.getString("access_token");
  23. if (StringUtils.isEmpty(accessToken)) {
  24. log.info("获取token失败");
  25. return null;
  26. }
  27. log.info("token : {}", accessToken);
  28. //获取phone
  29. String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber"
  30. + "?access_token=" + accessToken;
  31. JSONObject jsonObject = new JSONObject();
  32. jsonObject.put("code", param.getCode());
  33. String reqJsonStr = JsonUtil.objToString(jsonObject);
  34. wxJson = JSON.parseObject(HttpClientSslUtils.doPost(url, reqJsonStr));
  35. if (wxJson == null) {
  36. log.info("获取手机号失败");
  37. return ResultResponse.error("获取手机号失败!");
  38. }
  39. return ResultResponse.ok("获取成功!").setData(wxJson);
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. return ResultResponse.error("获取失败,请重试!");
  44. }

3.另外介绍一点access_token

access_token是有次数限制的 一天2000次 超过了需要刷新accessToken限制次数,10次/月

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/284659
推荐阅读
相关标签
  

闽ICP备14008679号