項目需要做了一個http的接口,POST請求,返回接口數據,JSON 格式參考了許多網上例子,寫了一個實現。
接口需要頭信息,加密簽名串。
X-Signature(簽名串) = Lowercase(Binary2HEX(HMAC-SHA256(APPKEY
, Sign
)))
- Binary2HEX 將二進制轉換爲 HEX
- HMAC-SHA256 使用 HMAC 算法簽名, 摘要算法爲 sha256
- Lowercase 將字符串轉換爲小寫
遇到的坑,項目的編碼格式是GBK,但是接口統一的編碼格式爲UTF-8,加密簽名串的時候,導致簽名失敗。源碼如下:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import net.sf.json.JSONObject;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HttpClientUtil {
static MessageDigest md;
private static String AppID ="******************";
private static String AppKey ="*************************";
private static String Accept="application/******.v1+json";
private static String url="http://host:port/quoteApi";
private static String currentTime = Long.toString(new Date().getTime()/1000);
private static String httpBody =makeParams();//MD5(HTTP body)
private static String StringToSign = currentTime + AppKey + Accept + url + getMD5(httpBody) + AppID;
private static String XYobeeSignature =sha256_HMAC(StringToSign,AppKey);
public static String getHttpBody(){
Map<String, String> params =setParams();
JSONObject jsonObject=JSONObject.fromObject(params);
String jsonStr=jsonObject.toString();
System.out.println(jsonStr);
return jsonStr;
}
public static String getMD5(String mm){
String md5 = "";
if (mm != null) {
try {
if (md == null) {
md = MessageDigest.getInstance("MD5");
}
byte[] results = md.digest(mm.getBytes("utf-8"));
md5 = byteArrayToHexString(results);
return md5.toLowerCase();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return md5;
}
private static String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b!=null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1)
hs.append('0');
hs.append(stmp);
}
return hs.toString().toLowerCase();
}
private static String sha256_HMAC(String message, String secret) {
String hash = "";
try {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] bytes = sha256_HMAC.doFinal(message.getBytes());
hash = byteArrayToHexString(bytes);
} catch (Exception e) {
System.out.println("Error HmacSHA256 ===========" + e.getMessage());
}
return hash;
}
public static JSONObject postJsonData(String url,String postStr) {
CloseableHttpClient httpclient = HttpClientUtil.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", Accept);
httpPost.addHeader("Authorization", "appid "+AppID);
httpPost.addHeader("X-Timestamp", currentTime);
httpPost.addHeader("X-Signature", XYobeeSignature);
httpPost.addHeader("Content-type","application/json; charset=utf-8");
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(1*60*1000)
// .setConnectionRequestTimeout(1000)
.setSocketTimeout(3*60*1000).build();
httpPost.setConfig(requestConfig);
CloseableHttpResponse response=null;
try {
httpPost.setEntity(new StringEntity(postStr, Charset.forName("UTF-8")));
response = httpclient.execute(httpPost);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
JSONObject jsonObject=null;
if(response != null){
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity httpEntity = response.getEntity();
String result=null;
try {
result = EntityUtils.toString(httpEntity);
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
jsonObject = JSONObject.fromObject(result);
}
}
return jsonObject;
}
public static CloseableHttpClient createDefault() {
return HttpClientBuilder.create().build();
}
public static void main(String[] arg) {
// getHttpBody();
//postJsonData(url,makeParams()).toString();
System.out.println(postJsonData(url,makeParams()).toString());
}
private static Map<String,String> setParams() {
Map<String,String> params = new HashMap<String,String>();
// params.put("a1","LVSHFCAC5JH375979");
params.put("a2","val1");
// params.put("a3","val2");
// params.put("a4","val3");
params.put("a5","val4");
// params.put("a6","vall5");
params.put("a7","val6");
return params;
}
public static String makeParams(){
Bean vo=new Bean();
vo.setA1("val1");
vo.setA2("val2");
vo.setA3("val3");
String s = JSON.toJSONString(vo, SerializerFeature.PrettyFormat);
return replaceBlank(s);
}
public static String replaceBlank(String str) {
String dest = "";
if (str != null) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
}