HttpClient實現API接口

 項目需要做了一個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;

    }
}

 

參考網址: 基於apache httpclient的常用接口調用方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章