公众号的一些配置以及前面的域名配置我这里就不说了,我这里只记录了后端的签名接口
controller,就是普通的post请求,这里需要前端把扫一扫的那个页面url发给你,需要进行转码处理的url
@PostMapping("/wxScan") public R wxScan(@RequestBody Map<String,String> map)throws Exception{ String url = map.get("url"); if(StrBlankUtils.isBlank(url)){ return new R(new Exception("url不能为空")); } return userService.wxScan(map); }
service
@Override public R wxScan(Map<String ,String> map2) { Map<String, Object> map = new HashMap<>(); String accessToken = getAccessToken(); Object jsApiTicket = getJsApiTicket(accessToken); String nonceStr = UUID.randomUUID().toString(); String timestamp = Long.toString(System.currentTimeMillis() / 1000); String string1; String signature = ""; //注意这里参数名必须全部小写,且必须有序 string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + map2.get("url"); System.out.println("string1:"+string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (Exception e) { e.printStackTrace(); } map.put("url", map2.get("url")); map.put("jsapi_ticket", jsApiTicket); map.put("nonceStr", nonceStr); map.put("timestamp", timestamp); map.put("signature", signature); map.put("appId", WechatConstants.PUBLIC_APP_ID);//公众号的appid return new R(map); }
里面用到的方法
/** * 普通基础调用所需 * @return */ public String getAccessToken() { Object dhx_accessToken = redisTemplate.opsForValue().get("JFQ_AccessToken"); if(dhx_accessToken==null||StringUtils.isBlank(dhx_accessToken.toString())){ try{ /** *String GET_ACCESS_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token"; */ String path = WechatConstants.GET_ACCESS_TOKEN_URL+"?" + "appid="+ WechatConstants.PUBLIC_APP_ID + "&secret="+ WechatConstants.PUBLIC_APP_SECRET + "&grant_type=client_credential"; Connection connect = Jsoup.connect(path); Connection.Response response = connect.method(Connection.Method.GET).ignoreContentType(true).execute(); String body = response.body(); log.info(body); String access_token = new Gson().fromJson(body, Map.class).get("access_token").toString(); if(StringUtils.isNotBlank(access_token)){ redisTemplate.opsForValue().set("JFQ_AccessToken",access_token,1200, TimeUnit.SECONDS); } return access_token ; }catch (Exception e){ return ""; } } return dhx_accessToken.toString(); }
private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; }
public static String doGet(String url, Map<String, String> param) { // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpGet httpGet = new HttpGet(uri); // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doGet(String url) { return doGet(url, null); }
public String getJsApiTicket(String token) { Object JsApiTicket = redisTemplate.opsForValue().get("JFQ_JsApiTicket"); if(JsApiTicket==null){ //String JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; String url = WechatConstants.JSAPI_TICKET + "?access_token=" + token + "&type=jsapi"; String msg = doGet(url); if (StringUtils.isBlank(msg)) { return null; } Map map = new Gson().fromJson(msg, Map.class); String ticket = String.valueOf(map.get("ticket")); redisTemplate.opsForValue().set("JFQ_JsApiTicket",ticket,1200, TimeUnit.SECONDS); return ticket; }else{ return JsApiTicket.toString(); } }