微信小程序獲取token、登錄、獲取二維碼操作

說明

目前項目當中用到了微信小程序的登錄獲取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,在上面的方法已經說明了,就不重複了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章