java实现微信运动数据,从小程序的获取及存储

1.获取过程及需要的参数,图已经很明显,这个是在网上拿别人的图,写的很好很到位,就不一一解释,比较我也是菜鸟

2,在小程序这边,我们需要用 wx.login来给后台传code(因为微信小程序,不支持在小程序页面使用appid和secret,防止你的信息丢失,所以正式版只能从后台调用接口),注意code只有十分钟有效期,而且每次访问code都是变化的(微信这么写的)


后台代码

public class WxStepController {
    private String appid = "你的appid";
    private String secret = "你的secret";
    private String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=";
    private String url0 = "&grant_type=authorization_code";
    //我自己的注入,------------------------------------
    @Autowired
    private MemberMapper ms;
    @Autowired                                    虚线内的你们可以不要
    private WalkStepMapper ws;
------------------------------------------------------
    protected static final Logger logger = LoggerFactory.getLogger(WxStepController.class);


    @ApiOperation(value = "微信登录")
    @ApiImplicitParam(name = "code",value = "微信code",required = true, dataType = "int")     //两行为swagger的注解,可以不要
    @RequestMapping("/onlogin")
    public String login(String code){
        String oppid="";
        JSONObject oppidObj=null;
        try {
           oppid = new HttpRequestor().doGet(url+code+url0);    //url+code+url0
           oppidObj =JSONObject.fromObject(oppid);
           System.out.println(oppidObj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.debug("获取到的json串"+oppid);
        Gson gson = new Gson();
        return gson.toJson(oppidObj);
    }

这样的话,就能获取到用户session_key,openid(对于一个公众号唯一),

获取到的json,这些数据都是临时,并对公众号唯一,所以你们拿去也没用

3.这时候,我们需要用wx.getWeRunData来获取微信运动的数据,以及加密方式等,用来解密微信运动数据数据


其中,token是用来验证用户是否登录,和传递用户信息的,相信很多都用,因为我这个是app跳小程序,所以传token,如果只是小程序的,传openid即可,因为这就是唯一标识符,openid在上面的json已经获取到

解密方法类AES,直接copy别人的

POM依赖

<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.9.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.2</version>
		</dependency>
		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.3</version>
		</dependency>
		<dependency>
			<groupId>com.hynnet</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>org.json</groupId>
			<artifactId>json</artifactId>
			<version>20160810</version>
		</dependency>

		<!--加密组件-->
		<dependency>
			<groupId>org.bouncycastle</groupId>
			<artifactId>bcprov-jdk15on</artifactId>
			<version>1.57</version>
		</dependency>
		<!--google转json-->
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.3.1</version>
		</dependency>

http请求工具类

import java.io.*;
import java.net.*;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by Administrator on 2018/5/24.
 */
public class HttpRequestor {
    private String charset = "utf-8";
    private Integer connectTimeout = null;
    private Integer socketTimeout = null;
    private String proxyHost = null;
    private Integer proxyPort = null;

    public HttpRequestor() {
    }

    public String doGet(String url) throws Exception {
        URL localURL = new URL(url);
        URLConnection connection = this.openConnection(localURL);
        HttpURLConnection httpURLConnection = (HttpURLConnection)connection;
        httpURLConnection.setRequestProperty("Accept-Charset", this.charset);
        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;
        if(httpURLConnection.getResponseCode() >= 300) {
            throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
        } else {
            try {
                inputStream = httpURLConnection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
                reader = new BufferedReader(inputStreamReader);

                while((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                }
            } finally {
                if(reader != null) {
                    reader.close();
                }

                if(inputStreamReader != null) {
                    inputStreamReader.close();
                }

                if(inputStream != null) {
                    inputStream.close();
                }

            }

            return resultBuffer.toString();
        }
    }

    public String doPost(String url, Map parameterMap) throws Exception {
        StringBuffer parameterBuffer = new StringBuffer();
        if(parameterMap != null) {
            Iterator iterator = parameterMap.keySet().iterator();
            String key = null;
            String value = null;

            while(iterator.hasNext()) {
                key = (String)iterator.next();
                if(parameterMap.get(key) != null) {
                    value = (String)parameterMap.get(key);
                } else {
                    value = "";
                }

                parameterBuffer.append(key).append("=").append(value);
                if(iterator.hasNext()) {
                    parameterBuffer.append("&");
                }
            }
        }

        System.out.println("POST parameter : " + parameterBuffer.toString());
        URL localURL = new URL(url);
        URLConnection connection = this.openConnection(localURL);
        HttpURLConnection httpURLConnection = (HttpURLConnection)connection;
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Accept-Charset", this.charset);
        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        httpURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterBuffer.length()));
        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;

        try {
            outputStream = httpURLConnection.getOutputStream();
            outputStreamWriter = new OutputStreamWriter(outputStream);
            outputStreamWriter.write(parameterBuffer.toString());
            outputStreamWriter.flush();
            if(httpURLConnection.getResponseCode() >= 300) {
                throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
            }

            inputStream = httpURLConnection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            reader = new BufferedReader(inputStreamReader);

            while((tempLine = reader.readLine()) != null) {
                resultBuffer.append(tempLine);
            }
        } finally {
            if(outputStreamWriter != null) {
                outputStreamWriter.close();
            }

            if(outputStream != null) {
                outputStream.close();
            }

            if(reader != null) {
                reader.close();
            }

            if(inputStreamReader != null) {
                inputStreamReader.close();
            }

            if(inputStream != null) {
                inputStream.close();
            }

        }

        return resultBuffer.toString();
    }

    private URLConnection openConnection(URL localURL) throws IOException {
        URLConnection connection;
        if(this.proxyHost != null && this.proxyPort != null) {
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.proxyHost, this.proxyPort.intValue()));
            connection = localURL.openConnection(proxy);
        } else {
            connection = localURL.openConnection();
        }

        return connection;
    }

