package net.yyc.common.ding.entity; import io.micrometer.core.instrument.util.StringUtils; import org.apache.commons.io.IOUtils; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; public class Test { public static void main(String[] args) throws Exception { /** * 参数列表 */ String bodyStr = "{\n" + " \"freelances\": [\n" + " {\n" + " \"mobile\": \"15000998877\",\n" + " \"name\": \"张三\",\n" + " \"idType\": \"1\",\n" + " \"idCard\": \"350198765623418765\"\n" + " }\n" + " ]\n" + "}"; String serviceSign = serviceSign("/oapi/v1/employ/freelances/check", "POST", new HashMap<>(), bodyStr.getBytes()); System.out.println("serviceSign=========" + serviceSign); // 创建一个post对象 String url = "https://test-f.renlijia.com/oapi/v1/employ/freelances/check"; HttpPost post = new HttpPost(url); StringEntity s = new StringEntity(bodyStr, "UTF-8"); // 中文乱码在此解决 s.setContentType("application/json"); post.setEntity(s); post.setHeader("app-id","888999"); post.setHeader("signature",serviceSign); // 执行post请求 CloseableHttpResponse response = HttpClients.createDefault().execute(post); // String json = HttpClientUtils.doPost("https://test-f.renlijia.com", params); String result = fromStream(response.getEntity().getContent(), "UTF-8"); System.out.println("result-----" + result); System.out.println("response=========" + response.getStatusLine().getStatusCode()); System.out.println("response=========" + response.getEntity().getContent().toString()); } private static String fromStream(InputStream is, String charset) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer buffer = new StringBuffer(); String line = ""; while ((line = in.readLine()) != null) { buffer.append(line); } return new String(buffer.toString().getBytes("UTF-8"), charset); } /** * 签名算法HmacSha256 */ public static final String HMAC_SHA256 = "HmacSHA256"; /** * 编码 */ public static final String ENCODING = "UTF-8"; /** * 换⾏符 */ private static char LF = '\n'; private static final String HTTP_METHOD_POST = "post"; private static final String HTTP_METHOD_PUT = "put"; /** * 26 * 获取请求签名 * 27 * * 28 * @param uri 原始HTTP请求PATH(例:/oapi/v1/employ/free * lances/check) * 29 * @param httpMethod 原始HTTP请求⽅法(例:POST)5 * 30 * @param paramsMap 原始HTTP请求所有Query+Form参数(POST请求:Ma * ps.newHashMap()) * 31 * @param body 原始HTTP请求Body体(仅当请求为POST/PUT且⾮表 * 单请求才需要设置此属性,表单形式的需要将参数放到paramsMap中) * 32 * @param appId ⽤户id * 33 * @return 签名结果 * 34 * @throws Exception * 35 */ public static String serviceSign(String uri, String httpMethod, Map paramsMap, byte[] body) throws Exception { String bodyMd5 = buildBodyMd5(httpMethod, body); String resourceToSign = buildResource(uri, paramsMap); String stringToSign = buildStringToSign(resourceToSign, httpMethod, bodyMd5); Mac hmacSha256 = Mac.getInstance(HMAC_SHA256); String appSecret = "5T8134269D467IGa0ZC7s907666r2C43"; byte[] keyBytes = appSecret.getBytes(ENCODING); hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes. length, HMAC_SHA256)); return new String(Base64.encodeBase64(hmacSha256.doFinal (stringToSign.getBytes(ENCODING))), ENCODING); } public static String buildBodyMd5(String httpMethod, byte[] body) throws IOException { if (body == null) { return null; } if (!httpMethod.equalsIgnoreCase(HTTP_METHOD_POST) && !httpMethod.equalsIgnoreCase(HTTP_METHOD_PUT)){ return null; } InputStream inputStream = new ByteArrayInputStream(body); byte[] bodyBytes = IOUtils.toByteArray(inputStream); if (bodyBytes != null && bodyBytes.length > 0) { return base64AndMD5(bodyBytes).trim(); } return null; } public static String base64AndMD5(byte[] bytes) { try { final MessageDigest md = MessageDigest.getInstance( "MD5"); md.reset(); md.update(bytes); final Base64 base64 = new Base64(); return new String(base64.encode(md.digest())); } catch (final NoSuchAlgorithmException e) { throw new IllegalArgumentException("unknown algorith m MD5"); } } public static String buildResource(String uri, Map paramsMap) { StringBuilder builder = new StringBuilder(); builder.append(uri); TreeMap sortMap = new TreeMap<>(); sortMap.putAll(paramsMap); if (sortMap.size() > 0) { builder.append('?'); builder.append(buildMapToSign(sortMap)); } return builder.toString(); } public static String buildStringToSign(String resourceToSign, String method, String bodyMd5) { StringBuilder sb = new StringBuilder(); sb.append(method).append(LF); if (StringUtils.isNotBlank(bodyMd5)) { sb.append(bodyMd5); } sb.append(LF); sb.append(resourceToSign); return sb.toString(); } /** * 将Map转换为用&及=拼接的字符串 */ public static String buildMapToSign(Map paramMap) { StringBuilder builder = new StringBuilder(); for (Map.Entry e : paramMap.entrySet()) { if (builder.length() > 0) { builder.append('&'); } String key = e.getKey(); Object value = e.getValue(); if (value != null) { if (value instanceof List) { List list = (List) value; if (list.size() == 0) { builder.append(key); } else { builder.append(key).append("=").append(String.valueOf(list.get(0))); } } else if (value instanceof Object[]) { Object[] objs = (Object[]) value; if (objs.length == 0) { builder.append(key); } else { builder.append(key).append("=").append(String.valueOf(objs[0])); } } else { builder.append(key).append("=").append(String.valueOf(value)); } } } return builder.toString(); } public void check() throws IOException { String resourceToSign = "/oapi/v1/employ/freelances/check"; String body ="{\"freelances\":[{\"mobile\":\"15000998877\",\"name\":\"张三\",\"idType\":\"1\",\n" + "\"idCard\":\"350198765623418765\"}]}"; String bodyMd5 = buildBodyMd5(HTTP_METHOD_POST, body.getBytes()); String stringToSign = buildStringToSign(resourceToSign, HTTP_METHOD_POST, bodyMd5); } }