开发者社区 问答 正文

API 签名机制(Java示例代码1)


Java 示例代码

[font=PingFangSC, "]本示例不需要依赖第三方的库包,可以直接使用。签名步骤如下所示。


  1. 构造规范化的请求字符串(排序及 URL 编码)。

public static Map<String, String> splitQueryString(String url)
         throws URISyntaxException, UnsupportedEncodingException {
     URI uri = new URI(url);
     String query = uri.getQuery();
     final String[] pairs = query.split("&");
     TreeMap<String, String> queryMap = new TreeMap<String, String>();
     for (String pair : pairs) {
         final int idx = pair.indexOf("=");
         final String key = idx > 0 ? pair.substring(0, idx) : pair;
         if (!queryMap.containsKey(key)) {
             queryMap.put(key, URLDecoder.decode(pair.substring(idx + 1),
                     CHARSET_UTF8));
         }
     }
     return queryMap;
}
/** 对参数名称和参数值进行URL编码**/
public static String generate(String method, Map<String, String> parameter,
                               String accessKeySecret) throws Exception {
     String signString = generateSignString(method, parameter);
     System.out.println("signString---" + signString);
     byte[] signBytes = hmacSHA1Signature(accessKeySecret + "&", signString);
     String signature = newStringByBase64(signBytes);
     System.out.println("signature---" + signature);
     if ("POST".equals(method))
         return signature;
     return URLEncoder.encode(signature, "UTF-8");
}




2.构造成待签名的字符串。 public static String generateSignString(String httpMethod,
                                         Map<String, String> parameter) throws IOException {
     TreeMap<String, String> sortParameter = new TreeMap<String, String>();
     sortParameter.putAll(parameter);
     String canonicalizedQueryString = UrlUtil.generateQueryString(
             sortParameter, true);
     if (null == httpMethod) {
         throw new RuntimeException("httpMethod can not be empty");
     }
     /** 构造待签名的字符串* */
     StringBuilder stringToSign = new StringBuilder();
     stringToSign.append(httpMethod).append(SEPARATOR);
     stringToSign.append(percentEncode("/")).append(SEPARATOR);
     stringToSign.append(percentEncode(canonicalizedQueryString));
     return stringToSign.toString();
}


3.计算待签名字符串的 HMAC 值。 public static byte[] hmacSHA1Signature(String secret, String baseString)
         throws Exception {
     if (isEmpty(secret)) {
         throw new IOException("secret can not be empty");
     }
     if (isEmpty(baseString)) {
         return null;
     }
     Mac mac = Mac.getInstance("HmacSHA1");
     SecretKeySpec keySpec = new SecretKeySpec(
             secret.getBytes(CHARSET_UTF8), ALGORITHM);
     mac.init(keySpec);
     return mac.doFinal(baseString.getBytes(CHARSET_UTF8));
}
private static boolean isEmpty(String str) {
    return (str == null || str.length() == 0);
}

展开
收起
云栖大讲堂 2017-10-19 15:08:28 3664 分享 版权
阿里云 AI 助理回答

您的Java示例代码似乎是要解析URL中的查询字符串,并将其分割成键值对。下面是一个基于您给出的代码片段的完整Java方法示例,这个方法会将查询字符串分割成一个Map,其中键是参数名,值是参数值。请注意,这里直接使用了Java标准库,并没有依赖任何第三方库,正如您所要求的。

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

public class QueryStringParser {

    public static void main(String[] args) throws URISyntaxException, UnsupportedEncodingException {
        String url = "http://example.com/?key1=value1&key2=value2";
        Map<String, String> queryPairs = splitQueryString(url);
        for (Map.Entry<String, String> entry : queryPairs.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
        }
    }

    /**
     * 分割URL中的查询字符串为键值对的Map。
     *
     * @param url 包含查询字符串的URL
     * @return 查询参数的Map
     * @throws URISyntaxException 如果URL格式不正确
     * @throws UnsupportedEncodingException 如果编码不支持
     */
    public static Map<String, String> splitQueryString(String url) throws URISyntaxException, UnsupportedEncodingException {
        URI uri = new URI(url);
        String query = uri.getQuery();
        if (query == null || query.isEmpty()) {
            return new HashMap<>();
        }
        
        String[] pairs = query.split("&");
        Map<String, String> params = new HashMap<>();
        for (String pair : pairs) {
            int idx = pair.indexOf('=');
            String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
            String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
            params.put(key, value);
        }
        return params;
    }
}

这段代码首先定义了一个QueryStringParser类,其中包含一个splitQueryString静态方法,该方法接收一个包含查询字符串的URL作为输入,然后解析这个查询字符串,将其转换为一个Map对象。此外,还提供了一个main方法来演示如何使用这个函数,通过构造一个包含查询参数的URL并打印出解析后的结果。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: