diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java
new file mode 100644
index 00000000..9ea33b12
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java
@@ -0,0 +1,40 @@
+package me.chanjar.weixin.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Hex;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ *
+ * 签名工具类
+ * Created by BinaryWang on 2018/7/11.
+ *
+ *
+ * @author Binary Wang
+ */
+@Slf4j
+public class SignUtils {
+ /**
+ * HmacSHA256 签名算法
+ *
+ * @param message 签名数据
+ * @param key 签名密钥
+ */
+ public static String createHmacSha256Sign(String message, String key) {
+ try {
+ Mac sha256 = Mac.getInstance("HmacSHA256");
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");
+ sha256.init(secretKeySpec);
+ byte[] bytes = sha256.doFinal(message.getBytes());
+ return Hex.encodeHexString(bytes).toUpperCase();
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ SignUtils.log.error(e.getMessage(), e);
+ }
+
+ return null;
+ }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java
index 8c567218..a4abdc04 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java
@@ -5,6 +5,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import me.chanjar.weixin.common.error.WxErrorException;
+import java.util.Map;
+
/**
* 用户信息相关操作接口.
*
@@ -28,6 +30,16 @@ public interface WxMaUserService {
*/
WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String ivStr);
+ /**
+ * 上报用户数据后台接口.
+ * 小游戏可以通过本接口上报key-value数据到用户的CloudStorage。
+ * 文档参考https://developers.weixin.qq.com/minigame/dev/document/open-api/data/setUserStorage.html
+ * @param kvMap 要上报的数据
+ * @param sessionKey 通过wx.login 获得的登录态
+ * @param openid
+ */
+ void setUserStorage(Map kvMap, String sessionKey, String openid) throws WxErrorException;
+
/**
* 解密用户手机号信息.
*
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java
index f1bac75e..f8177bf1 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java
@@ -1,14 +1,25 @@
package cn.binarywang.wx.miniapp.api.impl;
-import org.apache.commons.codec.digest.DigestUtils;
-
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.SignUtils;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.DigestUtils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
/**
* @author Binary Wang
@@ -30,6 +41,30 @@ public class WxMaUserServiceImpl implements WxMaUserService {
return WxMaUserInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr));
}
+ @Override
+ public void setUserStorage(Map kvMap, String sessionKey, String openid) throws WxErrorException {
+ final WxMaConfig config = this.service.getWxMaConfig();
+ JsonObject param = new JsonObject();
+ JsonArray array = new JsonArray();
+ for (Map.Entry e : kvMap.entrySet()) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("key", e.getKey());
+ jsonObject.addProperty("value", e.getValue());
+ array.add(jsonObject);
+ }
+ param.add("kv_list", array);
+ String params = param.toString();
+ String signature = SignUtils.createHmacSha256Sign(params, sessionKey);
+ String url = String.format("https://api.weixin.qq.com/wxa/set_user_storage" +
+ "?appid=%s&signature=%s&openid=%s&sig_method=%s",
+ config.getAppid(), signature, openid, "hmac_sha256");
+ String result = this.service.post(url, params);
+ WxError error = WxError.fromJson(result);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ }
+
@Override
public WxMaPhoneNumberInfo getPhoneNoInfo(String sessionKey, String encryptedData, String ivStr) {
return WxMaPhoneNumberInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr));
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java
index 33e39a6b..2c478e8f 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java
@@ -1,5 +1,9 @@
package cn.binarywang.wx.miniapp.api.impl;
+import cn.binarywang.wx.miniapp.test.TestConfig;
+import com.google.common.collect.ImmutableMap;
+import jdk.nashorn.internal.ir.annotations.Immutable;
+import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.*;
import cn.binarywang.wx.miniapp.api.WxMaService;
@@ -8,6 +12,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.test.ApiTestModule;
import com.google.inject.Inject;
+import javax.management.ImmutableDescriptor;
+
import static org.testng.Assert.*;
/**
@@ -54,4 +60,17 @@ public class WxMaUserServiceImplTest {
assertNotNull(phoneNoInfo);
System.out.println(phoneNoInfo.toString());
}
+
+ @Test
+ public void testGetSessionInfo() {
+ }
+
+ /**
+ * TODO 测试数据有问题,需要替换为正确的数据
+ */
+ @Test
+ public void testSetUserStorage() throws WxErrorException {
+ this.wxService.getUserService().setUserStorage(ImmutableMap.of("1","2"),
+ "r7BXXKkLb8qrSNn05n0qiA",((TestConfig)this.wxService.getWxMaConfig()).getOpenid());
+ }
}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
index 10aedfe3..eda47de3 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
@@ -6,19 +6,12 @@ import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.thoughtworks.xstream.annotations.XStreamAlias;
-import me.chanjar.weixin.common.util.BeanUtils;
-import org.apache.commons.codec.binary.Hex;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
@@ -29,9 +22,8 @@ import java.util.*;
*
* @author binarywang(Binary Wang)
*/
+@Slf4j
public class SignUtils {
- private static final Logger log = LoggerFactory.getLogger(SignUtils.class);
-
/**
* 请参考并使用 {@link #createSign(Object, String, String, boolean)}.
*/
@@ -91,26 +83,12 @@ public class SignUtils {
toSign.append("key=").append(signKey);
if (SignType.HMAC_SHA256.equals(signType)) {
- return createHmacSha256Sign(toSign.toString(), signKey);
+ return me.chanjar.weixin.common.util.SignUtils.createHmacSha256Sign(toSign.toString(), signKey);
} else {
return DigestUtils.md5Hex(toSign.toString()).toUpperCase();
}
}
- private static String createHmacSha256Sign(String message, String key) {
- try {
- Mac sha256 = Mac.getInstance("HmacSHA256");
- SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");
- sha256.init(secretKeySpec);
- byte[] bytes = sha256.doFinal(message.getBytes());
- return Hex.encodeHexString(bytes).toUpperCase();
- } catch (NoSuchAlgorithmException | InvalidKeyException e) {
- log.error(e.getMessage(), e);
- }
-
- return null;
- }
-
/**
* 校验签名是否正确.
*
@@ -146,11 +124,11 @@ public class SignUtils {
Map result = Maps.newHashMap();
List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields()));
fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields()));
- if(bean.getClass().getSuperclass().getSuperclass() == BaseWxPayRequest.class){
+ if (bean.getClass().getSuperclass().getSuperclass() == BaseWxPayRequest.class) {
fields.addAll(Arrays.asList(BaseWxPayRequest.class.getDeclaredFields()));
}
- if(bean.getClass().getSuperclass().getSuperclass() == BaseWxPayResult.class){
+ if (bean.getClass().getSuperclass().getSuperclass() == BaseWxPayResult.class) {
fields.addAll(Arrays.asList(BaseWxPayResult.class.getDeclaredFields()));
}