请求金蝶Api工具类

本文介绍了如何在Java中使用KingdeeApiUtils类处理HTTP请求,包括参数编码、构建请求字符串、生成签名以及验证签名,使用HmacSHA256算法确保请求安全。
摘要由CSDN通过智能技术生成
import com.fasterxml.jackson.core.type.TypeReference;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class KingdeeApiUtils {

	public static String convertReqMap2QueryStr(Map<String,String> map) {
		StringBuilder sbTemp = new StringBuilder();
		int index = 0;
		for (String key : map.keySet()) {
			sbTemp.append(key+"=");
			sbTemp.append(map.get(key));
			if(index != map.size() - 1) {
				sbTemp.append("&");
			}
			index++;
		}
		return sbTemp.toString();
	}

	/**
	 * 签名原文:请求方式字符串 + \n + 接口相对路径字符串 + \n + 请求参数字符串 + \n + 请求头字符串
	 * @return
	 * @throws Exception
	 */
	public static boolean verifySignatures(HttpServletRequest request,String appSecret,String paramContent, String reqUrl) throws Exception {
		String signature = request.getHeader("X-Api-Signature");
		String xApiSignHeaders = request.getHeader("X-Api-SignHeaders");
		String timeStamp = request.getHeader("X-Api-TimeStamp");
		String nonce = request.getHeader("X-Api-Nonce");
		if(StringUtils.isAnyBlank(signature,timeStamp,nonce)) {
			return false;
		}
		String encodeParams = URLEncoder.encode(paramContent,"UTF-8");
		String encodePath = URLEncoder.encode(reqUrl,"UTF-8");
		String rawStr = request.getMethod() + "\n" +
				encodePath + "\n" +
				sortKV(encodeParams)+
				"\n"  +handleSignHeaders(request,xApiSignHeaders) + "\n";
		String encodeStr = hashMAC(rawStr,appSecret);
		return signature.equals(encodeStr);
	}

	public static String buildSignatures(String appSecret,String method,TreeMap<String, String> params, String path,Map<String, String> headerMap) throws Exception {
		String paramContent = HttpUtils.buildQuery(params,"UTF-8");
		String encodePath = URLEncoder.encode(path,"UTF-8");
		String rawStr = method + "\n" +
				encodePath + "\n" +
				sortKV(paramContent)+
				"\n"  + handleSignHeaders(headerMap) + "\n";
		return hashMAC(rawStr,appSecret);
	}

	public static String hashMAC(String data,String secret) {
		try {
			Mac kdmac = Mac.getInstance("HmacSHA256");
			SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
			kdmac.init(secret_key);
			byte[] rawHmac = kdmac.doFinal(data.getBytes());
			return Base64.encodeBase64String(bytesToHex(rawHmac).getBytes());
		}catch(Exception e) {
			return null;
		}
	}
	public static String bytesToHex(byte[] hashInBytes) {
		int len = hashInBytes.length;
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			String hex = Integer.toHexString(hashInBytes[i] & 0xFF);
			if(hex.length() < 2){
				hex = "0" + hex;
			}
			sb.append(hex);
		}
		return sb.toString();
	}

	public static String handleSignHeaders(Map<String, String> headerMap) {
		String xApiSignHeaders = headerMap.get("X-Api-SignHeaders");
		String[] headerNames = xApiSignHeaders.split(",");
		Arrays.sort(headerNames);
		StringBuilder sbTemp = new StringBuilder();
		int index = 0;
		for (String headerName : headerNames) {
			String header = headerMap.get(headerName);
			if(StringUtils.isBlank(header)) {
				return null;
			}
			sbTemp.append(headerName.toLowerCase());
			sbTemp.append(":");
			sbTemp.append(header);
			if(index != headerNames.length -1) {
				sbTemp.append("\n");
			}
			index++;
		}
		return sbTemp.toString();
	}

	public static String handleSignHeaders(HttpServletRequest request,String xApiSignHeaders) {
		String[] headerNames = xApiSignHeaders.split(",");
		Arrays.sort(headerNames);
		StringBuilder sbTemp = new StringBuilder();
		int index = 0;
		for (String headerName : headerNames) {
			String header = request.getHeader(headerName);
			if(StringUtils.isBlank(header)) {
				return null;
			}
			sbTemp.append(headerName.toLowerCase());
			sbTemp.append(":");
			if(index != headerNames.length -1) {
				sbTemp.append("\n");
			}
			index++;
		}
		return sbTemp.toString();
	}

	/**
	 * 对键值对进行排序
	 * @param oriStr
	 * @return
	 */
	public static String sortKV(String oriStr) {
		StringBuilder sbTemp = new StringBuilder();
		String[] strings = oriStr.split("&");
		Arrays.sort(strings);
		for (int i = 0 ; i < strings.length ; i++) {
			sbTemp.append(strings[i]);
			if(i != strings.length - 1) {
				sbTemp.append("&");
			}
		}
		return sbTemp.toString();
	}

