├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── aliyun │ └── api │ └── gateway │ └── demo │ ├── Client.java │ ├── Request.java │ ├── Response.java │ ├── constant │ ├── Constants.java │ ├── ContentType.java │ ├── HttpHeader.java │ ├── HttpMethod.java │ ├── HttpSchema.java │ └── SystemHeader.java │ ├── enums │ └── Method.java │ └── util │ ├── HttpUtil.java │ ├── HttpUtils.java │ ├── MessageDigestUtil.java │ └── SignUtil.java └── test └── java └── com └── aliyun └── api └── gateway └── demo └── Demo.java /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # api-gateway-demo-sign-java 2 | aliyun api gateway request signature demo by java 3 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.aliyun.api.gateway 8 | java.demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | com.alibaba 14 | fastjson 15 | 1.2.15 16 | 17 | 18 | org.apache.httpcomponents 19 | httpclient 20 | 4.2.1 21 | 22 | 23 | org.apache.httpcomponents 24 | httpcore 25 | 4.2.1 26 | 27 | 28 | commons-lang 29 | commons-lang 30 | 2.6 31 | 32 | 33 | org.eclipse.jetty 34 | jetty-util 35 | 9.3.7.v20160115 36 | 37 | 38 | junit 39 | junit 40 | 4.5 41 | test 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/Client.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo; 20 | 21 | import com.aliyun.api.gateway.demo.util.HttpUtil; 22 | 23 | /** 24 | * Client 25 | */ 26 | public class Client { 27 | /** 28 | * 发送请求 29 | * 30 | * @param request request对象 31 | * @return Response 32 | * @throws Exception 33 | */ 34 | public static Response execute(Request request) throws Exception { 35 | switch (request.getMethod()) { 36 | case GET: 37 | return HttpUtil.httpGet(request.getHost(), request.getPath(), 38 | request.getTimeout(), 39 | request.getHeaders(), 40 | request.getQuerys(), 41 | request.getSignHeaderPrefixList(), 42 | request.getAppKey(), request.getAppSecret()); 43 | case POST_FORM: 44 | return HttpUtil.httpPost(request.getHost(), request.getPath(), 45 | request.getTimeout(), 46 | request.getHeaders(), 47 | request.getQuerys(), 48 | request.getBodys(), 49 | request.getSignHeaderPrefixList(), 50 | request.getAppKey(), request.getAppSecret()); 51 | case POST_STRING: 52 | return HttpUtil.httpPost(request.getHost(), request.getPath(), 53 | request.getTimeout(), 54 | request.getHeaders(), 55 | request.getQuerys(), 56 | request.getStringBody(), 57 | request.getSignHeaderPrefixList(), 58 | request.getAppKey(), request.getAppSecret()); 59 | case POST_BYTES: 60 | return HttpUtil.httpPost(request.getHost(), request.getPath(), 61 | request.getTimeout(), 62 | request.getHeaders(), 63 | request.getQuerys(), 64 | request.getBytesBody(), 65 | request.getSignHeaderPrefixList(), 66 | request.getAppKey(), request.getAppSecret()); 67 | case PUT_STRING: 68 | return HttpUtil.httpPut(request.getHost(), request.getPath(), 69 | request.getTimeout(), 70 | request.getHeaders(), 71 | request.getQuerys(), 72 | request.getStringBody(), 73 | request.getSignHeaderPrefixList(), 74 | request.getAppKey(), request.getAppSecret()); 75 | case PUT_BYTES: 76 | return HttpUtil.httpPut(request.getHost(), request.getPath(), 77 | request.getTimeout(), 78 | request.getHeaders(), 79 | request.getQuerys(), 80 | request.getBytesBody(), 81 | request.getSignHeaderPrefixList(), 82 | request.getAppKey(), request.getAppSecret()); 83 | case DELETE: 84 | return HttpUtil.httpDelete(request.getHost(), request.getPath(), 85 | request.getTimeout(), 86 | request.getHeaders(), 87 | request.getQuerys(), 88 | request.getSignHeaderPrefixList(), 89 | request.getAppKey(), request.getAppSecret()); 90 | default: 91 | throw new IllegalArgumentException(String.format("unsupported method:%s", request.getMethod())); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/Request.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo; 20 | 21 | import com.aliyun.api.gateway.demo.enums.Method; 22 | 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * Request 28 | */ 29 | public class Request { 30 | 31 | public Request() { 32 | } 33 | 34 | public Request(Method method, String host, String path, String appKey, String appSecret, int timeout) { 35 | this.method = method; 36 | this.host = host; 37 | this.path = path; 38 | this.appKey = appKey; 39 | this.appSecret = appSecret; 40 | this.timeout = timeout; 41 | } 42 | 43 | /** 44 | * (必选)请求方法 45 | */ 46 | private Method method; 47 | 48 | /** 49 | * (必选)Host 50 | */ 51 | private String host; 52 | 53 | /** 54 | * (必选)Path 55 | */ 56 | private String path; 57 | 58 | /** 59 | * (必选)APP KEY 60 | */ 61 | private String appKey; 62 | 63 | /** 64 | * (必选)APP密钥 65 | */ 66 | private String appSecret; 67 | 68 | /** 69 | * (必选)超时时间,单位毫秒,设置零默认使用com.aliyun.apigateway.demo.constant.Constants.DEFAULT_TIMEOUT 70 | */ 71 | private int timeout; 72 | 73 | /** 74 | * (可选) HTTP头 75 | */ 76 | private Map headers; 77 | 78 | /** 79 | * (可选) Querys 80 | */ 81 | private Map querys; 82 | 83 | /** 84 | * (可选)表单参数 85 | */ 86 | private Map bodys; 87 | 88 | /** 89 | * (可选)字符串Body体 90 | */ 91 | private String stringBody; 92 | 93 | /** 94 | * (可选)字节数组类型Body体 95 | */ 96 | private byte[] bytesBody; 97 | 98 | /** 99 | * (可选)自定义参与签名Header前缀 100 | */ 101 | private List signHeaderPrefixList; 102 | 103 | public Method getMethod() { 104 | return method; 105 | } 106 | 107 | public void setMethod(Method method) { 108 | this.method = method; 109 | } 110 | 111 | public String getHost() { 112 | return host; 113 | } 114 | 115 | public void setPath(String path) { 116 | this.path = path; 117 | } 118 | 119 | public String getPath() { 120 | return path; 121 | } 122 | 123 | public void setHost(String host) { 124 | this.host = host; 125 | } 126 | 127 | public String getAppKey() { 128 | return appKey; 129 | } 130 | 131 | public void setAppKey(String appKey) { 132 | this.appKey = appKey; 133 | } 134 | 135 | public String getAppSecret() { 136 | return appSecret; 137 | } 138 | 139 | public void setAppSecret(String appSecret) { 140 | this.appSecret = appSecret; 141 | } 142 | 143 | public int getTimeout() { 144 | return timeout; 145 | } 146 | 147 | public void setTimeout(int timeout) { 148 | this.timeout = timeout; 149 | } 150 | 151 | public Map getHeaders() { 152 | return headers; 153 | } 154 | 155 | public void setHeaders(Map headers) { 156 | this.headers = headers; 157 | } 158 | 159 | public Map getQuerys() { 160 | return querys; 161 | } 162 | 163 | public void setQuerys(Map querys) { 164 | this.querys = querys; 165 | } 166 | 167 | public Map getBodys() { 168 | return bodys; 169 | } 170 | 171 | public void setBodys(Map bodys) { 172 | this.bodys = bodys; 173 | } 174 | 175 | public String getStringBody() { 176 | return stringBody; 177 | } 178 | 179 | public void setStringBody(String stringBody) { 180 | this.stringBody = stringBody; 181 | } 182 | 183 | public byte[] getBytesBody() { 184 | return bytesBody; 185 | } 186 | 187 | public void setBytesBody(byte[] bytesBody) { 188 | this.bytesBody = bytesBody; 189 | } 190 | 191 | public List getSignHeaderPrefixList() { 192 | return signHeaderPrefixList; 193 | } 194 | 195 | public void setSignHeaderPrefixList(List signHeaderPrefixList) { 196 | this.signHeaderPrefixList = signHeaderPrefixList; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/Response.java: -------------------------------------------------------------------------------- 1 | package com.aliyun.api.gateway.demo; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Response { 7 | private int statusCode; 8 | private String contentType; 9 | private String requestId; 10 | private String errorMessage; 11 | private Map headers; 12 | private String body; 13 | 14 | public Response() { 15 | 16 | } 17 | 18 | public int getStatusCode() { 19 | return statusCode; 20 | } 21 | 22 | public void setStatusCode(int statusCode) { 23 | this.statusCode = statusCode; 24 | } 25 | 26 | public String getContentType() { 27 | return contentType; 28 | } 29 | 30 | public void setContentType(String contentType) { 31 | this.contentType = contentType; 32 | } 33 | 34 | public String getRequestId() { 35 | return requestId; 36 | } 37 | 38 | public void setRequestId(String requestId) { 39 | this.requestId = requestId; 40 | } 41 | 42 | public String getErrorMessage() { 43 | return errorMessage; 44 | } 45 | 46 | public void setErrorMessage(String errorMessage) { 47 | this.errorMessage = errorMessage; 48 | } 49 | 50 | public Map getHeaders() { 51 | return headers; 52 | } 53 | 54 | public String getHeader(String key) { 55 | if (null != headers) { 56 | return headers.get(key); 57 | } else { 58 | return null; 59 | } 60 | } 61 | 62 | public void setHeaders(Map headers) { 63 | this.headers = headers; 64 | } 65 | 66 | public void setHeader(String key, String value) { 67 | if (null == this.headers) { 68 | this.headers = new HashMap(); 69 | } 70 | this.headers.put(key, value); 71 | } 72 | 73 | public String getBody() { 74 | return body; 75 | } 76 | 77 | public void setBody(String body) { 78 | this.body = body; 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * 通用常量 23 | */ 24 | public class Constants { 25 | //签名算法HmacSha256 26 | public static final String HMAC_SHA256 = "HmacSHA256"; 27 | //编码UTF-8 28 | public static final String ENCODING = "UTF-8"; 29 | //UserAgent 30 | public static final String USER_AGENT = "demo/aliyun/java"; 31 | //换行符 32 | public static final String LF = "\n"; 33 | //串联符 34 | public static final String SPE1 = ","; 35 | //示意符 36 | public static final String SPE2 = ":"; 37 | //连接符 38 | public static final String SPE3 = "&"; 39 | //赋值符 40 | public static final String SPE4 = "="; 41 | //问号符 42 | public static final String SPE5 = "?"; 43 | //默认请求超时时间,单位毫秒 44 | public static final int DEFAULT_TIMEOUT = 1000; 45 | //参与签名的系统Header前缀,只有指定前缀的Header才会参与到签名中 46 | public static final String CA_HEADER_TO_SIGN_PREFIX_SYSTEM = "X-Ca-"; 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/ContentType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * 常用HTTP Content-Type常量 23 | */ 24 | public class ContentType { 25 | //表单类型Content-Type 26 | public static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded; charset=UTF-8"; 27 | // 流类型Content-Type 28 | public static final String CONTENT_TYPE_STREAM = "application/octet-stream; charset=UTF-8"; 29 | //JSON类型Content-Type 30 | public static final String CONTENT_TYPE_JSON = "application/json; charset=UTF-8"; 31 | //XML类型Content-Type 32 | public static final String CONTENT_TYPE_XML = "application/xml; charset=UTF-8"; 33 | //文本类型Content-Type 34 | public static final String CONTENT_TYPE_TEXT = "application/text; charset=UTF-8"; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/HttpHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * HTTP头常量 23 | */ 24 | public class HttpHeader { 25 | //请求Header Accept 26 | public static final String HTTP_HEADER_ACCEPT = "Accept"; 27 | //请求Body内容MD5 Header 28 | public static final String HTTP_HEADER_CONTENT_MD5 = "Content-MD5"; 29 | //请求Header Content-Type 30 | public static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; 31 | //请求Header UserAgent 32 | public static final String HTTP_HEADER_USER_AGENT = "User-Agent"; 33 | //请求Header Date 34 | public static final String HTTP_HEADER_DATE = "Date"; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/HttpMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * HTTP方法常量 23 | */ 24 | public class HttpMethod { 25 | //GET 26 | public static final String GET = "GET"; 27 | //POST 28 | public static final String POST = "POST"; 29 | //PUT 30 | public static final String PUT = "PUT"; 31 | //DELETE 32 | public static final String DELETE = "DELETE"; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/HttpSchema.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * HTTP Schema常量 23 | */ 24 | public class HttpSchema { 25 | //HTTP 26 | public static final String HTTP = "http://"; 27 | //HTTPS 28 | public static final String HTTPS = "https://"; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/constant/SystemHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.constant; 20 | 21 | /** 22 | * 系统HTTP头常量 23 | */ 24 | public class SystemHeader { 25 | //签名Header 26 | public static final String X_CA_SIGNATURE = "X-Ca-Signature"; 27 | //所有参与签名的Header 28 | public static final String X_CA_SIGNATURE_HEADERS = "X-Ca-Signature-Headers"; 29 | //请求时间戳 30 | public static final String X_CA_TIMESTAMP = "X-Ca-Timestamp"; 31 | //请求放重放Nonce,15分钟内保持唯一,建议使用UUID 32 | public static final String X_CA_NONCE = "X-Ca-Nonce"; 33 | //APP KEY 34 | public static final String X_CA_KEY = "X-Ca-Key"; 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/enums/Method.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.enums; 20 | 21 | /** 22 | * Http请求方法 23 | * Created by lipengfei on 16/3/17. 24 | */ 25 | public enum Method { 26 | GET, POST_FORM, POST_STRING, POST_BYTES, PUT_FORM, PUT_STRING, PUT_BYTES, DELETE; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/util/HttpUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.util; 20 | 21 | import java.io.ByteArrayOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.UnsupportedEncodingException; 25 | import java.net.MalformedURLException; 26 | import java.net.URLEncoder; 27 | import java.nio.ByteBuffer; 28 | import java.nio.channels.Channels; 29 | import java.nio.channels.ReadableByteChannel; 30 | import java.nio.channels.WritableByteChannel; 31 | import java.security.KeyManagementException; 32 | import java.security.NoSuchAlgorithmException; 33 | import java.security.cert.X509Certificate; 34 | import java.util.ArrayList; 35 | import java.util.Date; 36 | import java.util.HashMap; 37 | import java.util.List; 38 | import java.util.Map; 39 | 40 | import javax.net.ssl.SSLContext; 41 | import javax.net.ssl.TrustManager; 42 | import javax.net.ssl.X509TrustManager; 43 | 44 | import org.apache.commons.lang.StringUtils; 45 | import org.apache.http.Header; 46 | import org.apache.http.HttpResponse; 47 | import org.apache.http.NameValuePair; 48 | import org.apache.http.client.HttpClient; 49 | import org.apache.http.client.entity.UrlEncodedFormEntity; 50 | import org.apache.http.client.methods.HttpDelete; 51 | import org.apache.http.client.methods.HttpGet; 52 | import org.apache.http.client.methods.HttpPost; 53 | import org.apache.http.client.methods.HttpPut; 54 | import org.apache.http.conn.ClientConnectionManager; 55 | import org.apache.http.conn.scheme.Scheme; 56 | import org.apache.http.conn.scheme.SchemeRegistry; 57 | import org.apache.http.conn.ssl.SSLSocketFactory; 58 | import org.apache.http.entity.ByteArrayEntity; 59 | import org.apache.http.entity.StringEntity; 60 | import org.apache.http.impl.client.DefaultHttpClient; 61 | import org.apache.http.message.BasicNameValuePair; 62 | import org.apache.http.params.CoreConnectionPNames; 63 | 64 | import com.aliyun.api.gateway.demo.Response; 65 | import com.aliyun.api.gateway.demo.constant.Constants; 66 | import com.aliyun.api.gateway.demo.constant.ContentType; 67 | import com.aliyun.api.gateway.demo.constant.HttpHeader; 68 | import com.aliyun.api.gateway.demo.constant.HttpMethod; 69 | import com.aliyun.api.gateway.demo.constant.SystemHeader; 70 | 71 | /** 72 | * Http工具类 73 | */ 74 | public class HttpUtil { 75 | /** 76 | * HTTP GET 77 | * @param host 78 | * @param path 79 | * @param connectTimeout 80 | * @param headers 81 | * @param querys 82 | * @param signHeaderPrefixList 83 | * @param appKey 84 | * @param appSecret 85 | * @return 86 | * @throws Exception 87 | */ 88 | public static Response httpGet(String host, String path, int connectTimeout, Map headers, Map querys, List signHeaderPrefixList, String appKey, String appSecret) 89 | throws Exception { 90 | headers = initialBasicHeader(HttpMethod.GET, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 91 | 92 | HttpClient httpClient = wrapClient(host); 93 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 94 | 95 | HttpGet get = new HttpGet(initUrl(host, path, querys)); 96 | 97 | for (Map.Entry e : headers.entrySet()) { 98 | get.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 99 | } 100 | 101 | return convert(httpClient.execute(get)); 102 | } 103 | 104 | /** 105 | * HTTP POST表单 106 | * @param host 107 | * @param path 108 | * @param connectTimeout 109 | * @param headers 110 | * @param querys 111 | * @param bodys 112 | * @param signHeaderPrefixList 113 | * @param appKey 114 | * @param appSecret 115 | * @return 116 | * @throws Exception 117 | */ 118 | public static Response httpPost(String host, String path, int connectTimeout, Map headers, Map querys, Map bodys, List signHeaderPrefixList, String appKey, String appSecret) 119 | throws Exception { 120 | if (headers == null) { 121 | headers = new HashMap(); 122 | } 123 | 124 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_FORM); 125 | 126 | headers = initialBasicHeader(HttpMethod.POST, path, headers, querys, bodys, signHeaderPrefixList, appKey, appSecret); 127 | 128 | HttpClient httpClient = wrapClient(host); 129 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 130 | 131 | HttpPost post = new HttpPost(initUrl(host, path, querys)); 132 | for (Map.Entry e : headers.entrySet()) { 133 | post.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 134 | } 135 | 136 | UrlEncodedFormEntity formEntity = buildFormEntity(bodys); 137 | if (formEntity != null) { 138 | post.setEntity(formEntity); 139 | } 140 | 141 | return convert(httpClient.execute(post)); 142 | } 143 | 144 | /** 145 | * Http POST 字符串 146 | * @param host 147 | * @param path 148 | * @param connectTimeout 149 | * @param headers 150 | * @param querys 151 | * @param body 152 | * @param signHeaderPrefixList 153 | * @param appKey 154 | * @param appSecret 155 | * @return 156 | * @throws Exception 157 | */ 158 | public static Response httpPost(String host, String path, int connectTimeout, Map headers, Map querys, String body, List signHeaderPrefixList, String appKey, String appSecret) 159 | throws Exception { 160 | headers = initialBasicHeader(HttpMethod.POST, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 161 | 162 | HttpClient httpClient = wrapClient(host); 163 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 164 | 165 | HttpPost post = new HttpPost(initUrl(host, path, querys)); 166 | for (Map.Entry e : headers.entrySet()) { 167 | post.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 168 | } 169 | 170 | if (StringUtils.isNotBlank(body)) { 171 | post.setEntity(new StringEntity(body, Constants.ENCODING)); 172 | 173 | } 174 | 175 | return convert(httpClient.execute(post)); 176 | } 177 | 178 | /** 179 | * HTTP POST 字节数组 180 | * @param host 181 | * @param path 182 | * @param connectTimeout 183 | * @param headers 184 | * @param querys 185 | * @param bodys 186 | * @param signHeaderPrefixList 187 | * @param appKey 188 | * @param appSecret 189 | * @return 190 | * @throws Exception 191 | */ 192 | public static Response httpPost(String host, String path, int connectTimeout, Map headers, Map querys, byte[] bodys, List signHeaderPrefixList, String appKey, String appSecret) 193 | throws Exception { 194 | headers = initialBasicHeader(HttpMethod.POST, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 195 | 196 | HttpClient httpClient = wrapClient(host); 197 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 198 | 199 | HttpPost post = new HttpPost(initUrl(host, path, querys)); 200 | for (Map.Entry e : headers.entrySet()) { 201 | post.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 202 | } 203 | 204 | if (bodys != null) { 205 | post.setEntity(new ByteArrayEntity(bodys)); 206 | } 207 | 208 | return convert(httpClient.execute(post)); 209 | } 210 | 211 | /** 212 | * HTTP PUT 字符串 213 | * @param host 214 | * @param path 215 | * @param connectTimeout 216 | * @param headers 217 | * @param querys 218 | * @param body 219 | * @param signHeaderPrefixList 220 | * @param appKey 221 | * @param appSecret 222 | * @return 223 | * @throws Exception 224 | */ 225 | public static Response httpPut(String host, String path, int connectTimeout, Map headers, Map querys, String body, List signHeaderPrefixList, String appKey, String appSecret) 226 | throws Exception { 227 | headers = initialBasicHeader(HttpMethod.PUT, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 228 | 229 | HttpClient httpClient = wrapClient(host); 230 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 231 | 232 | HttpPut put = new HttpPut(initUrl(host, path, querys)); 233 | for (Map.Entry e : headers.entrySet()) { 234 | put.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 235 | } 236 | 237 | if (StringUtils.isNotBlank(body)) { 238 | put.setEntity(new StringEntity(body, Constants.ENCODING)); 239 | 240 | } 241 | 242 | return convert(httpClient.execute(put)); 243 | } 244 | 245 | /** 246 | * HTTP PUT字节数组 247 | * @param host 248 | * @param path 249 | * @param connectTimeout 250 | * @param headers 251 | * @param querys 252 | * @param bodys 253 | * @param signHeaderPrefixList 254 | * @param appKey 255 | * @param appSecret 256 | * @return 257 | * @throws Exception 258 | */ 259 | public static Response httpPut(String host, String path, int connectTimeout, Map headers, Map querys, byte[] bodys, List signHeaderPrefixList, String appKey, String appSecret) 260 | throws Exception { 261 | headers = initialBasicHeader(HttpMethod.PUT, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 262 | 263 | HttpClient httpClient = wrapClient(host); 264 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 265 | 266 | HttpPut put = new HttpPut(initUrl(host, path, querys)); 267 | for (Map.Entry e : headers.entrySet()) { 268 | put.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 269 | } 270 | 271 | if (bodys != null) { 272 | put.setEntity(new ByteArrayEntity(bodys)); 273 | } 274 | 275 | return convert(httpClient.execute(put)); 276 | } 277 | 278 | /** 279 | * HTTP DELETE 280 | * @param host 281 | * @param path 282 | * @param connectTimeout 283 | * @param headers 284 | * @param querys 285 | * @param signHeaderPrefixList 286 | * @param appKey 287 | * @param appSecret 288 | * @return 289 | * @throws Exception 290 | */ 291 | public static Response httpDelete(String host, String path, int connectTimeout, Map headers, Map querys, List signHeaderPrefixList, String appKey, String appSecret) 292 | throws Exception { 293 | headers = initialBasicHeader(HttpMethod.DELETE, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret); 294 | 295 | HttpClient httpClient = wrapClient(host); 296 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout)); 297 | 298 | HttpDelete delete = new HttpDelete(initUrl(host, path, querys)); 299 | for (Map.Entry e : headers.entrySet()) { 300 | delete.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue())); 301 | } 302 | 303 | return convert(httpClient.execute(delete)); 304 | } 305 | 306 | /** 307 | * 构建FormEntity 308 | * 309 | * @param formParam 310 | * @return 311 | * @throws UnsupportedEncodingException 312 | */ 313 | private static UrlEncodedFormEntity buildFormEntity(Map formParam) 314 | throws UnsupportedEncodingException { 315 | if (formParam != null) { 316 | List nameValuePairList = new ArrayList(); 317 | 318 | for (String key : formParam.keySet()) { 319 | nameValuePairList.add(new BasicNameValuePair(key, formParam.get(key))); 320 | } 321 | UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, Constants.ENCODING); 322 | formEntity.setContentType(ContentType.CONTENT_TYPE_FORM); 323 | return formEntity; 324 | } 325 | 326 | return null; 327 | } 328 | 329 | private static String initUrl(String host, String path, Map querys) throws UnsupportedEncodingException { 330 | StringBuilder sbUrl = new StringBuilder(); 331 | sbUrl.append(host); 332 | if (!StringUtils.isBlank(path)) { 333 | sbUrl.append(path); 334 | } 335 | if (null != querys) { 336 | StringBuilder sbQuery = new StringBuilder(); 337 | for (Map.Entry query : querys.entrySet()) { 338 | if (0 < sbQuery.length()) { 339 | sbQuery.append(Constants.SPE3); 340 | } 341 | if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { 342 | sbQuery.append(query.getValue()); 343 | } 344 | if (!StringUtils.isBlank(query.getKey())) { 345 | sbQuery.append(query.getKey()); 346 | if (!StringUtils.isBlank(query.getValue())) { 347 | sbQuery.append(Constants.SPE4); 348 | sbQuery.append(URLEncoder.encode(query.getValue(), Constants.ENCODING)); 349 | } 350 | } 351 | } 352 | if (0 < sbQuery.length()) { 353 | sbUrl.append(Constants.SPE5).append(sbQuery); 354 | } 355 | } 356 | 357 | return sbUrl.toString(); 358 | } 359 | 360 | 361 | /** 362 | * 初始化基础Header 363 | * @param method 364 | * @param path 365 | * @param headers 366 | * @param querys 367 | * @param bodys 368 | * @param signHeaderPrefixList 369 | * @param appKey 370 | * @param appSecret 371 | * @return 372 | * @throws MalformedURLException 373 | */ 374 | private static Map initialBasicHeader(String method, String path, 375 | Map headers, 376 | Map querys, 377 | Map bodys, 378 | List signHeaderPrefixList, 379 | String appKey, String appSecret) 380 | throws MalformedURLException { 381 | if (headers == null) { 382 | headers = new HashMap(); 383 | } 384 | 385 | headers.put(SystemHeader.X_CA_TIMESTAMP, String.valueOf(new Date().getTime())); 386 | //headers.put(SystemHeader.X_CA_NONCE, UUID.randomUUID().toString()); 387 | headers.put(SystemHeader.X_CA_KEY, appKey); 388 | headers.put(SystemHeader.X_CA_SIGNATURE, 389 | SignUtil.sign(appSecret, method, path, headers, querys, bodys, signHeaderPrefixList)); 390 | 391 | return headers; 392 | } 393 | 394 | /** 395 | * 读取超时时间 396 | * 397 | * @param timeout 398 | * @return 399 | */ 400 | private static int getTimeout(int timeout) { 401 | if (timeout == 0) { 402 | return Constants.DEFAULT_TIMEOUT; 403 | } 404 | 405 | return timeout; 406 | } 407 | 408 | private static Response convert(HttpResponse response) throws IOException { 409 | Response res = new Response(); 410 | 411 | if (null != response) { 412 | res.setStatusCode(response.getStatusLine().getStatusCode()); 413 | for (Header header : response.getAllHeaders()) { 414 | res.setHeader(header.getName(), MessageDigestUtil.iso88591ToUtf8(header.getValue())); 415 | } 416 | 417 | res.setContentType(res.getHeader("Content-Type")); 418 | res.setRequestId(res.getHeader("X-Ca-Request-Id")); 419 | res.setErrorMessage(res.getHeader("X-Ca-Error-Message")); 420 | res.setBody(readStreamAsStr(response.getEntity().getContent())); 421 | 422 | } else { 423 | //服务器无回应 424 | res.setStatusCode(500); 425 | res.setErrorMessage("No Response"); 426 | } 427 | 428 | return res; 429 | } 430 | 431 | 432 | /** 433 | * 将流转换为字符串 434 | * 435 | * @param is 436 | * @return 437 | * @throws IOException 438 | */ 439 | public static String readStreamAsStr(InputStream is) throws IOException { 440 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 441 | WritableByteChannel dest = Channels.newChannel(bos); 442 | ReadableByteChannel src = Channels.newChannel(is); 443 | ByteBuffer bb = ByteBuffer.allocate(4096); 444 | 445 | while (src.read(bb) != -1) { 446 | bb.flip(); 447 | dest.write(bb); 448 | bb.clear(); 449 | } 450 | src.close(); 451 | dest.close(); 452 | 453 | return new String(bos.toByteArray(), Constants.ENCODING); 454 | } 455 | 456 | private static HttpClient wrapClient(String host) { 457 | HttpClient httpClient = new DefaultHttpClient(); 458 | if (host.startsWith("https://")) { 459 | sslClient(httpClient); 460 | } 461 | 462 | return httpClient; 463 | } 464 | 465 | private static void sslClient(HttpClient httpClient) { 466 | try { 467 | SSLContext ctx = SSLContext.getInstance("TLS"); 468 | X509TrustManager tm = new X509TrustManager() { 469 | public X509Certificate[] getAcceptedIssuers() { 470 | return null; 471 | } 472 | public void checkClientTrusted(X509Certificate[] xcs, String str) { 473 | 474 | } 475 | public void checkServerTrusted(X509Certificate[] xcs, String str) { 476 | 477 | } 478 | }; 479 | ctx.init(null, new TrustManager[] { tm }, null); 480 | SSLSocketFactory ssf = new SSLSocketFactory(ctx); 481 | ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 482 | ClientConnectionManager ccm = httpClient.getConnectionManager(); 483 | SchemeRegistry registry = ccm.getSchemeRegistry(); 484 | registry.register(new Scheme("https", 443, ssf)); 485 | } catch (KeyManagementException ex) { 486 | throw new RuntimeException(ex); 487 | } catch (NoSuchAlgorithmException ex) { 488 | throw new RuntimeException(ex); 489 | } 490 | } 491 | } -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.aliyun.api.gateway.demo.util; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.security.KeyManagementException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.cert.X509Certificate; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import javax.net.ssl.SSLContext; 13 | import javax.net.ssl.TrustManager; 14 | import javax.net.ssl.X509TrustManager; 15 | 16 | import org.apache.commons.lang.StringUtils; 17 | import org.apache.http.HttpResponse; 18 | import org.apache.http.NameValuePair; 19 | import org.apache.http.client.HttpClient; 20 | import org.apache.http.client.entity.UrlEncodedFormEntity; 21 | import org.apache.http.client.methods.HttpDelete; 22 | import org.apache.http.client.methods.HttpGet; 23 | import org.apache.http.client.methods.HttpPost; 24 | import org.apache.http.client.methods.HttpPut; 25 | import org.apache.http.conn.ClientConnectionManager; 26 | import org.apache.http.conn.scheme.Scheme; 27 | import org.apache.http.conn.scheme.SchemeRegistry; 28 | import org.apache.http.conn.ssl.SSLSocketFactory; 29 | import org.apache.http.entity.ByteArrayEntity; 30 | import org.apache.http.entity.StringEntity; 31 | import org.apache.http.impl.client.DefaultHttpClient; 32 | import org.apache.http.message.BasicNameValuePair; 33 | 34 | public class HttpUtils { 35 | 36 | /** 37 | * get 38 | * 39 | * @param host 40 | * @param path 41 | * @param method 42 | * @param headers 43 | * @param querys 44 | * @return 45 | * @throws Exception 46 | */ 47 | public static HttpResponse doGet(String host, String path, String method, 48 | Map headers, 49 | Map querys) 50 | throws Exception { 51 | HttpClient httpClient = wrapClient(host); 52 | 53 | HttpGet request = new HttpGet(buildUrl(host, path, querys)); 54 | for (Map.Entry e : headers.entrySet()) { 55 | request.addHeader(e.getKey(), e.getValue()); 56 | } 57 | 58 | return httpClient.execute(request); 59 | } 60 | 61 | /** 62 | * post form 63 | * 64 | * @param host 65 | * @param path 66 | * @param method 67 | * @param headers 68 | * @param querys 69 | * @param bodys 70 | * @return 71 | * @throws Exception 72 | */ 73 | public static HttpResponse doPost(String host, String path, String method, 74 | Map headers, 75 | Map querys, 76 | Map bodys) 77 | throws Exception { 78 | HttpClient httpClient = wrapClient(host); 79 | 80 | HttpPost request = new HttpPost(buildUrl(host, path, querys)); 81 | for (Map.Entry e : headers.entrySet()) { 82 | request.addHeader(e.getKey(), e.getValue()); 83 | } 84 | 85 | if (bodys != null) { 86 | List nameValuePairList = new ArrayList(); 87 | 88 | for (String key : bodys.keySet()) { 89 | nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key))); 90 | } 91 | UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); 92 | formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); 93 | request.setEntity(formEntity); 94 | } 95 | 96 | return httpClient.execute(request); 97 | } 98 | 99 | /** 100 | * Post String 101 | * 102 | * @param host 103 | * @param path 104 | * @param method 105 | * @param headers 106 | * @param querys 107 | * @param body 108 | * @return 109 | * @throws Exception 110 | */ 111 | public static HttpResponse doPost(String host, String path, String method, 112 | Map headers, 113 | Map querys, 114 | String body) 115 | throws Exception { 116 | HttpClient httpClient = wrapClient(host); 117 | 118 | HttpPost request = new HttpPost(buildUrl(host, path, querys)); 119 | for (Map.Entry e : headers.entrySet()) { 120 | request.addHeader(e.getKey(), e.getValue()); 121 | } 122 | 123 | if (StringUtils.isNotBlank(body)) { 124 | request.setEntity(new StringEntity(body, "utf-8")); 125 | } 126 | 127 | return httpClient.execute(request); 128 | } 129 | 130 | /** 131 | * Post stream 132 | * 133 | * @param host 134 | * @param path 135 | * @param method 136 | * @param headers 137 | * @param querys 138 | * @param body 139 | * @return 140 | * @throws Exception 141 | */ 142 | public static HttpResponse doPost(String host, String path, String method, 143 | Map headers, 144 | Map querys, 145 | byte[] body) 146 | throws Exception { 147 | HttpClient httpClient = wrapClient(host); 148 | 149 | HttpPost request = new HttpPost(buildUrl(host, path, querys)); 150 | for (Map.Entry e : headers.entrySet()) { 151 | request.addHeader(e.getKey(), e.getValue()); 152 | } 153 | 154 | if (body != null) { 155 | request.setEntity(new ByteArrayEntity(body)); 156 | } 157 | 158 | return httpClient.execute(request); 159 | } 160 | 161 | /** 162 | * Put String 163 | * @param host 164 | * @param path 165 | * @param method 166 | * @param headers 167 | * @param querys 168 | * @param body 169 | * @return 170 | * @throws Exception 171 | */ 172 | public static HttpResponse doPut(String host, String path, String method, 173 | Map headers, 174 | Map querys, 175 | String body) 176 | throws Exception { 177 | HttpClient httpClient = wrapClient(host); 178 | 179 | HttpPut request = new HttpPut(buildUrl(host, path, querys)); 180 | for (Map.Entry e : headers.entrySet()) { 181 | request.addHeader(e.getKey(), e.getValue()); 182 | } 183 | 184 | if (StringUtils.isNotBlank(body)) { 185 | request.setEntity(new StringEntity(body, "utf-8")); 186 | } 187 | 188 | return httpClient.execute(request); 189 | } 190 | 191 | /** 192 | * Put stream 193 | * @param host 194 | * @param path 195 | * @param method 196 | * @param headers 197 | * @param querys 198 | * @param body 199 | * @return 200 | * @throws Exception 201 | */ 202 | public static HttpResponse doPut(String host, String path, String method, 203 | Map headers, 204 | Map querys, 205 | byte[] body) 206 | throws Exception { 207 | HttpClient httpClient = wrapClient(host); 208 | 209 | HttpPut request = new HttpPut(buildUrl(host, path, querys)); 210 | for (Map.Entry e : headers.entrySet()) { 211 | request.addHeader(e.getKey(), e.getValue()); 212 | } 213 | 214 | if (body != null) { 215 | request.setEntity(new ByteArrayEntity(body)); 216 | } 217 | 218 | return httpClient.execute(request); 219 | } 220 | 221 | /** 222 | * Delete 223 | * 224 | * @param host 225 | * @param path 226 | * @param method 227 | * @param headers 228 | * @param querys 229 | * @return 230 | * @throws Exception 231 | */ 232 | public static HttpResponse doDelete(String host, String path, String method, 233 | Map headers, 234 | Map querys) 235 | throws Exception { 236 | HttpClient httpClient = wrapClient(host); 237 | 238 | HttpDelete request = new HttpDelete(buildUrl(host, path, querys)); 239 | for (Map.Entry e : headers.entrySet()) { 240 | request.addHeader(e.getKey(), e.getValue()); 241 | } 242 | 243 | return httpClient.execute(request); 244 | } 245 | 246 | private static String buildUrl(String host, String path, Map querys) throws UnsupportedEncodingException { 247 | StringBuilder sbUrl = new StringBuilder(); 248 | sbUrl.append(host); 249 | if (!StringUtils.isBlank(path)) { 250 | sbUrl.append(path); 251 | } 252 | if (null != querys) { 253 | StringBuilder sbQuery = new StringBuilder(); 254 | for (Map.Entry query : querys.entrySet()) { 255 | if (0 < sbQuery.length()) { 256 | sbQuery.append("&"); 257 | } 258 | if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { 259 | sbQuery.append(query.getValue()); 260 | } 261 | if (!StringUtils.isBlank(query.getKey())) { 262 | sbQuery.append(query.getKey()); 263 | if (!StringUtils.isBlank(query.getValue())) { 264 | sbQuery.append("="); 265 | sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); 266 | } 267 | } 268 | } 269 | if (0 < sbQuery.length()) { 270 | sbUrl.append("?").append(sbQuery); 271 | } 272 | } 273 | 274 | return sbUrl.toString(); 275 | } 276 | 277 | private static HttpClient wrapClient(String host) { 278 | HttpClient httpClient = new DefaultHttpClient(); 279 | if (host.startsWith("https://")) { 280 | sslClient(httpClient); 281 | } 282 | 283 | return httpClient; 284 | } 285 | 286 | private static void sslClient(HttpClient httpClient) { 287 | try { 288 | SSLContext ctx = SSLContext.getInstance("TLS"); 289 | X509TrustManager tm = new X509TrustManager() { 290 | public X509Certificate[] getAcceptedIssuers() { 291 | return null; 292 | } 293 | public void checkClientTrusted(X509Certificate[] xcs, String str) { 294 | 295 | } 296 | public void checkServerTrusted(X509Certificate[] xcs, String str) { 297 | 298 | } 299 | }; 300 | ctx.init(null, new TrustManager[] { tm }, null); 301 | SSLSocketFactory ssf = new SSLSocketFactory(ctx); 302 | ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 303 | ClientConnectionManager ccm = httpClient.getConnectionManager(); 304 | SchemeRegistry registry = ccm.getSchemeRegistry(); 305 | registry.register(new Scheme("https", 443, ssf)); 306 | } catch (KeyManagementException ex) { 307 | throw new RuntimeException(ex); 308 | } catch (NoSuchAlgorithmException ex) { 309 | throw new RuntimeException(ex); 310 | } 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/util/MessageDigestUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.util; 20 | 21 | import com.aliyun.api.gateway.demo.constant.Constants; 22 | import org.apache.commons.codec.binary.Base64; 23 | 24 | import java.io.UnsupportedEncodingException; 25 | import java.security.MessageDigest; 26 | import java.security.NoSuchAlgorithmException; 27 | 28 | /** 29 | * 消息摘要工具 30 | */ 31 | public class MessageDigestUtil { 32 | /** 33 | * 先进行MD5摘要再进行Base64编码获取摘要字符串 34 | * 35 | * @param str 36 | * @return 37 | */ 38 | public static String base64AndMD5(String str) { 39 | if (str == null) { 40 | throw new IllegalArgumentException("inStr can not be null"); 41 | } 42 | return base64AndMD5(toBytes(str)); 43 | } 44 | 45 | /** 46 | * 先进行MD5摘要再进行Base64编码获取摘要字符串 47 | * 48 | * @return 49 | */ 50 | public static String base64AndMD5(byte[] bytes) { 51 | if (bytes == null) { 52 | throw new IllegalArgumentException("bytes can not be null"); 53 | } 54 | try { 55 | final MessageDigest md = MessageDigest.getInstance("MD5"); 56 | md.reset(); 57 | md.update(bytes); 58 | final Base64 base64 = new Base64(); 59 | final byte[] enbytes = base64.encode(md.digest()); 60 | return new String(enbytes); 61 | } catch (final NoSuchAlgorithmException e) { 62 | throw new IllegalArgumentException("unknown algorithm MD5"); 63 | } 64 | } 65 | 66 | /** 67 | * UTF-8编码转换为ISO-9959-1 68 | * 69 | * @param str 70 | * @return 71 | */ 72 | public static String utf8ToIso88591(String str) { 73 | if (str == null) { 74 | return str; 75 | } 76 | 77 | try { 78 | return new String(str.getBytes("UTF-8"), "ISO-8859-1"); 79 | } catch (UnsupportedEncodingException e) { 80 | throw new RuntimeException(e.getMessage(), e); 81 | } 82 | } 83 | 84 | /** 85 | * ISO-9959-1编码转换为UTF-8 86 | * 87 | * @param str 88 | * @return 89 | */ 90 | public static String iso88591ToUtf8(String str) { 91 | if (str == null) { 92 | return str; 93 | } 94 | 95 | try { 96 | return new String(str.getBytes("ISO-8859-1"), "UTF-8"); 97 | } catch (UnsupportedEncodingException e) { 98 | throw new RuntimeException(e.getMessage(), e); 99 | } 100 | } 101 | 102 | /** 103 | * String转换为字节数组 104 | * 105 | * @param str 106 | * @return 107 | */ 108 | private static byte[] toBytes(final String str) { 109 | if (str == null) { 110 | return null; 111 | } 112 | try { 113 | return str.getBytes(Constants.ENCODING); 114 | } catch (final UnsupportedEncodingException e) { 115 | throw new RuntimeException(e.getMessage(), e); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/aliyun/api/gateway/demo/util/SignUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo.util; 20 | 21 | import java.util.Collections; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.TreeMap; 25 | 26 | import javax.crypto.Mac; 27 | import javax.crypto.spec.SecretKeySpec; 28 | 29 | import org.apache.commons.codec.binary.Base64; 30 | import org.apache.commons.lang.StringUtils; 31 | 32 | import com.aliyun.api.gateway.demo.constant.Constants; 33 | import com.aliyun.api.gateway.demo.constant.HttpHeader; 34 | import com.aliyun.api.gateway.demo.constant.SystemHeader; 35 | 36 | /** 37 | * 签名工具 38 | */ 39 | public class SignUtil { 40 | 41 | /** 42 | * 计算签名 43 | * 44 | * @param secret APP密钥 45 | * @param method HttpMethod 46 | * @param path 47 | * @param headers 48 | * @param querys 49 | * @param bodys 50 | * @param signHeaderPrefixList 自定义参与签名Header前缀 51 | * @return 签名后的字符串 52 | */ 53 | public static String sign(String secret, String method, String path, 54 | Map headers, 55 | Map querys, 56 | Map bodys, 57 | List signHeaderPrefixList) { 58 | try { 59 | Mac hmacSha256 = Mac.getInstance(Constants.HMAC_SHA256); 60 | byte[] keyBytes = secret.getBytes(Constants.ENCODING); 61 | hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, Constants.HMAC_SHA256)); 62 | 63 | return new String(Base64.encodeBase64( 64 | hmacSha256.doFinal(buildStringToSign(method, path, headers, querys, bodys, signHeaderPrefixList) 65 | .getBytes(Constants.ENCODING))), 66 | Constants.ENCODING); 67 | } catch (Exception e) { 68 | throw new RuntimeException(e); 69 | } 70 | } 71 | 72 | /** 73 | * 构建待签名字符串 74 | * @param method 75 | * @param path 76 | * @param headers 77 | * @param querys 78 | * @param bodys 79 | * @param signHeaderPrefixList 80 | * @return 81 | */ 82 | private static String buildStringToSign(String method, String path, 83 | Map headers, 84 | Map querys, 85 | Map bodys, 86 | List signHeaderPrefixList) { 87 | StringBuilder sb = new StringBuilder(); 88 | 89 | sb.append(method.toUpperCase()).append(Constants.LF); 90 | if (null != headers) { 91 | if (null != headers.get(HttpHeader.HTTP_HEADER_ACCEPT)) { 92 | sb.append(headers.get(HttpHeader.HTTP_HEADER_ACCEPT)); 93 | } 94 | sb.append(Constants.LF); 95 | if (null != headers.get(HttpHeader.HTTP_HEADER_CONTENT_MD5)) { 96 | sb.append(headers.get(HttpHeader.HTTP_HEADER_CONTENT_MD5)); 97 | } 98 | sb.append(Constants.LF); 99 | if (null != headers.get(HttpHeader.HTTP_HEADER_CONTENT_TYPE)) { 100 | sb.append(headers.get(HttpHeader.HTTP_HEADER_CONTENT_TYPE)); 101 | } 102 | sb.append(Constants.LF); 103 | if (null != headers.get(HttpHeader.HTTP_HEADER_DATE)) { 104 | sb.append(headers.get(HttpHeader.HTTP_HEADER_DATE)); 105 | } 106 | } 107 | sb.append(Constants.LF); 108 | sb.append(buildHeaders(headers, signHeaderPrefixList)); 109 | sb.append(buildResource(path, querys, bodys)); 110 | 111 | return sb.toString(); 112 | } 113 | 114 | /** 115 | * 构建待签名Path+Query+BODY 116 | * 117 | * @param path 118 | * @param querys 119 | * @param bodys 120 | * @return 待签名 121 | */ 122 | private static String buildResource(String path, Map querys, Map bodys) { 123 | StringBuilder sb = new StringBuilder(); 124 | 125 | if (!StringUtils.isBlank(path)) { 126 | sb.append(path); 127 | } 128 | Map sortMap = new TreeMap(); 129 | if (null != querys) { 130 | for (Map.Entry query : querys.entrySet()) { 131 | if (!StringUtils.isBlank(query.getKey())) { 132 | sortMap.put(query.getKey(), query.getValue()); 133 | } 134 | } 135 | } 136 | 137 | if (null != bodys) { 138 | for (Map.Entry body : bodys.entrySet()) { 139 | if (!StringUtils.isBlank(body.getKey())) { 140 | sortMap.put(body.getKey(), body.getValue()); 141 | } 142 | } 143 | } 144 | 145 | StringBuilder sbParam = new StringBuilder(); 146 | for (Map.Entry item : sortMap.entrySet()) { 147 | if (!StringUtils.isBlank(item.getKey())) { 148 | if (0 < sbParam.length()) { 149 | sbParam.append(Constants.SPE3); 150 | } 151 | sbParam.append(item.getKey()); 152 | if (!StringUtils.isBlank(item.getValue())) { 153 | sbParam.append(Constants.SPE4).append(item.getValue()); 154 | } 155 | } 156 | } 157 | if (0 < sbParam.length()) { 158 | sb.append(Constants.SPE5); 159 | sb.append(sbParam); 160 | } 161 | 162 | return sb.toString(); 163 | } 164 | 165 | /** 166 | * 构建待签名Http头 167 | * 168 | * @param headers 请求中所有的Http头 169 | * @param signHeaderPrefixList 自定义参与签名Header前缀 170 | * @return 待签名Http头 171 | */ 172 | private static String buildHeaders(Map headers, List signHeaderPrefixList) { 173 | StringBuilder sb = new StringBuilder(); 174 | 175 | if (null != signHeaderPrefixList) { 176 | signHeaderPrefixList.remove(SystemHeader.X_CA_SIGNATURE); 177 | signHeaderPrefixList.remove(HttpHeader.HTTP_HEADER_ACCEPT); 178 | signHeaderPrefixList.remove(HttpHeader.HTTP_HEADER_CONTENT_MD5); 179 | signHeaderPrefixList.remove(HttpHeader.HTTP_HEADER_CONTENT_TYPE); 180 | signHeaderPrefixList.remove(HttpHeader.HTTP_HEADER_DATE); 181 | Collections.sort(signHeaderPrefixList); 182 | if (null != headers) { 183 | Map sortMap = new TreeMap(); 184 | sortMap.putAll(headers); 185 | StringBuilder signHeadersStringBuilder = new StringBuilder(); 186 | for (Map.Entry header : sortMap.entrySet()) { 187 | if (isHeaderToSign(header.getKey(), signHeaderPrefixList)) { 188 | sb.append(header.getKey()); 189 | sb.append(Constants.SPE2); 190 | if (!StringUtils.isBlank(header.getValue())) { 191 | sb.append(header.getValue()); 192 | } 193 | sb.append(Constants.LF); 194 | if (0 < signHeadersStringBuilder.length()) { 195 | signHeadersStringBuilder.append(Constants.SPE1); 196 | } 197 | signHeadersStringBuilder.append(header.getKey()); 198 | } 199 | } 200 | headers.put(SystemHeader.X_CA_SIGNATURE_HEADERS, signHeadersStringBuilder.toString()); 201 | } 202 | } 203 | 204 | return sb.toString(); 205 | } 206 | 207 | /** 208 | * Http头是否参与签名 return 209 | */ 210 | private static boolean isHeaderToSign(String headerName, List signHeaderPrefixList) { 211 | if (StringUtils.isBlank(headerName)) { 212 | return false; 213 | } 214 | 215 | if (headerName.startsWith(Constants.CA_HEADER_TO_SIGN_PREFIX_SYSTEM)) { 216 | return true; 217 | } 218 | 219 | if (null != signHeaderPrefixList) { 220 | for (String signHeaderPrefix : signHeaderPrefixList) { 221 | if (headerName.equalsIgnoreCase(signHeaderPrefix)) { 222 | return true; 223 | } 224 | } 225 | } 226 | 227 | return false; 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /src/test/java/com/aliyun/api/gateway/demo/Demo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package com.aliyun.api.gateway.demo; 20 | 21 | import com.alibaba.fastjson.JSON; 22 | import com.aliyun.api.gateway.demo.constant.Constants; 23 | import com.aliyun.api.gateway.demo.constant.ContentType; 24 | import com.aliyun.api.gateway.demo.constant.HttpHeader; 25 | import com.aliyun.api.gateway.demo.constant.HttpSchema; 26 | import com.aliyun.api.gateway.demo.enums.Method; 27 | import com.aliyun.api.gateway.demo.util.MessageDigestUtil; 28 | import org.apache.http.Header; 29 | import org.apache.http.HttpResponse; 30 | import org.junit.Test; 31 | 32 | import java.io.ByteArrayOutputStream; 33 | import java.io.IOException; 34 | import java.io.InputStream; 35 | import java.nio.ByteBuffer; 36 | import java.nio.channels.Channels; 37 | import java.nio.channels.ReadableByteChannel; 38 | import java.nio.channels.WritableByteChannel; 39 | import java.util.ArrayList; 40 | import java.util.HashMap; 41 | import java.util.List; 42 | import java.util.Map; 43 | 44 | /** 45 | * 调用示例 46 | * 请替换APP_KEY,APP_SECRET,HOST,CUSTOM_HEADERS_TO_SIGN_PREFIX为真实配置 47 | */ 48 | public class Demo { 49 | //APP KEY 50 | private final static String APP_KEY = "app_key"; 51 | // APP密钥 52 | private final static String APP_SECRET = "APP_SECRET"; 53 | //API域名 54 | private final static String HOST = "api.aaaa.com"; 55 | //自定义参与签名Header前缀(可选,默认只有"X-Ca-"开头的参与到Header签名) 56 | private final static List CUSTOM_HEADERS_TO_SIGN_PREFIX = new ArrayList(); 57 | 58 | /** 59 | * HTTP GET 60 | * 61 | * @throws Exception 62 | */ 63 | @Test 64 | public void get() throws Exception { 65 | //请求path 66 | String path = "/get"; 67 | 68 | Map headers = new HashMap(); 69 | //(必填)根据期望的Response内容类型设置 70 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 71 | headers.put("a-header1", "header1Value"); 72 | headers.put("b-header2", "header2Value"); 73 | 74 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 75 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 76 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 77 | 78 | Request request = new Request(Method.GET, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 79 | request.setHeaders(headers); 80 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 81 | 82 | //请求的query 83 | Map querys = new HashMap(); 84 | querys.put("a-query1", "query1Value"); 85 | querys.put("b-query2", "query2Value"); 86 | request.setQuerys(querys); 87 | 88 | //调用服务端 89 | Response response = Client.execute(request); 90 | 91 | System.out.println(JSON.toJSONString(response)); 92 | } 93 | 94 | /** 95 | * HTTP POST 表单 96 | * 97 | * @throws Exception 98 | */ 99 | @Test 100 | public void postForm() throws Exception { 101 | //请求path 102 | String path = "/postform"; 103 | 104 | Map headers = new HashMap(); 105 | //(必填)根据期望的Response内容类型设置 106 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 107 | headers.put("a-header1", "header1Value"); 108 | headers.put("b-header2", "header2Value"); 109 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 110 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 111 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 112 | 113 | Request request = new Request(Method.POST_FORM, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 114 | request.setHeaders(headers); 115 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 116 | 117 | //请求的query 118 | Map querys = new HashMap(); 119 | querys.put("a-query1", "query1Value"); 120 | querys.put("b-query2", "query2Value"); 121 | request.setQuerys(querys); 122 | 123 | Map bodys = new HashMap(); 124 | bodys.put("a-body1", "body1Value"); 125 | bodys.put("b-body2", "body2Value"); 126 | request.setBodys(bodys); 127 | 128 | //调用服务端 129 | Response response = Client.execute(request); 130 | 131 | System.out.println(JSON.toJSONString(response)); 132 | } 133 | 134 | /** 135 | * HTTP POST 字符串 136 | * 137 | * @throws Exception 138 | */ 139 | @Test 140 | public void postString() throws Exception { 141 | //请求path 142 | String path = "/poststring"; 143 | //Body内容 144 | String body = "demo string body content"; 145 | 146 | Map headers = new HashMap(); 147 | //(必填)根据期望的Response内容类型设置 148 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 149 | //(可选)Body MD5,服务端会校验Body内容是否被篡改,建议Body非Form表单时添加此Header 150 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.base64AndMD5(body)); 151 | //(POST/PUT请求必选)请求Body内容格式 152 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT); 153 | 154 | headers.put("a-header1", "header1Value"); 155 | headers.put("b-header2", "header2Value"); 156 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 157 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 158 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 159 | 160 | 161 | Request request = new Request(Method.POST_STRING, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 162 | request.setHeaders(headers); 163 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 164 | 165 | //请求的query 166 | Map querys = new HashMap(); 167 | querys.put("a-query1", "query1Value"); 168 | querys.put("b-query2", "query2Value"); 169 | request.setQuerys(querys); 170 | 171 | request.setStringBody(body); 172 | 173 | //调用服务端 174 | Response response = Client.execute(request); 175 | 176 | System.out.println(JSON.toJSONString(response)); 177 | } 178 | 179 | /** 180 | * HTTP POST 字节数组 181 | * 182 | * @throws Exception 183 | */ 184 | @Test 185 | public void postBytes() throws Exception { 186 | //请求path 187 | String path = "/poststream"; 188 | //Body内容 189 | byte[] bytesBody = "demo bytes body content".getBytes(Constants.ENCODING); 190 | 191 | Map headers = new HashMap(); 192 | //(必填)根据期望的Response内容类型设置 193 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 194 | //(可选)Body MD5,服务端会校验Body内容是否被篡改,建议Body非Form表单时添加此Header 195 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.base64AndMD5(bytesBody)); 196 | //(POST/PUT请求必选)请求Body内容格式 197 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT); 198 | 199 | headers.put("a-header1", "header1Value"); 200 | headers.put("b-header2", "header2Value"); 201 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 202 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 203 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 204 | 205 | Request request = new Request(Method.POST_BYTES, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 206 | request.setHeaders(headers); 207 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 208 | 209 | //请求的query 210 | Map querys = new HashMap(); 211 | querys.put("a-query1", "query1Value"); 212 | querys.put("b-query2", "query2Value"); 213 | request.setQuerys(querys); 214 | 215 | request.setBytesBody(bytesBody); 216 | 217 | //调用服务端 218 | Response response = Client.execute(request); 219 | 220 | System.out.println(JSON.toJSONString(response)); 221 | } 222 | 223 | /** 224 | * HTTP PUT 字符串 225 | * 226 | * @throws Exception 227 | */ 228 | @Test 229 | public void putString() throws Exception { 230 | //请求path 231 | String path = "/putstring"; 232 | //Body内容 233 | String body = "demo string body content"; 234 | 235 | Map headers = new HashMap(); 236 | //(必填)根据期望的Response内容类型设置 237 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 238 | //(可选)Body MD5,服务端会校验Body内容是否被篡改,建议Body非Form表单时添加此Header 239 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.base64AndMD5(body)); 240 | //(POST/PUT请求必选)请求Body内容格式 241 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT); 242 | 243 | headers.put("a-header1", "header1Value"); 244 | headers.put("b-header2", "header2Value"); 245 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 246 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 247 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 248 | 249 | Request request = new Request(Method.POST_STRING, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 250 | request.setHeaders(headers); 251 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 252 | request.setStringBody(body); 253 | 254 | //调用服务端 255 | Response response = Client.execute(request); 256 | 257 | System.out.println(JSON.toJSONString(response)); 258 | } 259 | 260 | /** 261 | * HTTP PUT 字节数组 262 | * 263 | * @throws Exception 264 | */ 265 | @Test 266 | public void putBytesBody() throws Exception { 267 | //请求path 268 | String path = "/putstream"; 269 | //Body内容 270 | byte[] bytesBody = "demo bytes body content".getBytes(Constants.ENCODING); 271 | 272 | Map headers = new HashMap(); 273 | //(必填)根据期望的Response内容类型设置 274 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 275 | //(可选)Body MD5,服务端会校验Body内容是否被篡改,建议Body非Form表单时添加此Header 276 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_MD5, MessageDigestUtil.base64AndMD5(bytesBody)); 277 | //(POST/PUT请求必选)请求Body内容格式 278 | headers.put(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_TEXT); 279 | headers.put("a-header1", "header1Value"); 280 | headers.put("b-header2", "header2Value"); 281 | CUSTOM_HEADERS_TO_SIGN_PREFIX.clear(); 282 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header1"); 283 | CUSTOM_HEADERS_TO_SIGN_PREFIX.add("a-header2"); 284 | 285 | Request request = new Request(Method.PUT_BYTES, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 286 | request.setHeaders(headers); 287 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 288 | request.setBytesBody(bytesBody); 289 | 290 | //调用服务端 291 | Response response = Client.execute(request); 292 | 293 | System.out.println(JSON.toJSONString(response)); 294 | } 295 | 296 | /** 297 | * HTTP DELETE 298 | * 299 | * @throws Exception 300 | */ 301 | @Test 302 | public void delete() throws Exception { 303 | //请求path 304 | String path = "/delete"; 305 | 306 | Map headers = new HashMap(); 307 | //(必填)根据期望的Response内容类型设置 308 | headers.put(HttpHeader.HTTP_HEADER_ACCEPT, "application/json"); 309 | 310 | Request request = new Request(Method.DELETE, HttpSchema.HTTP + HOST, path, APP_KEY, APP_SECRET, Constants.DEFAULT_TIMEOUT); 311 | request.setHeaders(headers); 312 | request.setSignHeaderPrefixList(CUSTOM_HEADERS_TO_SIGN_PREFIX); 313 | 314 | //调用服务端 315 | Response response = Client.execute(request); 316 | 317 | System.out.println(JSON.toJSONString(response)); 318 | } 319 | 320 | 321 | } 322 | --------------------------------------------------------------------------------