說明
目前項目當中用到了微信小程序的登錄獲取token和二維碼的操作,因此在此記錄一下,方法比較簡單也好理解。
登錄相關
登錄Controller
/**
* 獲取用戶的openId
*
* @param codeId 微信小程序code
* @return
* @author zhongsy
* @date 2019/12/24
*/
@RequestMapping(value = "/doGetOpenid", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String login(ModelMap model, HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "codeId") String codeId) {
//微信的接口
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + SystemConfig.get("sys.applet.appid") +
"&secret=" + SystemConfig.get("sys.applet.secret") + "&js_code=" + codeId + "&grant_type=authorization_code";
RestTemplate restTemplate = new RestTemplate();
//進行網絡請求,訪問url接口
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
//根據返回值進行後續操作
if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
String sessionData = responseEntity.getBody();
System.out.println("打印調用微信小程序登錄接口返回值:" + sessionData);
Gson gson = new Gson();
WeChatSession weChatSession = gson.fromJson(sessionData, WeChatSession.class);
//獲取用戶的唯一標識
String openid = weChatSession.getOpenid();
//獲取會話祕鑰
String session_key = weChatSession.getSession_key();
//業務代碼
return openid;
} else {
throw new EcRuntimeException("獲取用戶信息失敗,請重試");
}
}
登錄接口實體類
/**
* @author zhongsy
* @Description:
* @Title: 微信小程序用戶
* @Created by zhongshuiayou on 2019/12/9 14:55
*/
public class WeChatSession {
private String openid;
private String session_key;
private String unionid;
private Integer errcode;
private String errmsg;
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getSession_key() {
return session_key;
}
public void setSession_key(String session_key) {
this.session_key = session_key;
}
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
登錄接口說明
相對來說如果你只是用到登錄接口獲取openId,那可以直接返回openId,如果要和本身項目中的結合,那可以需要別的處理,看業務吧大概請求微信是這麼個步驟;另外appid和祕鑰 是寫在配置文件當中的,大家自行根據項目修改就好了
獲取token
獲取token的工具類
/**
* 獲取微信小城的accesstoken
*
* @param
* @return java.lang.String
* @author zhongsy
* @date 2019/12/28
*/
public String getWxAppletAccessToken() {
if (!redisUtil.exists(WX_APPLET_ACCESS_TOKEN_KEY)){
RestTemplate restTemplate = new RestTemplate();
//進行網絡請求,訪問url接口
ResponseEntity<String> responseEntity = restTemplate.exchange(GET_ACCESS_TOKEN_URL + "&appid=" + SystemConfig.get("sys.applet.appid") + "&secret=" + SystemConfig.get("sys.applet.secret"), HttpMethod.GET, null, String.class);
//根據返回值進行後續操作
if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
String result = responseEntity.getBody();
System.out.println("打印調用微信小程序獲取token返回值:" + result);
Gson gson = new Gson();
WxAppletAccessToken wxAppletAccessToken = gson.fromJson(result, WxAppletAccessToken.class);
// if (wxAppletAccessToken.getErrcode()==null||wxAppletAccessToken.getErrcode()==0){
String accessToken = wxAppletAccessToken.getAccess_token();
Long expires = wxAppletAccessToken.getExpires_in();
redisUtil.set(WX_APPLET_ACCESS_TOKEN_KEY,accessToken,expires);
return accessToken;
// }else {
// throw new EcRuntimeException("獲取小程序token失敗,請重試");
// }
} else {
throw new EcRuntimeException("獲取小程序token失敗,請重試");
}
}else {
return redisUtil.getString(WX_APPLET_ACCESS_TOKEN_KEY);
}
}
獲取token的實體類
package com.jerehsoft.mobile.wxApplet.entity;
/**
* @author zhongshuiayou
* @Description:
* @Title: 微信小程序獲取access_token實體類
* @Created by zhongsy on 2019/12/28 11:32
*/
public class WxAppletAccessToken {
/**
* 獲取到的憑證
*/
private String access_token;
/**
* 憑證有效時間,單位:秒。目前是7200秒之內的值。
*/
private Long expires_in;
/**
* 錯誤碼
*/
private Integer errcode;
/**
* 錯誤信息
*/
private Integer errmsg;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public Long getExpires_in() {
return expires_in;
}
public void setExpires_in(Long expires_in) {
this.expires_in = expires_in;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public Integer getErrmsg() {
return errmsg;
}
public void setErrmsg(Integer errmsg) {
this.errmsg = errmsg;
}
}
獲取token說明
- 思路:被動獲取token,先判斷redis當中是否有token,如果沒有則獲取,有則返回token
- 爲什麼放在redis中:根據官網的文檔token是有時效因此放在redis中更加的方便
- token的解釋:根據官方文檔token分爲兩種,還有一種是網頁授權用的,那個token只能用一次,大家在做項目的時候需要注意
- redis工具類 :暫時就不提供redis工具類了,大家需要就自行百度吧
獲取小程序二維碼
獲取小程序二維碼Controller
/**
* 獲取二維碼
*
* @param
* @return
* @author zhongsy
* @date 2019/12/24
*/
@RequestMapping(value = "/doGetQRCode", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Object doGetQRCode(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "path") String path) throws IOException {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
JSONObject jsonObject = new JSONObject();
jsonObject.put("path", path);
jsonObject.put("width", 430);
HttpEntity<String> formEntity = new HttpEntity<String>(jsonObject.toString(), headers);
ResponseEntity<Resource> responseEntity = restTemplate.postForEntity(GET_QR_CODE + "?access_token=" + wxAppletUtil.getWxAppletAccessToken(), formEntity, Resource.class);
if (responseEntity.getStatusCode().value() == HttpStatus.OK.value()) {
InputStream responseImputStream = responseEntity.getBody().getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = responseImputStream.read(buff, 0, 100)) > 0) {
byteArrayOutputStream.write(buff, 0, rc);
}
byte[] data = byteArrayOutputStream.toByteArray();
return new String(Base64.encodeBase64(data));
} else {
return "獲取二維碼失敗";
}
}
獲取二維碼操作說明
- 獲取二維碼接口:官方文檔有三個獲取二維碼的接口,使用方式都是大同小異的,此次調用的是第一種。
- 說明:首先說官方文檔的文檔有時候讓人很迷,這個接口看官方文檔發返回值是JSON類型的,但是實際當中如果請求成功了返回的是一個圖片的流,需要處理成base64返回給前臺,或者存到本地返回給前臺,這個看項目具體需求;然後對於請求失敗看文檔顯示的應該是返回JSON,因此這種處理可能不夠完美,具體的我沒有測試過,因爲我暫時沒有碰到請求失敗的情況。
- 關於失敗開發當中碰到的問題:當你發現請求失敗的話,首先應該確定請求格式和請求頭是否正確,確定之後基本就沒有問題了。
- 接口的前序工作:主要是獲取token,在上面的方法已經說明了,就不重複了