|
@@ -0,0 +1,266 @@
|
|
|
|
|
+package cn.com.ctop.job.adq.data.utils;
|
|
|
|
|
+
|
|
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
|
|
+import org.springframework.http.HttpEntity;
|
|
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
|
|
+import org.springframework.http.MediaType;
|
|
|
|
|
+import org.springframework.http.ResponseEntity;
|
|
|
|
|
+import org.springframework.util.DigestUtils;
|
|
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
|
|
+
|
|
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+
|
|
|
|
|
+import static java.net.URLEncoder.encode;
|
|
|
|
|
+
|
|
|
|
|
+public class Signature {
|
|
|
|
|
+
|
|
|
|
|
+ private String secret = "302424a82b378320e5dc7008a916e2ab";
|
|
|
|
|
+
|
|
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
|
|
+ System.out.println("=====参数是hashmap的签名demo=====");
|
|
|
|
|
+ test_hashmap();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("=====参数为json字符串的签名demo=====");
|
|
|
|
|
+ test_json();
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println("=====请求接口demo=====");
|
|
|
|
|
+ test_request();
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //参数是hashmap的签名demo
|
|
|
|
|
+ public static void test_hashmap() throws Exception {
|
|
|
|
|
+ String secret = "302424a82b378320e5dc7008a916e2ab";
|
|
|
|
|
+
|
|
|
|
|
+ Map<String,Object> param =new HashMap<>();
|
|
|
|
|
+ param.put("param1","aaaa哈哈哈");
|
|
|
|
|
+ param.put("param2","qweqwe");
|
|
|
|
|
+ param.put("param3[0]","1");
|
|
|
|
|
+
|
|
|
|
|
+ long timestamp = 1646899307;
|
|
|
|
|
+
|
|
|
|
|
+ Signature signature = new Signature(secret);
|
|
|
|
|
+ String signStr = signature.buildSignature(timestamp, param);
|
|
|
|
|
+ System.out.println(signStr);
|
|
|
|
|
+ //System.out.println(signature.http_build_query(param));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //参数为json字符串的签名demo
|
|
|
|
|
+ public static void test_json() throws Exception {
|
|
|
|
|
+ String secret = "302424a82b378320e5dc7008a916e2ab";
|
|
|
|
|
+
|
|
|
|
|
+ String jsonStr = "{" +
|
|
|
|
|
+ " \"items\": [" +
|
|
|
|
|
+ " {" +
|
|
|
|
|
+ " \"creative_user_id\": 10064255535," +
|
|
|
|
|
+ " \"designer_id\": 10064255535," +
|
|
|
|
|
+ " \"folder_id\": 12002122805," +
|
|
|
|
|
+ " \"album_id\": 12000018105," +
|
|
|
|
|
+ " \"material_name\": \"牵爱30402一组勤阿喵限制0216成片01.mp4\"," +
|
|
|
|
|
+ " \"file_md5\": \"abf422e18234919979d9c0bff5cde80d\"," +
|
|
|
|
|
+ " \"url\": \"https://chuxin-gz.oss-cn-shenzhen.aliyuncs.com/cxai/2023/02/牵爱30402一组勤阿喵限制0216成片01.mp4\"" +
|
|
|
|
|
+ " }," +
|
|
|
|
|
+ " {" +
|
|
|
|
|
+ " \"album_id\": 12000018105," +
|
|
|
|
|
+ " \"creative_user_id\": 10064255535," +
|
|
|
|
|
+ " \"designer_id\": 10064255535," +
|
|
|
|
|
+ " \"file_md5\": \"a3f445511a5b58ff75cd33d79f29a658\"," +
|
|
|
|
|
+ " \"folder_id\": 12002122805," +
|
|
|
|
|
+ " \"material_name\": \"牵爱30402一组勤阿喵限制0216成片02.mp4\"," +
|
|
|
|
|
+ " \"url\": \"https://chuxin-gz.oss-cn-shenzhen.aliyuncs.com/cxai/2023/02/牵爱30402一组勤阿喵限制0216成片02.mp4\"" +
|
|
|
|
|
+ " }," +
|
|
|
|
|
+ " {" +
|
|
|
|
|
+ " \"album_id\": 12000018105," +
|
|
|
|
|
+ " \"creative_user_id\": 10064255535," +
|
|
|
|
|
+ " \"file_md5\": \"b5a179f0e3b5aae42c4fd69ffb1772b2\"," +
|
|
|
|
|
+ " \"folder_id\": 12002122805," +
|
|
|
|
|
+ " \"designer_id\": 10064255535," +
|
|
|
|
|
+ " \"material_name\": \"牵爱30402一组勤阿喵限制0216成片03.mp4\"," +
|
|
|
|
|
+ " \"url\": \"https://chuxin-gz.oss-cn-shenzhen.aliyuncs.com/cxai/2023/02/牵爱30402一组勤阿喵限制0216成片03.mp4\"" +
|
|
|
|
|
+ " }" +
|
|
|
|
|
+ " ]" +
|
|
|
|
|
+ "}";
|
|
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
+ Map<String, Object> param = objectMapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});
|
|
|
|
|
+
|
|
|
|
|
+ long timestamp = 1676616009;
|
|
|
|
|
+
|
|
|
|
|
+ Signature signature = new Signature(secret);
|
|
|
|
|
+ String signStr = signature.buildSignature(timestamp, param);
|
|
|
|
|
+ System.out.println(signStr);
|
|
|
|
|
+ //System.out.println(signature.http_build_query(param));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //请求接口demo
|
|
|
|
|
+ public static void test_request() throws Exception {
|
|
|
|
|
+ String url = "https://openapi2.mobgi.com/api/AdMaterial/report";
|
|
|
|
|
+
|
|
|
|
|
+ String secret = "302424a82b378320e5dc7008a916e2ab";
|
|
|
|
|
+ String email = "yuyang2@hrcentury.cn";
|
|
|
|
|
+ long timestamp = System.currentTimeMillis()/1000;
|
|
|
|
|
+
|
|
|
|
|
+ //请求参数
|
|
|
|
|
+ String jsonStr = " {\n" +
|
|
|
|
|
+ " \"media_type\": \"toutiao_upgrade\",\n" +
|
|
|
|
|
+ " \"page\": \"1\",\n" +
|
|
|
|
|
+ " \"page_size\": \"1\",\n" +
|
|
|
|
|
+ " \"start_date\": \"2024-05-22\",\n" +
|
|
|
|
|
+ " \"end_date\": \"2024-05-22\",\n" +
|
|
|
|
|
+ " \"time_dim\": \"days\",\n" +
|
|
|
|
|
+ " \"kpis\": [\"stat_cost\"]\n" +
|
|
|
|
|
+ "}";
|
|
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
+ Map<String, Object> params = objectMapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});
|
|
|
|
|
+
|
|
|
|
|
+ //获得到签名
|
|
|
|
|
+ Signature signature = new Signature(secret);
|
|
|
|
|
+ String signStr = signature.buildSignature(timestamp, params);
|
|
|
|
|
+
|
|
|
|
|
+ //设置header
|
|
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
|
|
+ headers.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
|
|
|
|
|
+ headers.add("email",email);
|
|
|
|
|
+ headers.add("timestamp",String.valueOf(timestamp));
|
|
|
|
|
+ headers.add("signature",signStr);
|
|
|
|
|
+
|
|
|
|
|
+ System.out.println(params);
|
|
|
|
|
+ System.out.println("===============");
|
|
|
|
|
+ System.out.println(headers);
|
|
|
|
|
+
|
|
|
|
|
+ //接口请求
|
|
|
|
|
+ HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);
|
|
|
|
|
+ RestTemplate restTemplate = new RestTemplate();
|
|
|
|
|
+ ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class);
|
|
|
|
|
+
|
|
|
|
|
+ //获得响应
|
|
|
|
|
+ String body = responseEntity.getBody();
|
|
|
|
|
+ System.out.println(unicodeToString(body));
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public Signature(String secret) {
|
|
|
|
|
+ this.secret = secret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param timestamp 时间戳
|
|
|
|
|
+ * @param params 参数
|
|
|
|
|
+ * @return 返回签名字符串
|
|
|
|
|
+ * @throws Exception
|
|
|
|
|
+ */
|
|
|
|
|
+ public String buildSignature(long timestamp, Map<String,Object> params) throws Exception {
|
|
|
|
|
+ //加入时间戳
|
|
|
|
|
+ params.put("timestamp", timestamp);
|
|
|
|
|
+ //生成url参数字符串
|
|
|
|
|
+ String signatureStr = http_build_query(params, true);
|
|
|
|
|
+ //将密钥拼接在后面
|
|
|
|
|
+ signatureStr += "&cl_secret="+secret;
|
|
|
|
|
+
|
|
|
|
|
+ //MD5
|
|
|
|
|
+ return getMD5(signatureStr);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param params 参数
|
|
|
|
|
+ * @return 返回php http_build_query()效果的URL-encode的字符串
|
|
|
|
|
+ * @throws Exception
|
|
|
|
|
+ */
|
|
|
|
|
+ public String http_build_query(Map<String,Object> params) throws Exception {
|
|
|
|
|
+ return http_build_query(params, true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String getMD5(String str) throws NoSuchAlgorithmException {
|
|
|
|
|
+ DigestUtils.md5DigestAsHex(str.getBytes());
|
|
|
|
|
+ String MD5 = DigestUtils.md5DigestAsHex(str.getBytes());
|
|
|
|
|
+ return MD5.toUpperCase();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Java实现PHP中的http_build_query()效果
|
|
|
|
|
+ * https://www.cnblogs.com/timseng/p/13280722.html
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private String http_build_query(Map<String, Object> array, boolean sort) throws Exception {
|
|
|
|
|
+ String reString = "";
|
|
|
|
|
+ //遍历数组形成akey=avalue&bkey=bvalue&ckey=cvalue形式的的字符串
|
|
|
|
|
+ reString = rescBuild(array, "", true, sort);
|
|
|
|
|
+ reString = StringUtils.removeEnd(reString, "&");
|
|
|
|
|
+
|
|
|
|
|
+ //将得到的字符串进行处理得到目标格式的字符串:utf8处理中文出错
|
|
|
|
|
+ ///reString = java.net.URLEncoder.encode(reString, "utf-8");
|
|
|
|
|
+ ///reString = reString.replace("%3D", "=").replace("%26", "&");
|
|
|
|
|
+ return reString;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String rescBuild(Object object, String parentStr, boolean first, boolean sort) throws Exception {
|
|
|
|
|
+ String r = "";
|
|
|
|
|
+ if (object instanceof Map) {
|
|
|
|
|
+
|
|
|
|
|
+ List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(((Map<String, Object>) object).entrySet());
|
|
|
|
|
+
|
|
|
|
|
+ //按照map的key排序
|
|
|
|
|
+ if(sort) {
|
|
|
|
|
+ Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
|
|
|
|
|
+ //升序排序
|
|
|
|
|
+ public int compare(Map.Entry<String, Object> o1,
|
|
|
|
|
+ Map.Entry<String, Object> o2) {
|
|
|
|
|
+ return o1.getKey().compareTo(o2.getKey());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (Map.Entry<String, Object> mapping : list) {
|
|
|
|
|
+ String key = mapping.getKey();
|
|
|
|
|
+ Object value = mapping.getValue();
|
|
|
|
|
+
|
|
|
|
|
+ if (first) {
|
|
|
|
|
+ r += rescBuild(value, key, false, sort);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ r += rescBuild(value, parentStr + "[" + key + "]", false, sort);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else if (object instanceof List) {
|
|
|
|
|
+ for (int i = 0; i < ((List) object).size(); i++) {
|
|
|
|
|
+ r += rescBuild(((List) object).get(i), parentStr + "[" + i + "]", false, sort);
|
|
|
|
|
+ }
|
|
|
|
|
+ //叶节点是String或者Number
|
|
|
|
|
+ } else if (object instanceof String) {
|
|
|
|
|
+ r += encode(parentStr,"utf-8") + "=" + encode(object.toString(),"utf-8") + "&";
|
|
|
|
|
+ } else if (object instanceof Number) {
|
|
|
|
|
+ r += encode(parentStr,"utf-8") + "=" + encode(((Number) object).toString(),"utf-8") + "&";
|
|
|
|
|
+ } else if (object instanceof Boolean) {
|
|
|
|
|
+ r += encode(parentStr,"utf-8") + "=" + encode(((Boolean) object).toString(),"utf-8") + "&";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ throw new Exception("unsupported type:"+object.getClass().toString());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return r;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static String unicodeToString(String unicode) {
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+ int i = 0;
|
|
|
|
|
+ while (i < unicode.length()) {
|
|
|
|
|
+ char c = unicode.charAt(i++);
|
|
|
|
|
+ if (c == '\\' && i < unicode.length() && unicode.charAt(i) == 'u') {
|
|
|
|
|
+ i++; // 跳过 'u'
|
|
|
|
|
+ int code = Integer.parseInt(unicode.substring(i, i + 4), 16);
|
|
|
|
|
+ sb.append((char) code);
|
|
|
|
|
+ i += 4;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ sb.append(c);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return sb.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|