近期在处理http请求时,遇到的问题,现在记录一下;
平时我们使用postman或者 soapUI等一些接口测试工具请求rest接口时,请求头的Content-Type 一般都是application/json,
这个其实是比较通用的请求方式,但是有时候我们在网上拷贝的httpUtil工具类使用的请求头里却是另一种content-type,
例如下面这段代码:创建HttpPost对象,然后把map对象放到httpPost的entity里;
// 创建httpPost对象
HttpPost httpPost = new HttpPost(httpUrl);
// 创建参数队列
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
for (String key : maps.keySet()) {
nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
}
try {
// 这里的new UrlEncodedFormEntity默认的请求头里contentType就是application/x-www-form-urlencoded
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getStackTrace());
System.out.println(e.getMessage());
}
// ===================================================================
// 下面贴出UrlEncodedFormEntity的有参构造源码
/**
* Constructs a new {@link UrlEncodedFormEntity} with the list
* of parameters in the specified encoding.
*
* @param parameters list of name/value pairs
* @param charset encoding the name/value pairs be encoded with
* @throws UnsupportedEncodingException if the encoding isn't supported
*/
public UrlEncodedFormEntity (
final List <? extends NameValuePair> parameters,
final String charset) throws UnsupportedEncodingException {
super(URLEncodedUtils.format(parameters,
charset != null ? charset : HTTP.DEF_CONTENT_CHARSET.name()),
ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset));
}
// ===================================================
// 如下是 URLEncodedUtils.CONTENT_TYPE 的值;
public class URLEncodedUtils {
/**
* The default HTML form content type.
*/
public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
}
这段适用普通的Post请求,但是当我们服务端入参是json的话,使用这个普通的post请求就会导致服务端解析失败;
有几种解决方法:
第一种是修改httpPost.setEntity里的参数;例如:
httpPost.setEntity(new StringEntity(JSONObject.toJSONString(paramMap), ContentType.create("application/json", "utf-8")));
第二种是:
我们直接在接收参数的时候,入参改为com.alibaba.fastjson.JSONObject,或者直接是json字符串;例:
//添加请求头
httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
//这里的params是JSONObject类型;如果已经是json字符串的话,直接使用即可;
httpPost.setEntity(new StringEntity(params.toJSONString(),"utf-8"));
--------------------------------------------------------------------------
接下来分享一下我这边目前使用的httpUtil工具类:
package com.wxy.mq.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
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.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
/**
* Http工具类
*
* @author wangxinyang
* @Date 2018年8月30日
*/
public class HttpUtils {
private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(6000).setConnectTimeout(6000)
.setConnectionRequestTimeout(15000).build();
/** 需要较长时间读取返回时的配置 */
private static RequestConfig requestConfigWait = RequestConfig.custom().setSocketTimeout(20 * 1000).setConnectTimeout(6000)
.setConnectionRequestTimeout(15000).build();
/**
* @param httpGet
* @param bol 是否需要较长时间读取返回值 true : 是 / false : 否
* @return
*/
public static String sendHttpGet(HttpGet httpGet, boolean bol) {
if (bol == false) {
sendHttpGet(httpGet);
}
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
httpGet.setConfig(requestConfigWait);
// 执行请求
response = httpClient.execute(httpGet);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}
public static String sendHttpGet(HttpGet httpGet) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
httpGet.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpGet);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}
/**
* 发送普通 post请求
*
* @param httpUrl
* 地址
* @param maps
* 参数
*/
public static String sendHttpPost(String httpUrl, Map<String, String> maps) {
HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
// 创建参数队列
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
for (String key : maps.keySet()) {
nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getStackTrace());
System.out.println(e.getMessage());
}
return sendHttpPost(httpPost);
}
public static String sendHttpPost(HttpPost httpPost) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
httpPost.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpPost);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getStackTrace());
System.out.println(e.getMessage());
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}
/**
* 发送Get请求Https
*
* @param httpPost
* @return
*/
public static String sendHttpsGet(HttpGet httpGet) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
// 创建默认的httpClient实例.
PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader
.load(new URL(httpGet.getURI().toString()));
DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();
httpGet.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpGet);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}
/**
* 请求参数为json字符串;
* @param url
* @param params
* @return
*/
public static String doPost(String url, JSONObject params){
String strResult = "";
// 1. 获取默认的client实例
CloseableHttpClient client = HttpClients.createDefault();
// 2. 创建httppost实例
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); //添加请求头
try {
httpPost.setEntity(new StringEntity(params.toJSONString(),"utf-8"));
CloseableHttpResponse resp = client.execute(httpPost);
try {
// 7. 获取响应entity
HttpEntity respEntity = resp.getEntity();
strResult = EntityUtils.toString(respEntity, "UTF-8");
} finally {
resp.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return strResult;
}
}
这里用到了com.alibaba.fastjson,httpclient,httpcore的依赖,
在pom.xml中添加:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.8</version>
</dependency>
end;