1. 程式人生 > >微信小程式二維碼(JAVA)

微信小程式二維碼(JAVA)

前言

最近在做小程式相關的專案,之前也在網上找過很多資料,遇到不少坑,和大家分享一下成果。

簡介

小程式獲取二維碼有官網三種介面:

  1. POST https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN:獲取小程式二維碼,適用於需要的碼數量較少的業務場景。
  2. POST https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN:獲取小程式碼,適用於需要的碼數量較少的業務場景。
  3. POST https://api.weixin.qq.com/wxa/getWXACodeUnlimit?access_token=ACCESS_TOKEN:獲取小程式碼,適用於需要的碼數量極多的業務場景。

    這三種方案前提都是要獲取access_token,大家可根據各自需求選擇。

獲取access_token

核心程式碼如下:

private static AppletTokenResult getAppletToken(String key){
		AppletTokenResult tokenResult = new AppletTokenResult();
		String getaccess_tokenurl = "https://api.weixin.qq.com/cgi-bin/token?" +
				"grant_type=client_credential" +
				"&appid=" + APPID +
				"&secret=" + SECRET;
		RestTemplate restTpl = new RestTemplate();
		String tokenDataStr = restTpl.getForObject(getaccess_tokenurl, String.class);
		if(StringUtil.isEmpty(tokenDataStr)){
			throw new CommonException("小程式獲取token失敗!");
		}
		tokenResult = new Gson().fromJson(tokenDataStr, AppletTokenResult.class);
		if(StringUtil.isEmpty(tokenResult.getAccess_token())){
			throw new CommonException("小程式獲取token失敗!");
		}
		int expire = 2 * 60 * 55;
		int temp = tokenResult.getExpires_in();
		expire = temp == 0 ? expire : temp- 5 * 60;
		redisCache.put(key, (Serializable) tokenResult, expire);
		return tokenResult;
		
	}

AppletTokenResult類定義請求微信平臺access_token返回資訊:


import java.io.Serializable;

/**
 * 小程式獲取token返回資料
 * @author 0200759
 *
 */
public class AppletTokenResult implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 2537928824643088525L;
	
	/**
	 * 小程式token
	 */
	private String access_token;
	
	/**
	 * token有效時間
	 */
	private int expires_in;
	
	public int getExpires_in() {
		return expires_in;
	}

	public void setExpires_in(int expires_in) {
		this.expires_in = expires_in;
	}

	public String getAccess_token() {
		return access_token;
	}

	public void setAccess_token(String access_token) {
		this.access_token = access_token;
	}

}

由於小程式token存在有效時間,超過這個時間需要重新從微信平臺取,我這裡把token放入redis快取裡並設定了快取有效時間(比小程式token有效時間略小)。

獲取二維碼

程式碼如下:

/**
 * 小程式介面
 * @author 0200759
 *
 */
@Controller
@RequestMapping("/applet")
public class AppletController {
	
	
	/**
	 * @param res
	 * 呼叫二維碼介面2(https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN)
	 */
	 @RequestMapping("/getQRCode")
	 public void getQRCode(HttpServletResponse res) {
	        RestTemplate rest = new RestTemplate();
	        InputStream inputStream = null;
	        try {
	        	AppletTokenResult appletTokenResult = CacheAppletUtil.get(Constants.APPLET_TOKEN);
	        	if(appletTokenResult == null || StringUtil.isEmpty(appletTokenResult.getAccess_token())){
	        		throw new CommonException("小程式token獲取失敗!");
	        	}
	            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="
	            			  +appletTokenResult.getAccess_token();
	            Map<String, Object> param= new HashMap<String, Object>();
	            param.put("scene", "xxxx");
	            param.put("page", "pages/index");
	            param.put("width", 430);
	            param.put("auto_color", false);
	            Map<String,Object> line_color = new HashMap<>();
	            line_color.put("r", 0);
	            line_color.put("g", 0);
	            line_color.put("b", 0);
	            param.put("line_color", line_color);
	            HttpHeaders headers = new HttpHeaders();
	            headers.setContentType(MediaType.APPLICATION_JSON);
	            HttpEntity<String> requestEntity = new HttpEntity<String>(new Gson().toJson(param), headers);
	            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, 
	            		requestEntity, byte[].class, new Object[0]);
	            byte[] result = entity.getBody();
	            inputStream = new ByteArrayInputStream(result);
	            
	            IOUtils.copy(inputStream, res.getOutputStream());

	        } catch (Exception e) {
	            new CommonException("呼叫小程式生成微信永久小程式碼URL介面異常!");
	        } finally {
	            if(inputStream != null){
	                try {
	                    inputStream.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
}

這裡使用的二維碼方式是方案三getwxacodeunlimit,有以下幾點需注意:

  • param.put(“scene”, “xxxx”)和param.put(“page”, “pages/index”)必填
  • 需要將引數json化,即new Gson().toJson(param)
  • 我這裡直接把返回的二維碼位元組流寫到HttpServletResponse
  • 不要在controller的getQRCode方法上@ResponseBody。。。

結語

從微信支付到微信小程式,一路坑過,希望我走過的路對你有點用。