如何用Spring Boot获取微信运动

创建第三方服务器工程

我们知道小程序是基于微信团队开发的IDE,设计模式类似Vue.js。

新建项目时首先需要选择->建立第三方服务器。(小程序版本更新快,已经集成多种开发模式。在此,为何不选择最方便的开发模式,因为最开始开发此项目时还未出现各种云服务开发等。)

用户微信身份授权

image

可以查看微信官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/

详细了解如何获取openid和session_key。

微信运动-前端处理

发送请求:

    var code
    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        code = res.code
      }
    })

    wx.getWeRunData({
      success(res) {
        var encryptedData = res.encryptedData
        var iv = res.iv
        wx.request({
          url: app.globalData.host + "/Cal/step",
          method: "post",
          header: {
            'content-type': 'application/json',
            'cookie': cookie
          },
          data: {
            code: code,
            encryptedData: encryptedData,
            iv: iv
          },
          success: function(res) {
            res = res.data
            console.log(res)
            if (res.status == "1") {
              self.setData({
                step: res.step
              })
            }
            setTimeout(() => {
              wx.hideLoading()
              wx.stopPullDownRefresh();
            }, 1000)
          }
        })
      }
    })

其中encryptedData,iv是做为获取运动步数的依据


image.png

前端将 code,encryptedData,iv的加密数据提交到后台处理。

微信运动-后端处理

controller层获取数据:

    @PostMapping("/step") // 用户授权获取微信步数
    public Map<String, Object> step(@RequestBody pass pass1) throws Exception {

        Map<String, String> param = new HashMap<String, String>();
        Map<String, Object> msg1 = new HashMap<String, Object>();
        // 登录凭证不能为空
        if (pass1.getCode() == null || pass1.getCode().length() == 0) {
            msg1.put("status", "0");
            msg1.put("msg", "code 不能为空");
            return msg1;
        }
//获取用户的code,用过URL和APPID 和 SECREET还有code向微信服务器获得OPENID和SEESION_KEY
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        param.put("appid", "你的微信appid");
        param.put("secret", "获取到的secret加密串");
        param.put("js_code", pass1.getCode());
        param.put("grant_type", "authorization_code");

        String wxResult = HttpClientUtil.doGet(url, param);

        WXSessionModel wxSessionModel = JsonUtils.jsonToPojo(wxResult, WXSessionModel.class);
        String sessionkey = wxSessionModel.getSession_key();
        String openid = wxSessionModel.getOpenid();
        System.out.println("用户步数session_key:" + sessionkey);
        try {
            // 利用AES类Base64解密算法解密用户敏感信息
            byte[] bytes = AES.decrypt(Base64.decodeBase64(sessionkey), 
                                                                    Base64.decodeBase64(pass1.getIv()),
                                                Base64.decodeBase64(pass1.getEncryptedData()));
            String theStep = new String(bytes, "UTF8");
            System.out.println(theStep);// 解密后获取到用户过去30天的JSON字符串组成的步数
            JSONObject jsonObject = JSON.parseObject(theStep);// 将字符串转化为json形式取出今日步数
            JSONObject jsstep = (JSONObject) jsonObject.getJSONArray("stepInfoList").get(30);// 获取微信用户当前步数

            String getstep = jsstep.getString("step");
            int step= Integer.parseInt(getstep);
                msg1.put("status", "1");
            msg1.put("step",step);
              } catch (Exception e) {
                e.printStackTrace();
            }
        return msg1;
    }

创建AES类Base64解密算法

public class AES {
    /**
     * 解密算法
     * @param sessionkey 小程序登录sessionKey
     * @param iv 向量
     * @param encryptedData
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidAlgorithmParameterException
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static byte[] decrypt(byte[] sessionkey, byte[] iv, byte[] encryptedData)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(sessionkey, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        return cipher.doFinal(encryptedData);
    }
}

HttpClientUtil.java 发送请求至微信服务器

public class HttpClientUtil {

    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 static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }
    
    public static String doPost(String url) {
        return doPost(url, null);
    }
    
    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }
}

JsonUtils.java 用于将对象转化为json字符串

public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
}

以上是做为第三方服务器需要获取到微信运动的流程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容