微信小程式二維碼(JAVA)
阿新 • • 發佈:2018-12-07
前言
最近在做小程式相關的專案,之前也在網上找過很多資料,遇到不少坑,和大家分享一下成果。
簡介
小程式獲取二維碼有官網三種介面:
- POST https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN:獲取小程式二維碼,適用於需要的碼數量較少的業務場景。
- POST https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN:獲取小程式碼,適用於需要的碼數量較少的業務場景。
- 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。。。
結語
從微信支付到微信小程式,一路坑過,希望我走過的路對你有點用。