HTTP的GET恳求RUL保存字处理方法(多个解决方案)ITeye - 乐橙lc8

HTTP的GET恳求RUL保存字处理方法(多个解决方案)ITeye

2019年04月03日08时39分47秒 | 作者: 宇航 | 标签: 恳求,处理,效劳 | 浏览: 2128

最近花了一天在处理一个出产环境问题,

客户端(发送数据):经过HTTP的GET恳求,传输参数中带有“+”加号。

效劳端(接纳数据):“+”加号变为空格。

由于是签名数据,导致效劳端验证签名不经过,算比较严重的问题。

 

解决问题示例(多个解决计划):

示例1(恳求url的参数选用直接组装的办法)(失利):

package com.qhfax.test;
import com.qhfax.common.util.HttpClientUtil;
public class HttpGetTest1 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 //恳求参数
 String queryString = "?sign="+sign;
 //URI编码处理
 String getUrl = serviceUrl + queryString;
 String response = HttpClientUtil.get(getUrl);
 System.out.println(response);

效劳端接纳的的值为:abcde fghij

效劳端回来:false

 

示例2(运用URIUtil.encodeQuery办法对恳求参数进行编码)(失利)

package com.qhfax.test;
import org.apache.commons.httpclient.util.URIUtil;
import com.qhfax.common.util.HttpClientUtil;
public class HttpGetTest2 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 //恳求参数
 String queryString = "?sign="+sign;
 //URI编码处理
 String getUrl = serviceUrl + URIUtil.encodeQuery(queryString);
 String response = HttpClientUtil.get(getUrl);
 System.out.println(response);

 

效劳端接纳的的值为:abcde fghij

效劳端回来:false

 

示例3(对URL保存字符进行ASCII码转化,把“+”替换为“%2B”)(成功)

package com.qhfax.test;
import com.qhfax.common.util.HttpClientUtil;
public class HttpGetTest3 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //把“+”替换为“%2B”
 sign = sign.replaceAll("\\+", "%2B");
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 //恳求参数
 String queryString = "?sign="+sign;
 //URI编码处理
 String getUrl = serviceUrl + queryString;
 String response = HttpClientUtil.get(getUrl);
 System.out.println(response);

效劳端接纳的的值为:abcde+fghij

效劳端回来:true

 

示例4(依据示例3,运用java自带的URLEncoder.encode办法对参数进行编码)(成功)

package com.qhfax.test;
import com.qhfax.common.util.HttpClientUtil;
public class HttpGetTest4 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //运用java自带的URLEncoder.encode办法对参数进行编码
 sign = java.net.URLEncoder.encode(sign);
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 //恳求参数
 String queryString = "?sign="+sign;
 //URI编码处理
 String getUrl = serviceUrl + queryString;
 String response = HttpClientUtil.get(getUrl);
 System.out.println(response);

效劳端接纳的的值为:abcde+fghij

效劳端回来:true

 

示例5(依据示例3、4,运用httpClient包中的UrlEncodedFormEntity类,详见上面的HttpClientUtil东西类)(终究版别)(成功)

package com.qhfax.test;
import java.util.HashMap;
import java.util.Map;
import com.qhfax.common.util.HttpClientUtil;
public class HttpGetTest5 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 //恳求参数
 Map String, String params = new HashMap String, String 
 params.put("sign", sign);
 String response = HttpClientUtil.get(serviceUrl, params);
 System.out.println(response);

效劳端接纳的的值为:abcde+fghij

效劳端回来:true

 

示例6(换一种办法,也是Httpclientjar包中的类,运用Request.Get)(成功)

 

