基於springboot實現RestTemplate、okhttp和HttpClient
一、HttpClient:
代碼複雜,還得操心資源回收等。代碼很複雜,冗餘代碼多,不建議直接使用。
1 添加依賴
<properties>
<httpclient.version>4.5.5</httpclient.version>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- springboot的web和test啓動庫 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- apache httpclient組件 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 跳過單元測試 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
2 編寫spring-boot啓動類
/**
* Description: springboot啓動類
*
* @author JourWon
* @date Created on 2018年4月19日
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3 編寫get和post請求測試controller
/**
* Description: get和post請求測試controller
*
* @author JourWon
* @date Created on 2018年4月19日
*/
@RestController
@RequestMapping("/hello")
public class HelloWorldController {
@GetMapping("/get")
public String get() throws InterruptedException {
return "get無參請求成功";
}
@GetMapping("/getWithParam")
public String getWithParam(@RequestParam String message) {
return "get帶參請求成功,參數message: " + message;
}
@PostMapping("/post")
public String post(@RequestHeader("User-Agent") String userAgent,
@RequestHeader("Accept") String accept,
@RequestHeader("Accept-Language") String acceptLanguage,
@RequestHeader("Accept-Encoding") String acceptEncoding,
@RequestHeader("Cookie") String cookie,
@RequestHeader("Connection") String conn) {
// 打印請求頭信息
System.out.println("Cookie = " + cookie);
System.out.println("Connection = " + conn);
System.out.println("Accept = " + accept);
System.out.println("Accept-Language = " + acceptLanguage);
System.out.println("Accept-Encoding = " + acceptEncoding);
System.out.println("User-Agent = " + userAgent);
return "post無參請求成功";
}
@PostMapping("/postWithParam")
public String postWithParam(@RequestParam String code, @RequestParam String message) {
return "post帶參請求成功,參數code: " + code + ",參數message: " + message;
}
}
4 創建httpClient響應結果對象
/**
* Description: 封裝httpClient響應結果
*
* @author JourWon
* @date Created on 2018年4月19日
*/
public class HttpClientResult implements Serializable {
/**
* 響應狀態碼
*/
private int code;
/**
* 響應數據
*/
private String content;
}
5 重點,編寫httpclient工具類
無連接池
/**
* Description: httpClient工具類
*
* @author JourWon
* @date Created on 2018年4月19日
*/
public class HttpClientUtils {
// 編碼格式。發送編碼格式統一用UTF-8
private static final String ENCODING = "UTF-8";
// 設置連接超時時間,單位毫秒。
private static final int CONNECT_TIMEOUT = 6000;
// 請求獲取數據的超時時間(即響應時間),單位毫秒。
private static final int SOCKET_TIMEOUT = 6000;
/**
* 發送get請求;不帶請求頭和請求參數
*
* @param url 請求地址
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url) throws Exception {
return doGet(url, null, null);
}
/**
* 發送get請求;帶請求參數
*
* @param url 請求地址
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url, Map<String, String> params) throws Exception {
return doGet(url, null, params);
}
/**
* 發送get請求;帶請求頭和請求參數
*
* @param url 請求地址
* @param headers 請求頭集合
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
// 創建httpClient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創建訪問的地址
URIBuilder uriBuilder = new URIBuilder(url);
if (params != null) {
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
uriBuilder.setParameter(entry.getKey(), entry.getValue());
}
}
// 創建http對象
HttpGet httpGet = new HttpGet(uriBuilder.build());
/**
* setConnectTimeout:設置連接超時時間,單位毫秒。
* setConnectionRequestTimeout:設置從connect Manager(連接池)獲取Connection
* 超時時間,單位毫秒。這個屬性是新加的屬性,因爲目前版本是可以共享連接池的。
* setSocketTimeout:請求獲取數據的超時時間(即響應時間),單位毫秒。 如果訪問一個接口,多少時間內無法返回數據,就直接放棄此次調用。
*/
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpGet.setConfig(requestConfig);
// 設置請求頭
packageHeader(headers, httpGet);
// 創建httpResponse對象
CloseableHttpResponse httpResponse = null;
try {
// 執行請求並獲得響應結果
return getHttpClientResult(httpResponse, httpClient, httpGet);
} finally {
// 釋放資源
release(httpResponse, httpClient);
}
}
/**
* 發送post請求;不帶請求頭和請求參數
*
* @param url 請求地址
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url) throws Exception {
return doPost(url, null, null);
}
/**
* 發送post請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url, Map<String, String> params) throws Exception {
return doPost(url, null, params);
}
/**
* 發送post請求;帶請求頭和請求參數
*
* @param url 請求地址
* @param headers 請求頭集合
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
// 創建httpClient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 創建http對象
HttpPost httpPost = new HttpPost(url);
/**
* setConnectTimeout:設置連接超時時間,單位毫秒。
* setConnectionRequestTimeout:設置從connect Manager(連接池)獲取Connection
* 超時時間,單位毫秒。這個屬性是新加的屬性,因爲目前版本是可以共享連接池的。
* setSocketTimeout:請求獲取數據的超時時間(即響應時間),單位毫秒。 如果訪問一個接口,多少時間內無法返回數據,就直接放棄此次調用。
*/
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpPost.setConfig(requestConfig);
// 設置請求頭
/*httpPost.setHeader("Cookie", "");
httpPost.setHeader("Connection", "keep-alive");
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
httpPost.setHeader("Accept-Encoding", "gzip, deflate, br");
httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");*/
packageHeader(headers, httpPost);
// 封裝請求參數
packageParam(params, httpPost);
// 創建httpResponse對象
CloseableHttpResponse httpResponse = null;
try {
// 執行請求並獲得響應結果
return getHttpClientResult(httpResponse, httpClient, httpPost);
} finally {
// 釋放資源
release(httpResponse, httpClient);
}
}
/**
* 發送put請求;不帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPut(String url) throws Exception {
return doPut(url);
}
/**
* 發送put請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPut(String url, Map<String, String> params) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPut httpPut = new HttpPut(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpPut.setConfig(requestConfig);
packageParam(params, httpPut);
CloseableHttpResponse httpResponse = null;
try {
return getHttpClientResult(httpResponse, httpClient, httpPut);
} finally {
release(httpResponse, httpClient);
}
}
/**
* 發送delete請求;不帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doDelete(String url) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpDelete httpDelete = new HttpDelete(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpDelete.setConfig(requestConfig);
CloseableHttpResponse httpResponse = null;
try {
return getHttpClientResult(httpResponse, httpClient, httpDelete);
} finally {
release(httpResponse, httpClient);
}
}
/**
* 發送delete請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doDelete(String url, Map<String, String> params) throws Exception {
if (params == null) {
params = new HashMap<String, String>();
}
params.put("_method", "delete");
return doPost(url, params);
}
/**
* Description: 封裝請求頭
* @param params
* @param httpMethod
*/
public static void packageHeader(Map<String, String> params, HttpRequestBase httpMethod) {
// 封裝請求頭
if (params != null) {
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
// 設置到請求頭到HttpRequestBase對象中
httpMethod.setHeader(entry.getKey(), entry.getValue());
}
}
}
/**
* Description: 封裝請求參數
*
* @param params
* @param httpMethod
* @throws UnsupportedEncodingException
*/
public static void packageParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod)
throws UnsupportedEncodingException {
// 封裝請求參數
if (params != null) {
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
// 設置到請求的http對象中
httpMethod.setEntity(new UrlEncodedFormEntity(nvps, ENCODING));
}
}
/**
* Description: 獲得響應結果
*
* @param httpResponse
* @param httpClient
* @param httpMethod
* @return
* @throws Exception
*/
public static HttpClientResult getHttpClientResult(CloseableHttpResponse httpResponse,
CloseableHttpClient httpClient, HttpRequestBase httpMethod) throws Exception {
// 執行請求
httpResponse = httpClient.execute(httpMethod);
// 獲取返回結果
if (httpResponse != null && httpResponse.getStatusLine() != null) {
String content = "";
if (httpResponse.getEntity() != null) {
content = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
}
return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content);
}
return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
/**
* Description: 釋放資源
*
* @param httpResponse
* @param httpClient
* @throws IOException
*/
public static void release(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient) throws IOException {
// 釋放資源
if (httpResponse != null) {
httpResponse.close();
}
if (httpClient != null) {
httpClient.close();
}
}
}
有連接池方式
/**
* Description: httpClient工具類
*
* @author JourWon
* @date Created on 2018年4月19日
*/
public class HttpClientUtils {
// 編碼格式。發送編碼格式統一用UTF-8
private static final String ENCODING = "UTF-8";
// 設置連接超時時間,單位毫秒。
private static final int CONNECT_TIMEOUT = 6000;
// 請求獲取數據的超時時間(即響應時間),單位毫秒。
private static final int SOCKET_TIMEOUT = 6000;
private static PoolingHttpClientConnectionManager cm;
private static void init() {
if (cm == null) {
cm = new PoolingHttpClientConnectionManager();
// 整個連接池最大連接數
cm.setMaxTotal(50);
// 每路由最大連接數,默認值是2
cm.setDefaultMaxPerRoute(5);
}
}
/**
* 通過連接池獲取HttpClient
*
* @return
*/
private static CloseableHttpClient getHttpClient() {
init();
return HttpClients.custom().setConnectionManager(cm).build();
}
/**
* 發送get請求;不帶請求頭和請求參數
*
* @param url 請求地址
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url) throws Exception {
return doGet(url, null, null);
}
/**
* 發送get請求;帶請求參數
*
* @param url 請求地址
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url, Map<String, String> params) throws Exception {
return doGet(url, null, params);
}
/**
* 發送get請求;帶請求頭和請求參數
*
* @param url 請求地址
* @param headers 請求頭集合
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doGet(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
// 創建httpClient對象
CloseableHttpClient httpClient = getHttpClient();
// 創建訪問的地址
URIBuilder uriBuilder = new URIBuilder(url);
if (params != null) {
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
uriBuilder.setParameter(entry.getKey(), entry.getValue());
}
}
// 創建http對象
HttpGet httpGet = new HttpGet(uriBuilder.build());
/**
* setConnectTimeout:設置連接超時時間,單位毫秒。
* setConnectionRequestTimeout:設置從connect Manager(連接池)獲取Connection
* 超時時間,單位毫秒。這個屬性是新加的屬性,因爲目前版本是可以共享連接池的。
* setSocketTimeout:請求獲取數據的超時時間(即響應時間),單位毫秒。 如果訪問一個接口,多少時間內無法返回數據,就直接放棄此次調用。
*/
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpGet.setConfig(requestConfig);
// 設置請求頭
packageHeader(headers, httpGet);
// 創建httpResponse對象
CloseableHttpResponse httpResponse = null;
try {
// 執行請求並獲得響應結果
return getHttpClientResult(httpResponse, httpClient, httpGet);
} finally {
// 釋放資源
release(httpResponse, null);
}
}
/**
* 發送post請求;不帶請求頭和請求參數
*
* @param url 請求地址
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url) throws Exception {
return doPost(url, null, null);
}
/**
* 發送post請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url, Map<String, String> params) throws Exception {
return doPost(url, null, params);
}
/**
* 發送post請求;帶請求頭和請求參數
*
* @param url 請求地址
* @param headers 請求頭集合
* @param params 請求參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params) throws Exception {
// 創建httpClient對象
CloseableHttpClient httpClient = getHttpClient();
// 創建http對象
HttpPost httpPost = new HttpPost(url);
/**
* setConnectTimeout:設置連接超時時間,單位毫秒。
* setConnectionRequestTimeout:設置從connect Manager(連接池)獲取Connection
* 超時時間,單位毫秒。這個屬性是新加的屬性,因爲目前版本是可以共享連接池的。
* setSocketTimeout:請求獲取數據的超時時間(即響應時間),單位毫秒。 如果訪問一個接口,多少時間內無法返回數據,就直接放棄此次調用。
*/
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpPost.setConfig(requestConfig);
// 設置請求頭
/*httpPost.setHeader("Cookie", "");
httpPost.setHeader("Connection", "keep-alive");
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
httpPost.setHeader("Accept-Encoding", "gzip, deflate, br");
httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");*/
packageHeader(headers, httpPost);
// 封裝請求參數
packageParam(params, httpPost);
// 創建httpResponse對象
CloseableHttpResponse httpResponse = null;
try {
// 執行請求並獲得響應結果
return getHttpClientResult(httpResponse, httpClient, httpPost);
} finally {
// 釋放資源
release(httpResponse, null);
}
}
/**
* 發送put請求;不帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPut(String url) throws Exception {
return doPut(url);
}
/**
* 發送put請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doPut(String url, Map<String, String> params) throws Exception {
CloseableHttpClient httpClient = getHttpClient();
HttpPut httpPut = new HttpPut(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpPut.setConfig(requestConfig);
packageParam(params, httpPut);
CloseableHttpResponse httpResponse = null;
try {
return getHttpClientResult(httpResponse, httpClient, httpPut);
} finally {
release(httpResponse, null);
}
}
/**
* 發送delete請求;不帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doDelete(String url) throws Exception {
CloseableHttpClient httpClient = getHttpClient();
HttpDelete httpDelete = new HttpDelete(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpDelete.setConfig(requestConfig);
CloseableHttpResponse httpResponse = null;
try {
return getHttpClientResult(httpResponse, httpClient, httpDelete);
} finally {
release(httpResponse, null);
}
}
/**
* 發送delete請求;帶請求參數
*
* @param url 請求地址
* @param params 參數集合
* @return
* @throws Exception
*/
public static HttpClientResult doDelete(String url, Map<String, String> params) throws Exception {
if (params == null) {
params = new HashMap<String, String>();
}
params.put("_method", "delete");
return doPost(url, params);
}
/**
* Description: 封裝請求頭
* @param params
* @param httpMethod
*/
public static void packageHeader(Map<String, String> params, HttpRequestBase httpMethod) {
// 封裝請求頭
if (params != null) {
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
// 設置到請求頭到HttpRequestBase對象中
httpMethod.setHeader(entry.getKey(), entry.getValue());
}
}
}
/**
* Description: 封裝請求參數
*
* @param params
* @param httpMethod
* @throws UnsupportedEncodingException
*/
public static void packageParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod)
throws UnsupportedEncodingException {
// 封裝請求參數
if (params != null) {
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
Set<Entry<String, String>> entrySet = params.entrySet();
for (Entry<String, String> entry : entrySet) {
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
// 設置到請求的http對象中
httpMethod.setEntity(new UrlEncodedFormEntity(nvps, ENCODING));
}
}
/**
* Description: 獲得響應結果
*
* @param httpResponse
* @param httpClient
* @param httpMethod
* @return
* @throws Exception
*/
public static HttpClientResult getHttpClientResult(CloseableHttpResponse httpResponse,
CloseableHttpClient httpClient, HttpRequestBase httpMethod) throws Exception {
// 執行請求
httpResponse = httpClient.execute(httpMethod);
// 獲取返回結果
if (httpResponse != null && httpResponse.getStatusLine() != null) {
String content = "";
if (httpResponse.getEntity() != null) {
content = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
}
return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content);
}
return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
/**
* Description: 釋放資源
*
* @param httpResponse
* @param httpClient
* @throws IOException
*/
public static void release(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient) throws IOException {
// 釋放資源
if (httpResponse != null) {
httpResponse.close();
}
if (httpClient != null) {
httpClient.close();
}
}
}
6 啓動spring-boot,測試get、post請求
/**
* Description: HttpClientUtils工具類測試
*
* @author JourWon
* @date Created on 2018年4月19日
*/
public class HttpClientUtilsTest {
/**
* Description: 測試get無參請求
*
* @throws Exception
*/
@Test
public void testGet() throws Exception {
HttpClientResult result = HttpClientUtils.doGet("http://127.0.0.1:8080/hello/get");
System.out.println(result);
}
/**
* Description: 測試get帶參請求
*
* @throws Exception
*/
@Test
public void testGetWithParam() throws Exception {
Map<String, String> params = new HashMap<String, String>();
params.put("message", "helloworld");
HttpClientResult result = HttpClientUtils.doGet("http://127.0.0.1:8080/hello/getWithParam", params);
System.out.println(result);
}
/**
* Description: 測試post帶請求頭不帶請求參數
*
* @throws Exception
*/
@Test
public void testPost() throws Exception {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Cookie", "123");
headers.put("Connection", "keep-alive");
headers.put("Accept", "application/json");
headers.put("Accept-Language", "zh-CN,zh;q=0.9");
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
HttpClientResult result = HttpClientUtils.doPost("http://127.0.0.1:8080/hello/post", headers, null);
System.out.println(result);
}
/**
* Description: 測試post帶參請求
*
* @throws Exception
*/
@Test
public void testPostWithParam() throws Exception {
Map<String, String> params = new HashMap<String, String>();
params.put("code", "0");
params.put("message", "helloworld");
HttpClientResult result = HttpClientUtils.doPost("http://127.0.0.1:8080/hello/postWithParam", params);
System.out.println(result);
}
}
二、RestTemplate:
是 Spring 提供的用於訪問Rest服務的客戶端, RestTemplate 提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。
引入jar包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
添加初始化配置(也可以不配,有默認的)–注意RestTemplate只有初始化配置,沒有什麼連接池
package com.itunion.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApiConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();//默認的是JDK提供http連接,需要的話可以//通過setRequestFactory方法替換爲例如Apache HttpComponents、Netty或//OkHttp等其它HTTP library。
factory.setReadTimeout(5000);//單位爲ms
factory.setConnectTimeout(5000);//單位爲ms
return factory;
}
}
1)get請求(不帶參的即把參數取消即可)
// 1-getForObject()
User user1 = this.restTemplate.getForObject(uri, User.class);
// 2-getForEntity()
ResponseEntity<User> responseEntity1 = this.restTemplate.getForEntity(uri, User.class);
HttpStatus statusCode = responseEntity1.getStatusCode();
HttpHeaders header = responseEntity1.getHeaders();
User user2 = responseEntity1.getBody();
// 3-exchange()
RequestEntity requestEntity = RequestEntity.get(new URI(uri)).build();
ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);
User user3 = responseEntity2.getBody();
方式一:
Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/{1}/{2}"
, Notice.class,1,5);
方式二:
Map<String,String> map = new HashMap();
map.put("start","1");
map.put("page","5");
Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/"
, Notice.class,map);
2)post請求:
// 1-postForObject()
User user1 = this.restTemplate.postForObject(uri, user, User.class);
// 2-postForEntity()
ResponseEntity<User> responseEntity1 = this.restTemplate.postForEntity(uri, user, User.class);
// 3-exchange()
RequestEntity<User> requestEntity = RequestEntity.post(new URI(uri)).body(user);
ResponseEntity<User> responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);
方式一:
String url = "http://demo/api/book/";
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
String requestJson = "{...}";
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String result = restTemplate.postForObject(url, entity, String.class);
System.out.println(result);
方式二:
@Test
public void rtPostObject(){
RestTemplate restTemplate = new RestTemplate();
String url = "http://47.xxx.xxx.96/register/checkEmail";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("email", "[email protected]");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );
System.out.println(response.getBody());
}
三、okhttp
OkHttp是一個高效的HTTP客戶端,允許所有同一個主機地址的請求共享同一個socket連接;連接池減少請求延時;透明的GZIP壓縮減少響應數據的大小;緩存響應內容,避免一些完全重複的請求
當網絡出現問題的時候OkHttp依然堅守自己的職責,它會自動恢復一般的連接問題,如果你的服務有多個IP地址,當第一個IP請求失敗時,OkHttp會交替嘗試你配置的其他IP,OkHttp使用現代TLS技術(SNI, ALPN)初始化新的連接,當握手失敗時會回退到TLS 1.0。
1)使用:它的請求/響應 API 使用構造器模式builders來設計,它支持阻塞式的同步請求和帶回調的異步請求。
引入jar包:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
例子1
配置文件:
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
@Configuration
public class OkHttpConfiguration {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
//.sslSocketFactory(sslSocketFactory(), x509TrustManager())
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30,TimeUnit.SECONDS)
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslSocketFactory() {
try {
//信任任何鏈接
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
/**
* Create a new connection pool with tuning parameters appropriate for a single-user application.
* The tuning parameters in this pool are subject to change in future OkHttp releases. Currently
*/
@Bean
public ConnectionPool pool() {
return new ConnectionPool(200, 5, TimeUnit.MINUTES);
}
}
3)util工具:
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
public class OkHttpUtil{
private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);
private static OkHttpClient okHttpClient;
@Autowired
public OkHttpUtil(OkHttpClient okHttpClient) {
OkHttpUtil.okHttpClient= okHttpClient;
}
/**
* get
* @param url 請求的url
* @param queries 請求的參數,在瀏覽器?後面的數據,沒有可以傳null
* @return
*/
public static String get(String url, Map<String, String> queries) {
String responseBody = "";
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
Request request = new Request.Builder()
.url(sb.toString())
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
/**
* post
*
* @param url 請求的url
* @param params post form 提交的參數
* @return
*/
public static String post(String url, Map<String, String> params) {
String responseBody = "";
FormBody.Builder builder = new FormBody.Builder();
//添加參數
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
builder.add(key, params.get(key));
}
}
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
/**
* get
* @param url 請求的url
* @param queries 請求的參數,在瀏覽器?後面的數據,沒有可以傳null
* @return
*/
public static String getForHeader(String url, Map<String, String> queries) {
String responseBody = "";
StringBuffer sb = new StringBuffer(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
Request request = new Request.Builder()
.addHeader("key", "value")
.url(sb.toString())
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
/**
* Post請求發送JSON數據....{"name":"zhangsan","pwd":"123456"}
* 參數一:請求Url
* 參數二:請求的JSON
* 參數三:請求回調
*/
public static String postJsonParams(String url, String jsonParams) {
String responseBody = "";
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
/**
* Post請求發送xml數據....
* 參數一:請求Url
* 參數二:請求的xmlString
* 參數三:請求回調
*/
public static String postXmlParams(String url, String xml) {
String responseBody = "";
RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
}
例子2
import android.util.Log;
import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by fyc on 2017/7/12.
*/
public class OkHttpUtil {
public final static int READ_TIMEOUT = 100;
public final static int CONNECT_TIMEOUT = 60;
public final static int WRITE_TIMEOUT = 60;
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static final byte[] LOCKER = new byte[0];
private static OkHttpUtil mInstance;
private OkHttpClient mOkHttpClient;
/**
* 自定義網絡回調接口
*/
public interface NetCall {
void success(Call call, Response response) throws IOException;
void failed(Call call, IOException e);
}
private OkHttpUtil() {
okhttp3.OkHttpClient.Builder ClientBuilder = new okhttp3.OkHttpClient.Builder();
ClientBuilder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);//讀取超時
ClientBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);//連接超時
ClientBuilder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);//寫入超時
//支持HTTPS請求,跳過證書驗證
ClientBuilder.sslSocketFactory(createSSLSocketFactory());
ClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
mOkHttpClient = ClientBuilder.build();
}
/**
* 單例模式獲取OkHttpUtil
*
* @return
*/
public static OkHttpUtil getInstance() {
if (mInstance == null) {
synchronized (LOCKER) {
if (mInstance == null) {
mInstance = new OkHttpUtil();
}
}
}
return mInstance;
}
/**
* get請求,同步方式,獲取網絡數據,是在主線程中執行的,需要新起線程,將其放到子線程中執行
*
* @param url
* @return
*/
public Response getData(String url) {
//1 構造Request
Request.Builder builder = new Request.Builder();
Request request = builder.get().url(url).build();
//2 將Request封裝爲Call
Call call = mOkHttpClient.newCall(request);
//3 執行Call,得到response
Response response = null;
try {
response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
/**
* post請求,同步方式,提交數據,是在主線程中執行的,需要新起線程,將其放到子線程中執行
*
* @param url
* @param bodyParams
* @return
*/
public Response postData(String url, Map<String, String> bodyParams) {
//1構造RequestBody
RequestBody body = setRequestBody(bodyParams);
//2 構造Request
Request.Builder requestBuilder = new Request.Builder();
Request request = requestBuilder.post(body).url(url).build();
//3 將Request封裝爲Call
Call call = mOkHttpClient.newCall(request);
//4 執行Call,得到response
Response response = null;
try {
response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
/**
* get請求,異步方式,獲取網絡數據,是在子線程中執行的,需要切換到主線程才能更新UI
*
* @param url
* @param netCall
* @return
*/
public void getDataAsyn(String url, final NetCall netCall) {
//1 構造Request
Request.Builder builder = new Request.Builder();
Request request = builder.get().url(url).build();
//2 將Request封裝爲Call
Call call = mOkHttpClient.newCall(request);
//3 執行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
}
/**
* post請求,異步方式,提交數據,是在子線程中執行的,需要切換到主線程才能更新UI
*
* @param url
* @param bodyParams
* @param netCall
*/
public void postDataAsyn(String url, Map<String, String> bodyParams, final NetCall netCall) {
//1構造RequestBody
RequestBody body = setRequestBody(bodyParams);
//2 構造Request
Request.Builder requestBuilder = new Request.Builder();
Request request = requestBuilder.post(body).url(url).build();
//3 將Request封裝爲Call
Call call = mOkHttpClient.newCall(request);
//4 執行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
}
/**
* post的請求參數,構造RequestBody
*
* @param BodyParams
* @return
*/
private RequestBody setRequestBody(Map<String, String> BodyParams) {
RequestBody body = null;
okhttp3.FormBody.Builder formEncodingBuilder = new okhttp3.FormBody.Builder();
if (BodyParams != null) {
Iterator<String> iterator = BodyParams.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next().toString();
formEncodingBuilder.add(key, BodyParams.get(key));
Log.d("post http", "post_Params===" + key + "====" + BodyParams.get(key));
}
}
body = formEncodingBuilder.build();
return body;
}
/**
* 生成安全套接字工廠,用於https請求的證書跳過
*
* @return
*/
private SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return ssfFactory;
}
public String postJson(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = mOkHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
public void postJsonAsyn(String url, String json, final NetCall netCall) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
//2 構造Request
Request.Builder requestBuilder = new Request.Builder();
Request request = requestBuilder.post(body).url(url).build();
//3 將Request封裝爲Call
Call call = mOkHttpClient.newCall(request);
//4 執行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
}
/**
* 用於信任所有證書
*/
class TrustAllCerts implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}