刚刚把支付接口对接完成,原以为报关是支付宝调用的,后来才发现也要自己掉支付宝的接口.啥也不说了看代码:
可以下载demo,额.连接不知道怎么添加,需要的可以私信.
我这里是用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 Listparts = new ArrayList ();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 nameValues144 * @return145 */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 }
分别编写一个请求和相应对象:
请求对象
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 }
响应对象:
1 public class HttpResponse { 2 3 /** 4 * 返回中的Header信息 5 */ 6 private Header[] responseHeaders; 7 8 /** 9 * String类型的result10 */11 private String stringResult;12 13 /**14 * btye类型的result15 */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:
/** * 生成请求url * @param params * @param key * @param paygateway * @param input_charset * @return */ public static String createUrl( Mapparams ,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
测试:
1 public static void main(String[] args) { 2 //报关 3 Mapparams = new HashMap (); 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 }
返回成功信息--案例:
12 T 34 0b69f5e1fd796b944c9749e832979ffb 5 1 6 hanguo 7 2016052500001000100000599501 8 utf-8 9 HANGZHOU10 MD511 alipay.acquire.customs12 20150525221013 208810112213624114 jwyhanguo_card15 1617 2418 232016052511082107300001603 19201505252210 20SUCCESS 212016052500001000100000599501 22ad6d244175cda04a3736af16d9f2da1e 25MD5 26