说明
目前项目当中用到了微信小程序的登录获取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,在上面的方法已经说明了,就不重复了