剛剛把支付接口對接完成,原覺得報關是支付寶調用的,後來才發現也要本身掉支付寶的接口.啥也不說了看代碼:html
能夠下載demo,額.鏈接不知道怎麼添加,須要的能夠私信.api
我這裏是用httpclient發送請求的.首先獲取httpclient的實力,工廠類:數組
1 public class HttpProtocolHandler { 2 3 private static String DEFAULT_CHARSET = "GBK"; 4 5 /** 鏈接超時時間,由bean factory設置,缺省爲8秒鐘 */ 6 private int defaultConnectionTimeout = 8000; 7 8 /** 迴應超時時間, 由bean factory設置,缺省爲30秒鐘 */ 9 private int defaultSoTimeout = 30000; 10 11 /** 閒置鏈接超時時間, 由bean factory設置,缺省爲60秒鐘 */ 12 private int defaultIdleConnTimeout = 60000; 13 14 private int defaultMaxConnPerHost = 30; 15 16 private int defaultMaxTotalConn = 80; 17 18 /** 默認等待HttpConnectionManager返回鏈接超時(只有在達到最大鏈接數時起做用):1秒*/ 19 private static final long defaultHttpConnectionManagerTimeout = 3 * 1000; 20 21 /** 22 * HTTP鏈接管理器,該鏈接管理器必須是線程安全的. 23 */ 24 private HttpConnectionManager connectionManager; 25 26 private static HttpProtocolHandler httpProtocolHandler = new HttpProtocolHandler(); 27 28 /** 29 * 工廠方法 30 * 31 * @return 32 */ 33 public static HttpProtocolHandler getInstance() { 34 return httpProtocolHandler; 35 } 36 37 /** 38 * 私有的構造方法 39 */ 40 private HttpProtocolHandler() { 41 // 建立一個線程安全的HTTP鏈接池 42 connectionManager = new MultiThreadedHttpConnectionManager(); 43 connectionManager.getParams().setDefaultMaxConnectionsPerHost(defaultMaxConnPerHost); 44 connectionManager.getParams().setMaxTotalConnections(defaultMaxTotalConn); 45 46 IdleConnectionTimeoutThread ict = new IdleConnectionTimeoutThread(); 47 ict.addConnectionManager(connectionManager); 48 ict.setConnectionTimeout(defaultIdleConnTimeout); 49 50 ict.start(); 51 } 52 53 /** 54 * 執行Http請求 55 * 56 * @param request 請求數據 57 * @param strParaFileName 文件類型的參數名 58 * @param strFilePath 文件路徑 59 * @return 60 * @throws HttpException, IOException 61 */ 62 public HttpResponse execute(HttpRequest request, String strParaFileName, String strFilePath) throws HttpException, IOException { 63 HttpClient httpclient = new HttpClient(connectionManager); 64 65 // 設置鏈接超時 66 int connectionTimeout = defaultConnectionTimeout; 67 if (request.getConnectionTimeout() > 0) { 68 connectionTimeout = request.getConnectionTimeout(); 69 } 70 httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout); 71 72 // 設置迴應超時 73 int soTimeout = defaultSoTimeout; 74 if (request.getTimeout() > 0) { 75 soTimeout = request.getTimeout(); 76 } 77 httpclient.getHttpConnectionManager().getParams().setSoTimeout(soTimeout); 78 79 // 設置等待ConnectionManager釋放connection的時間 80 httpclient.getParams().setConnectionManagerTimeout(defaultHttpConnectionManagerTimeout); 81 82 String charset = request.getCharset(); 83 charset = charset == null ? DEFAULT_CHARSET : charset; 84 HttpMethod method = null; 85 86 //get模式且不帶上傳文件 87 if (request.getMethod().equals(HttpRequest.METHOD_GET)) { 88 method = new GetMethod(request.getUrl()); 89 method.getParams().setCredentialCharset(charset); 90 91 // parseNotifyConfig會保證使用GET方法時,request必定使用QueryString 92 method.setQueryString(request.getQueryString()); 93 } else if(strParaFileName.equals("") && strFilePath.equals("")) { 94 //post模式且不帶上傳文件 95 method = new PostMethod(request.getUrl()); 96 ((PostMethod) method).addParameters(request.getParameters()); 97 method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; text/html; charset=" + charset); 98 } 99 else { 100 //post模式且帶上傳文件 101 method = new PostMethod(request.getUrl()); 102 List<Part> parts = new ArrayList<Part>(); 103 for (int i = 0; i < request.getParameters().length; i++) { 104 parts.add(new StringPart(request.getParameters()[i].getName(), request.getParameters()[i].getValue(), charset)); 105 } 106 //增長文件參數,strParaFileName是參數名,使用本地文件 107 parts.add(new FilePart(strParaFileName, new FilePartSource(new File(strFilePath)))); 108 109 // 設置請求體 110 ((PostMethod) method).setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[0]), new HttpMethodParams())); 111 } 112 113 // 設置Http Header中的User-Agent屬性 114 method.addRequestHeader("User-Agent", "Mozilla/4.0"); 115 HttpResponse response = new HttpResponse(); 116 117 try { 118 httpclient.executeMethod(method); 119 if (request.getResultType().equals(HttpResultType.STRING)) { 120 response.setStringResult(method.getResponseBodyAsString()); 121 } else if (request.getResultType().equals(HttpResultType.BYTES)) { 122 response.setByteResult(method.getResponseBody()); 123 } 124 response.setResponseHeaders(method.getResponseHeaders()); 125 } catch (UnknownHostException ex) { 126 127 return null; 128 } catch (IOException ex) { 129 130 return null; 131 } catch (Exception ex) { 132 133 return null; 134 } finally { 135 method.releaseConnection(); 136 } 137 return response; 138 } 139 140 /** 141 * 將NameValuePairs數組轉變爲字符串 142 * 143 * @param nameValues 144 * @return 145 */ 146 protected String toString(NameValuePair[] nameValues) { 147 if (nameValues == null || nameValues.length == 0) { 148 return "null"; 149 } 150 151 StringBuffer buffer = new StringBuffer(); 152 153 for (int i = 0; i < nameValues.length; i++) { 154 NameValuePair nameValue = nameValues[i]; 155 156 if (i == 0) { 157 buffer.append(nameValue.getName() + "=" + nameValue.getValue()); 158 } else { 159 buffer.append("&" + nameValue.getName() + "=" + nameValue.getValue()); 160 } 161 } 162 163 return buffer.toString(); 164 } 165 }
分別編寫一個請求和相應對象:安全
請求對象app
1 public class HttpRequest { 2 3 /** HTTP GET method */ 4 public static final String METHOD_GET = "GET"; 5 6 /** HTTP POST method */ 7 public static final String METHOD_POST = "POST"; 8 9 /** 10 * 待請求的url 11 */ 12 private String url = null; 13 14 /** 15 * 默認的請求方式 16 */ 17 private String method = METHOD_POST; 18 19 private int timeout = 0; 20 21 private int connectionTimeout = 0; 22 23 /** 24 * Post方式請求時組裝好的參數值對 25 */ 26 private NameValuePair[] parameters = null; 27 28 /** 29 * Get方式請求時對應的參數 30 */ 31 private String queryString = null; 32 33 /** 34 * 默認的請求編碼方式 35 */ 36 private String charset = "GBK"; 37 38 /** 39 * 請求發起方的ip地址 40 */ 41 private String clientIp; 42 43 /** 44 * 請求返回的方式 45 */ 46 private HttpResultType resultType = HttpResultType.BYTES; 47 48 public HttpRequest(HttpResultType resultType) { 49 super(); 50 this.resultType = resultType; 51 } 52 53 /** 54 * @return Returns the clientIp. 55 */ 56 public String getClientIp() { 57 return clientIp; 58 } 59 60 /** 61 * @param clientIp The clientIp to set. 62 */ 63 public void setClientIp(String clientIp) { 64 this.clientIp = clientIp; 65 } 66 67 public NameValuePair[] getParameters() { 68 return parameters; 69 } 70 71 public void setParameters(NameValuePair[] parameters) { 72 this.parameters = parameters; 73 } 74 75 public String getQueryString() { 76 return queryString; 77 } 78 79 public void setQueryString(String queryString) { 80 this.queryString = queryString; 81 } 82 83 public String getUrl() { 84 return url; 85 } 86 87 public void setUrl(String url) { 88 this.url = url; 89 } 90 91 public String getMethod() { 92 return method; 93 } 94 95 public void setMethod(String method) { 96 this.method = method; 97 } 98 99 public int getConnectionTimeout() { 100 return connectionTimeout; 101 } 102 103 public void setConnectionTimeout(int connectionTimeout) { 104 this.connectionTimeout = connectionTimeout; 105 } 106 107 public int getTimeout() { 108 return timeout; 109 } 110 111 public void setTimeout(int timeout) { 112 this.timeout = timeout; 113 } 114 115 /** 116 * @return Returns the charset. 117 */ 118 public String getCharset() { 119 return charset; 120 } 121 122 /** 123 * @param charset The charset to set. 124 */ 125 public void setCharset(String charset) { 126 this.charset = charset; 127 } 128 129 public HttpResultType getResultType() { 130 return resultType; 131 } 132 133 public void setResultType(HttpResultType resultType) { 134 this.resultType = resultType; 135 } 136 137 }
響應對象:post
1 public class HttpResponse { 2 3 /** 4 * 返回中的Header信息 5 */ 6 private Header[] responseHeaders; 7 8 /** 9 * String類型的result 10 */ 11 private String stringResult; 12 13 /** 14 * btye類型的result 15 */ 16 private byte[] byteResult; 17 18 public Header[] getResponseHeaders() { 19 return responseHeaders; 20 } 21 22 public void setResponseHeaders(Header[] responseHeaders) { 23 this.responseHeaders = responseHeaders; 24 } 25 26 public byte[] getByteResult() { 27 if (byteResult != null) { 28 return byteResult; 29 } 30 if (stringResult != null) { 31 return stringResult.getBytes(); 32 } 33 return null; 34 } 35 36 public void setByteResult(byte[] byteResult) { 37 this.byteResult = byteResult; 38 } 39 40 public String getStringResult() throws UnsupportedEncodingException { 41 if (stringResult != null) { 42 return stringResult; 43 } 44 if (byteResult != null) { 45 return new String(byteResult, AlipayConfig.input_charset); 46 } 47 return null; 48 } 49 50 public void setStringResult(String stringResult) { 51 this.stringResult = stringResult; 52 } 53 54 }
分別一個生產url和轉換參數的方法:
拼接參數:測試
1 /** 2 * 拼接請求參數 3 * @param params 4 * @param privateKey 5 * @return 6 */ 7 private static String getContent(Map params, String privateKey) { 8 Map map = params; 9 List keys = new ArrayList(map.keySet()); 10 Collections.sort(keys); 11 12 String prestr = ""; 13 14 for (int i = 0; i < keys.size(); i++) { 15 String key = (String) keys.get(i); 16 String value = (String) map.get(key); 17 18 if (i == keys.size() - 1) { 19 prestr = prestr + key + "=" + value; 20 } else { 21 prestr = prestr + key + "=" + value + "&"; 22 } 23 } 24 // String p = prestr + privateKe+"&forex_biz=\"FP\""; 25 String p = ""; 26 if(StringUtils.isNotBlank(privateKey)){ 27 p = prestr+privateKey; 28 29 } else { 30 p = prestr; 31 } 32 return p; 33 }
生產url:ui
/** * 生成請求url * @param params * @param key * @param paygateway * @param input_charset * @return */ public static String createUrl( Map<String,Object> params ,String key, String paygateway,String input_charset,String sign_type) { String prestr = ""; prestr = prestr + key; //System.out.println("prestr=" + prestr); String sign = DigestUtils.md5Hex(getContent(params, key)); String parameter = ""; parameter = parameter + paygateway; List<Object> keys = new ArrayList<Object>(params.keySet()); for (int i = 0; i < keys.size(); i++) { try { parameter = parameter + keys.get(i) + "=" + URLEncoder.encode((String) params.get(keys.get(i)), input_charset) + "&"; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } parameter = parameter + "sign=" + sign + "&sign_type="+sign_type; return parameter; }
測試:this
1 public static void main(String[] args) { 2 //報關 3 Map<String, Object> params = new HashMap<String, Object>(); 4 //一下的參數參考pdf裏面的必填參數 5 params.put("service", "alipay.acquire.customs"); 6 params.put("partner", AlipayConfig.partner); 7 params.put("_input_charset", AlipayConfig.input_charset); 8 params.put("trade_no", "2016070421001003100000009481");//這個是支付成功後,支付寶返回的支付流水號,若是你在支付的時候沒有保存,那麼就搞大了 9 params.put("out_request_no", StringUtil.timeStamp("BG"));///報關的流水號,用系統時間幾號,方法不貼了 10 // params.put("is_split","T"); 11 // params.put("merchant_customs_code", "hanguo"); 12 params.put("merchant_customs_code", "ZF14021901");//注意,這裏是你商品所在倉庫的備案號,並非支付寶備案號.用支付寶的備案號會致使:申報數據中電商平臺不一致(看我的緣由) 13 params.put("customs_place", "HANGZHOU");//海關編號 14 params.put("merchant_customs_name", "jwyhanguo_card");//商戶海關備案編號名稱 15 params.put("amount","1"); 16 String createUrl = createUrl(params, AlipayConfig.key, "https://openapi.alipaydev.com/gateway.do?", "utf-8",AlipayConfig.sign_type); 17 System.out.println("請求url:"+createUrl); 18 try { 19 HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance(); 20 HttpRequest request = new HttpRequest(HttpResultType.STRING); 21 //設置編碼集 22 request.setCharset(AlipayConfig.input_charset); 23 request.setUrl(createUrl);//支付寶測試環境 24 System.out.println(request.getUrl()); 25 HttpResponse response = httpProtocolHandler.execute(request,"",""); 26 String stringResult = response.getStringResult(); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 } 30 }
返回成功信息--案例:編碼
1 <alipay> 2 <is_success>T</is_success> 3 <request> 4 <param name="sign">0b69f5e1fd796b944c9749e832979ffb</param> 5 <param name="amount">1</param> 6 <param name="merchant_customs_code">hanguo</param> 7 <param name="trade_no">2016052500001000100000599501</param> 8 <param name="_input_charset">utf-8</param> 9 <param name="customs_place">HANGZHOU</param> 10 <param name="sign_type">MD5</param> 11 <param name="service">alipay.acquire.customs</param> 12 <param name="out_request_no">201505252210</param> 13 <param name="partner">2088101122136241</param> 14 <param name="merchant_customs_name">jwyhanguo_card</param> 15 </request> 16 <response> 17 <alipay> 18 <alipay_declare_no>2016052511082107300001603</alipay_declare_no> 19 <out_request_no>201505252210</out_request_no> 20 <result_code>SUCCESS</result_code> 21 <trade_no>2016052500001000100000599501</trade_no> 22 </alipay> 23 </response> 24 <sign>ad6d244175cda04a3736af16d9f2da1e</sign> 25 <sign_type>MD5</sign_type> 26 </alipay>