通过JDK网络类Java.net.HttpURLConnection
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
比较原始的一种调用做法。
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import com.fasterxml.jackson.databind.ObjectMapper;
public final class ConnectUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
private ConnectUtil() {
}
public <T, R> R doPost(String httpUrl, T params, Class<R> returnType, String token) throws IOException {
StringBuilder result = new StringBuilder();
//连接
HttpURLConnection connection = null;
OutputStream os = null;
InputStream is = null;
BufferedReader br = null;
try {
//创建连接对象
URL url = new URL(httpUrl);
//创建连接
connection = (HttpURLConnection) url.openConnection();
//设置请求方法
connection.setRequestMethod("POST");
//设置连接超时时间(必须)
connection.setConnectTimeout(15000);
//设置读取超时时间(必须)
connection.setReadTimeout(15000);
//DoOutput设置是否向httpUrlConnection输出,DoInput设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
//设置是否可读取
connection.setDoOutput(true);
connection.setDoInput(true);
//设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
//(可选)设置请求头鉴权信息
if (token != null && !"".equals(token)) {
connection.addRequestProperty("Authorization", token);
}
// 建立实际的连接
connection.connect();
//拼装参数
if (null != params) {
String param = objectMapper.writeValueAsString(params);
//设置参数
os = connection.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
//拼装参数
writer.write(param);
writer.flush();
//另一种方式
//设置参数
//os = connection.getOutputStream();
//拼装参数
//os.write(param.getBytes("UTF-8"));
}
//设置权限
//设置请求头等
//开启连接
//connection.connect();
//读取响应
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
if (null != is) {
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String temp = null;
while (null != (temp = br.readLine())) {
result.append(temp);
result.append("\r\n");
}
}
}
} finally {
//关闭连接
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭连接
connection.disconnect();
}
R object = objectMapper.readValue(result.toString(), returnType);
return object;
}
/**
* Http get请求
*
* @param httpUrl 连接
* @return 响应数据
*/
public static String doGet(String httpUrl, String param, String token) {
//链接
HttpURLConnection connection = null;
InputStream is = null;
BufferedReader br = null;
StringBuffer result = new StringBuffer();
try {
//创建连接
if (param != null && !"".equals(param)) {
httpUrl = httpUrl + "?" + param;
}
URL url = new URL(httpUrl);
connection = (HttpURLConnection) url.openConnection();
//设置请求方式
connection.setRequestMethod("GET");
//设置连接超时时间
connection.setReadTimeout(15000);
//(可选)设置请求头鉴权信息
if (token != null && !"".equals(token)) {
connection.addRequestProperty("Authorization", token);
}
//开始连接
connection.connect();
//请求参数(这里不要把参数放到outputStream中,会自动变成post请求)
/* if (param != null && !"".equals(param)) {
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write(param);
writer.flush();
}*/
//获取响应数据
if (connection.getResponseCode() == 200) {
//获取返回的数据
is = connection.getInputStream();
if (null != is) {
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String temp = null;
while (null != (temp = br.readLine())) {
result.append(temp);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭远程连接
connection.disconnect();
}
return result.toString();
}
}
通过Apache Common封装好的HttpClient请求
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public final class HttpUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
private static HttpClient httpClient = new HttpClient();
private HttpUtil() {
}
static {
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//1.设置HttpClient参数
//连接超时时间
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
//读写超时时间
httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT, 5000);
}
/**
* @param url
* @param param 这里使用泛型和Object都是一样的,不影响
* @return
* @throws IOException
* @throws IllegalAccessException
*/
public static String doGet(String url, Object param, String token) throws IOException, IllegalAccessException {
//2.生成GetMethod对象并设置参数
if (Objects.nonNull(param)) {
List<String> params = new ArrayList<>();
Class<?> clazz = param.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
Object o = declaredField.get(param);
if (declaredField.getType().equals(String.class)) {
//这里拼接的时候注意要使用URL编码
String s = (String) declaredField.get(param);
s = URLEncoder.encode(s, "UTF-8");
o = s;
}
params.add(declaredField.getName() + "=" + o);
}
String paramStr = params.stream().collect(Collectors.joining("&"));
url = url + "?" + paramStr;
}
GetMethod getMethod = new GetMethod(url);
//设置get请求超时为5秒
//getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
//设置请求重试处理,用的是默认的重试处理:请求三次
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
//设置请求头
//(可选)设置请求头鉴权信息
if (token != null && !"".equals(token)) {
getMethod.addRequestHeader("Authorization", token);
}
String response = "";
//3.执行HTTP GET 请求
try {
int statusCode = httpClient.executeMethod(getMethod);
//4.判断访问的状态码
if (statusCode != HttpStatus.SC_OK) {
System.out.println("请求出错:" + getMethod.getStatusLine());
return null;
}
//5.处理HTTP响应内容
//HTTP响应头部信息,这里简单打印
Header[] headers = getMethod.getResponseHeaders();
for (Header h : headers) {
System.out.println(h.getName() + "---------------" + h.getValue());
}
//读取HTTP响应内容,这里简单打印网页内容
//读取为字节数组
byte[] responseBody = getMethod.getResponseBody();
response = new String(responseBody, "UTF-8");
//读取为InputStream,在网页内容数据量大时候推荐使用
//InputStream response = getMethod.getResponseBodyAsStream();
} finally {
//6.释放连接
getMethod.releaseConnection();
}
return response;
}
public static <R> R doPost(String httpUrl, Object param, Class<R> returnType) throws IOException {
String json = "";
if (Objects.nonNull(param)) {
json = objectMapper.writeValueAsString(param);
}
PostMethod postMethod = new PostMethod(httpUrl);
//postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
//这里accept表示的是可接收的返回值类型,一般设置为*/*
//如果不设置将会使用浏览器的默认值,不过一般都会支持*/*,为了保险还是加上吧
//如果返回值类型不匹配则会提示No content to map due to end-of-input,可以尝试设置text/html试一下
postMethod.addRequestHeader("accept", "*/*");
//HTTP1.1协议默认使用Keep-Alive,如果是1.0的HTTP协议需要设置
//Keep-Alive发送请求时性能更高
postMethod.addRequestHeader("connection", "Keep-Alive");
//告诉服务器请求的媒体类型,目前基本都是用json,所以设置json格式传送
//即使不设置也是application/json,可能由于下面用到了StringRequestEntity、
//但是我注释了下面的StringRequestEntity还是application/json,目前搞不懂,所以暂时这么设置了
postMethod.addRequestHeader("Content-Type", "application/json;charset=UTF-8");
//设置下面这个Header,没什么用,注释了也能正常访问
//postMethod.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
//添加请求参数
RequestEntity se = new StringRequestEntity(json, "application/json", "UTF-8");
postMethod.setRequestEntity(se);
StringBuilder res = new StringBuilder();
try {
//必须要UTF-8,不然中文乱码
//3. 执行方法
int code = httpClient.executeMethod(postMethod);
//4. 处理状态码
if (code != 200) {
System.out.println("请求出错:" + postMethod.getStatusLine());
//这里最好是抛出一个异常
return null;
}
//5. 正常,进行处理
//方法1:拿到字节数据后使用new String
byte[] responseBody = postMethod.getResponseBody();
res.append(new String(responseBody, "UTF-8"));
System.out.println(res.toString());
//方法2:逐行读,在网页内容数据量大时候推荐使用
/*InputStream responseStream = postMethod.getResponseBodyAsStream();
InputStreamReader reader = new InputStreamReader(responseStream,"UTF-8");
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
while((line = bufferedReader.readLine()) !=null){
res.append(line).append("\r\n");
}*/
System.out.println(res.toString());
} finally {
//6. 释放连接
postMethod.releaseConnection();
}
R r = objectMapper.readValue(res.toString(), returnType);
return r;
}
}
通过Spring-RestTemplate
Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
<!--包含了RestTemplate-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--CloseableHttpClient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
public final class RestTemplateUtil {
private RestTemplateUtil() {
}
//如果是spring的web项目, 只需要注入即可,无需手动new
//@Autowired
// private RestTemplate restTemplate;
private static RestTemplate restTemplate = new RestTemplate();
static {
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory
= new HttpComponentsClientHttpRequestFactory();
//连接超时时间
httpComponentsClientHttpRequestFactory.setConnectTimeout(10000);
//读取超时时间
httpComponentsClientHttpRequestFactory.setReadTimeout(10000);
restTemplate.setRequestFactory(httpComponentsClientHttpRequestFactory);
}
public static String doGet(String url) {
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
return forEntity.getBody();
}
public static String doPost(String url, Map<String, Object> params) {
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, params, String.class);
return responseEntity.getBody();
}
}
通过Apache封装好的CloseableHttpClient
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
<!--CloseableHttpClient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public final class HttpClientUtil {
private HttpClientUtil() {
}
private static ObjectMapper objectMapper = new ObjectMapper();
private static HttpClient httpClient;
static {
//设置客户端,如果无参数设置可以不用调setDefaultRequestConfig方法
RequestConfig build = RequestConfig.custom()
.setSocketTimeout(6000)
.setConnectTimeout(6000).build();
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(build).build();
}
/**
* 以post方式调用第三方接口
*
* @param url
* @param param
* @return
*/
public <R> R doPost(String url, Object param, Class<R> returnType, String token) throws IOException {
String json = "";
if (Objects.nonNull(param)) {
json = objectMapper.writeValueAsString(param);
}
HttpPost httpPost = new HttpPost(url);
if (null != token && !token.equals("")) {
//Authorization的header头,用于token验证使用
httpPost.addHeader("Authorization", token);
}
httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
StringBuilder res = new StringBuilder();
//设置编码UTF-8,不然会出现问号
StringEntity se = new StringEntity(json, "UTF-8");
//经过验证,无用
//se.setContentEncoding("UTF-8");
//发送json数据需要设置contentType,否则提供者端提示请求类型not support
se.setContentType("application/json");
//设置请求参数
httpPost.setEntity(se);
//客户端设置了默认值,局部就无需再设置,除非有额外要求
/*RequestConfig build = RequestConfig.custom().setSocketTimeout(40000).setConnectTimeout(40000).build();
httpPost.setConfig(build);*/
HttpResponse response = httpClient.execute(httpPost);
if (Objects.nonNull(response) && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//返回json格式
res.append(EntityUtils.toString(response.getEntity(), "UTF-8"));
}
//这里不需要手动调用httpClient.close(),因为EntityUtils.toString方法中会自动调用输入流的close方法
//直接调用httpClient.close()反而会再第二次调用时出现Collection Pool shut down的错误
R r = objectMapper.readValue(res.toString(), returnType);
return r;
}
/**
* 以get方式调用第三方接口
*
* @param url
* @return
*/
public static String doGet(String url, Object param, String token) throws IOException, IllegalAccessException {
//拼接url参数
if (Objects.nonNull(param)) {
List<String> params = new ArrayList<>();
Class<?> clazz = param.getClass();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
Object o = declaredField.get(param);
if (declaredField.getType().equals(String.class)) {
//这里拼接的时候注意要使用URL编码
String s = (String) declaredField.get(param);
s = URLEncoder.encode(s);
o = s;
}
params.add(declaredField.getName() + "=" + o);
}
String paramStr = params.stream().collect(Collectors.joining("&"));
url = url + "?" + paramStr;
}
//创建HttpClient对象
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
if (null != token && !token.equals("")) {
//api_gateway_auth_token自定义header头,用于token验证使用
httpGet.addHeader("Authorization", token);
}
//httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
HttpResponse response = httpClient.execute(httpGet);
StringBuilder res = new StringBuilder();
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//返回json格式
res.append(EntityUtils.toString(response.getEntity()));
}
return res.toString();
}
}