package com.qhfax.test;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.utils.URIBuilder;
public class HttpGetTest6 {
 public static void main(String[] args) throws Exception {
 //签名
 String sign = "abcde+fghij";
 //恳求的效劳地址
 String serviceUrl = "http://localhost:8080/qhfaxWeb/httpGetTest/paramTest";//恳求途径
 String result = Request.Get(
 new URIBuilder(serviceUrl)
 .addParameter("sign", sign)
 .build())
 .connectTimeout(5000)
 .socketTimeout(5000).execute()
 .returnContent().asString();
 System.out.println(result);

效劳端接纳的的值为:abcde+fghij

效劳端回来:true

 

总结:

1、找到问题:

依据示例1中问题,HTTP的GET恳求URL中有包含“! * ( ) ; : @ =+ $ , / ? # [ ]”的保存字符,需要对它们进行转码,这是解决问题思路的第一步,找到原因。

2、验证解决计划:

依据示例3中的处理办法,将把“+”替换为“%2B”,验证处理办法是正确的。这是解决问题思路的第二步,测验计划,验证能否解决问题。

3、完善解决计划:

示例4、5、6是依据示例3的完善,运用现有的东西类,更好更全面的处理问题。这是解决问题思路的第三步,完善解决计划。

(补白:示例2中的URIUtil.encodeQuery是有编码作用的,仅仅如同对“+”不会编码,这个点在我处理时有点误导了我的思路)

 

演示预备前需预备的代码(注:SpringMVC结构环境需自己树立,httpclient的jar版别为4.4.1):

客户端:

HttpClientUtil东西类代码如下:

package com.qhfax.common.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 * @Description: 运用httpclient4.0以上组件
 * @author : huangaming
 * @date : 2017年 上午11:49:48
@SuppressWarnings("deprecation")
public class HttpClientUtil {
 private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
 public static String postJsonString(String uri, String jsonStr) {
 String result = "";
 Charset charset = Charset.forName("UTF-8");
 // 实例化http客户端
 HttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost post = null;
 try {
 post = new HttpPost(uri);
 StringEntity stringEntity = new StringEntity(jsonStr, ContentType.create("application/json", charset));
 // 实例化post提交办法
 post.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
 // 将参数参加post恳求体中
 post.setEntity(stringEntity);
 // 履行post恳求并得到回来目标 [ 到这一步咱们的恳求就开端了 ]
 HttpResponse resp = httpClient.execute(post);
 // 解析回来恳求成果
 HttpEntity entity = resp.getEntity();
 result = IOUtils.toString(entity.getContent(), charset);
 logger.info("[postJsonString response:{}]", result);
 // 输出成果
 } catch (Exception exception) {
 logger.error("postJsonString exception", exception);
 } finally {
 if (post != null) {
 post.releaseConnection();
 return result;
 public static final int connTimeout=10000;//衔接超时参数
 public static final int readTimeout=10000;//读取超时参数
 public static final String charset="UTF-8";//字符编码
 private static HttpClient client = null;
 static {
 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
 cm.setMaxTotal(128);
 cm.setDefaultMaxPerRoute(128);
 client = HttpClients.custom().setConnectionManager(cm).build();
 public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception{
 return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
 public static String postParameters(String url, String parameterStr,String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception{
 return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
 public static String postParameters(String url, Map String, String params) throws ConnectTimeoutException, 
 SocketTimeoutException, Exception {
 return postForm(url, params, null, connTimeout, readTimeout);
 public static String postParameters(String url, Map String, String params, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException, 
 SocketTimeoutException, Exception {
 return postForm(url, params, null, connTimeout, readTimeout);
 public static String get(String url) throws Exception { 
 return get(url, charset, connTimeout, readTimeout); 
 public static String get(String url, String charset) throws Exception { 
 return get(url, charset, connTimeout, readTimeout); 
 public static String get(String url, Map String, String params) throws Exception { 
 return get(url, params, charset, connTimeout, readTimeout); 
 /** 
 * 发送一个 Post 恳求, 运用指定的字符集编码. 
 * @param url 
 * @param body RequestBody 
 * @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1 b=2 c=3
 * @param charset 编码 
 * @param connTimeout 树立链接超时时刻,毫秒. 
 * @param readTimeout 呼应超时时刻,毫秒. 
 * @return ResponseBody, 运用指定的字符集编码. 
 * @throws ConnectTimeoutException 树立链接超时反常 
 * @throws SocketTimeoutException 呼应超时 
 * @throws Exception 
 public static String post(String url, String body, String mimeType,String charset, Integer connTimeout, Integer readTimeout) 
 throws ConnectTimeoutException, SocketTimeoutException, Exception {
 HttpClient client = null;
 HttpPost post = new HttpPost(url);
 String result = "";
 try {
 if (StringUtils.isNotBlank(body)) {
 HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
 post.setEntity(entity);
 // 设置参数
 Builder customReqConf = RequestConfig.custom();
 if (connTimeout != null) {
 customReqConf.setConnectTimeout(connTimeout);
 if (readTimeout != null) {
 customReqConf.setSocketTimeout(readTimeout);
 post.setConfig(customReqConf.build());
 HttpResponse res;
 if (url.startsWith("https")) {
 // 履行 Https 恳求.
 client = createSSLInsecureClient();
 res = client.execute(post);
 } else {
 // 履行 Http 恳求.
 client = HttpClientUtil.client;
 res = client.execute(post);
 result = IOUtils.toString(res.getEntity().getContent(), charset);
 } finally {
 post.releaseConnection();
 if (url.startsWith("https") client != null client instanceof CloseableHttpClient) {
 ((CloseableHttpClient) client).close();
 return result;                          
			
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表乐橙lc8立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章

阅读排行

  • 1

    discuz 单点登录 ucenterITeye

    项目,下载,文件
  • 2
  • 3

    spring+mybatis装备ITeye

    装备,一下,需求
  • 4

    单例形式-线程安全ITeye

    线程,安全,形式
  • 5

    java数据存储ITeye

    数据,存储,分配
  • 6
  • 7

    httpclient 恳求 post、getITeye

    恳求,使用,进行
  • 8

    Redis的耐久化机制ITeye

    耐久,方法,内存
  • 9

    java注解用法ITeye

    注解,注释,运用
  • 10