//	public static String sign(String secret, String data) throws Exception {
//		Mac mac = Mac.getInstance("HmacSHA256");
//		SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
//		mac.init(secretKey);
//		return byte2Hex(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
//	}

	/**
	 * 将byte转为16进制
	 *
	 * @param bytes
	 * @return
	 */
	public static String byte2Hex(byte[] bytes) {
		StringBuffer stringBuffer = new StringBuffer();
		String temp = null;
		for (int i = 0; i < bytes.length; i++) {
			temp = Integer.toHexString(bytes[i] & 0xFF);
			if (temp.length() == 1) {
				//1得到一位的进行补0操作
				stringBuffer.append("0");
			}
			stringBuffer.append(temp);
		}
		return stringBuffer.toString();
	}

	public static Map<String,String> getRequestMap(String requestBody) throws IOException {
		Map<String, String> stringMap = null;
		stringMap = JsonUtils.parseObject(requestBody, new TypeReference<Map<String,String>>(){});
		return stringMap;
	}

	public static String getBody(HttpServletRequest request) {
		try (InputStream is = request.getInputStream()) {
			return IOUtils.toString(is, StandardCharsets.UTF_8);
		} catch (IOException ex) {
			throw new BaseException("read http request body failed.", ex);
		}
	}

	/**
	 *
	 * @param appSecert 应用密钥
	 * @param clientId 应用ID
	 * @param host api host
	 * @param path 请求相对路径
	 * @param params 请求参数
	 * @return
	 */
	public static KingdeeApiResult doGet(String appSecert, String clientId,String host,String path, TreeMap<String, String> params) throws Exception {
		Map<String, String> headerMap = new HashMap<>();
//		headerMap.put("X-Api-Auth-Version","2.0");
//		headerMap.put("X-Api-ClientID",clientId);
//		Long timeStamp = System.currentTimeMillis();
//		Long nonce = Math.abs(new Random().nextLong());
//		headerMap.put("X-Api-TimeStamp",timeStamp+"");
//		headerMap.put("X-Api-Nonce",nonce+"");
//		headerMap.put("X-Api-SignHeaders","X-Api-TimeStamp,X-Api-Nonce");
//		headerMap.put("Content-Type","application/json;charset=UTF-8");
//		for (String key : params.keySet()) {
//			params.put(key,URLEncoder.encode(params.get(key),"UTF-8"));
//		}
//		String signatures = buildSignatures(appSecert,"GET",params,path,headerMap);
//		headerMap.put("X-Api-Signature",signatures);
		params.put("client_id",clientId);
		params.put("client_secret",appSecert);
		String resultStr = HttpUtils.doGet(host + path, params, "UTF-8", headerMap);
		return JsonUtils.parseObject(resultStr,KingdeeApiResult.class);
	}
}
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值