刚刚把支付接口对接完成,原觉得报关是支付宝调用的,后来才发现也要本身掉支付宝的接口.啥也不说了看代码: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>