说明

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