    private void renderRequest(URLConnection connection) {
        if(this.connectTimeout != null) {
            connection.setConnectTimeout(this.connectTimeout.intValue());
        }

        if(this.socketTimeout != null) {
            connection.setReadTimeout(this.socketTimeout.intValue());
        }

    }

    public Integer getConnectTimeout() {
        return this.connectTimeout;
    }

    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public Integer getSocketTimeout() {
        return this.socketTimeout;
    }

    public void setSocketTimeout(Integer socketTimeout) {
        this.socketTimeout = socketTimeout;
    }

    public String getProxyHost() {
        return this.proxyHost;
    }

    public void setProxyHost(String proxyHost) {
        this.proxyHost = proxyHost;
    }

    public Integer getProxyPort() {
        return this.proxyPort;
    }

    public void setProxyPort(Integer proxyPort) {
        this.proxyPort = proxyPort;
    }

    public String getCharset() {
        return this.charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }
}

AES解密工具类

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class AES {
    public static boolean initialized = false;

    /**
     * AES解密
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }


}

这部分是解密以及存数据库的部分,肯在页面传值,确定要协调多少天数据

@ApiOperation(value = "获取微信运动步数,并存储到数据库,只校对最近三天的")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "encryptedData", value = "加密数据", required = true, dataType = "string"),
            @ApiImplicitParam(name = "iv", value = "加密方式", required = true, dataType = "string"),
            @ApiImplicitParam(name = "sessionKey", value = "微信用code换的钥匙", required = true, dataType = "string"),
            @ApiImplicitParam(name = "token", value = "用户token", required = true, dataType = "string"),
            @ApiImplicitParam(name = "days", value = "需要协调的天数", required = true, dataType = "int")
    })
    @RequestMapping("/decrypt")
    public String decrypt(String encryptedData, String iv, String sessionKey, String token,Integer days) throws Exception{
        Map map = new HashMap();
        try {
            byte[] resultByte  = AES.decrypt(Base64.decodeBase64(encryptedData),
                    Base64.decodeBase64(sessionKey),
                    Base64.decodeBase64(iv));
            if(null != resultByte && resultByte.length > 0){
                String userInfo = new String(resultByte, "UTF-8");
                map.put("status", "1");
                map.put("msg", "解密成功");
                map.put("userInfo", userInfo);
                //获取当前调接口用户的信息
                List<TMemberBase> user=null;
                if(token!=null) {
                    user = ms.findAllByToken(token);
                }else{
                    map.put("errormsg","token不能为空");
                }
                //将微信运动的数据,转换为list
                JSONObject userinfo = JSONObject.fromObject(userInfo);
                String stepInfoList = userinfo.getString("stepInfoList");
                Gson gson = new Gson();
                List<WxStep> list = gson.fromJson(stepInfoList, new TypeToken<List<WxStep>>() {}.getType());
                int size=list.size();
                for (int i = 0; i < days; i++) {
                    //判断最近三天的数据,有没有存储过,有就只改变步数,没就存储
                    List<TWalk> walk = ws.findAllByMemberIdAndRecordDate(user.get(0).getMemberId(), DateKit.converIntToYYYYMMDD(list.get(size-i-1).getTimestamp()));
                    System.out.println("shuzu---"+walk);
                    int size1= walk.size();
                    if(size1>0&&walk!=null) {
                        TWalk tWalk = walk.get(0);
                        tWalk.setStepNum(list.get(size - i - 1).getStep());
                        ws.save(tWalk);
                    }else{
                        TWalk tWalk1 = new TWalk();
                        tWalk1.setMemberId(user.get(0).getMemberId());
                        tWalk1.setMemberName(user.get(0).getMemberName());
                        tWalk1.setOrgId(user.get(0).getOrgId());
                        tWalk1.setOrgName(user.get(0).getOrgName());
                        tWalk1.setRecordTime(list.get(size - i - 1).getTimestamp());
                        tWalk1.setRecordDate(DateKit.converIntToYYYYMMDD(list.get(size - i - 1).getTimestamp()));
                        tWalk1.setStepNum(list.get(size - i - 1).getStep());
                        ws.save(tWalk1);
                    }
                }
            }else{
                map.put("status", "0");
                map.put("msg", "解密失败");
            }
        }catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Gson gson = new Gson();
        String decodeJSON = gson.toJson(map);
        return decodeJSON;
    }


微信运动获取来的json串


这就算完成了,只需要把返回结果,放进data,然后页面调用就行,我把整体代码再贴一遍,免的你们看着乱

完整代码

在data中,加上 runData:{}即可

var that = this;
    wx.login({
      success: function(res) {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        //if (res.code) {
          wx.request({
            url: 'https://你的服务器地址/onlogin',          //本地调试,是获取不到code的,所以要实现,还是得传服务
            data: {
              "code": res.code
            },
            header: {
              'content-type': 'application/json' // 默认值
            },
            success: function (res) {
              console.log(res.data)
              console.log("sessionkey--" + res.data.session_key)
              //2、调用小程序API: wx.getWeRunData获取微信运动数据(加密的);
              wx.getWeRunData({
                success(resRun) {
                  const encryptedData = resRun
                  console.info(resRun);
                  //3、解密步骤2的数据;
                  wx.request({
                    url: 'https://你的服务器地址/decrypt',         //记得更改
                    data: {
                      encryptedData: resRun.encryptedData,
                      iv: resRun.iv,
                      sessionKey: res.data.session_key,
                      token:'用户token,如果你只是小程序开发,传openid即:res.data.openid',days: 3      //传要协调的天数
                    },
                    method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
                    // header: {}, // 设置请求的 header
                    success: function (resDecrypt) {
                      var runData = JSON.parse(resDecrypt.data.userInfo)
                      console.info(runData);
                      if (runData.stepInfoList) {
                        runData.stepInfoList = runData.stepInfoList.reverse()
                        for (var i in runData.stepInfoList) {
                          //给数据加上时间,格式呢,在你的util.js下面写,建微信小程序项目的时候就有,import进来就行,不要也可以
                          runData.stepInfoList[i].date = util.formatTime(new Date(runData.stepInfoList[i].timestamp * 1000))
                        }
                        that.setData({
                           runData: runData.stepInfoList 
                        });
                      }
                    }
                  });
                }
              })
            }
          })
        //} else {
        //  console.log('获取用户登录态失败!' + res.errMsg)
        //}
      }                        
    })

页面显示部分(我只取了当天数据,所以下标是0,如果要显示30天数据,用wx:for-items={{runData}}


后台代码,上面都有,只需要把我的存储步数的类,换成你的即可  (TWalk)数据存储和查询部分,根据自己情况即可,第一次在这上面发,写的不好,大家见谅,有问题可以互动的哦,希望能帮到大家,方法上面那些@Api什么的,都是swagger的注解,前后端分离时候,为前后知道接口作用和要传的参数用的



评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值