一、HttpClient
1.1、 前臺系統(tǒng)訪問后臺接口的方式
兩個系統(tǒng)間如何互相訪問?兩個tomcat上的項目如何互相訪問
采用HttpClient實現(xiàn)跨系統(tǒng)的接口調(diào)用。
1.2、 什么是HttpClient
官網(wǎng):http://hc.apache.org/index.html
現(xiàn)在也叫:HttpComponents
特點:
- HttpClient別名:HttpComponents
- HttpClient可以發(fā)送get、post、put、delete、…等請求
1.3、 HttpClient入門案例
導入maven坐標
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.4</version> </dependency>
1.3.1、 發(fā)起Get請求
- 1創(chuàng)建一個客戶端 CloseableHttpClient
- 2創(chuàng)建一個get方法請求實例 HttpGet
- 3發(fā)送請求 execute
- 4獲取響應的頭信息
- 5獲取響應的主題內(nèi)容
- 6關閉響應對象
使用HttpClient發(fā)起Get請求的案例代碼:
public class DoGET { public static void main(String[] args) throws Exception { // 創(chuàng)建Httpclient對象,相當于打開了瀏覽器 CloseableHttpClient httpclient = HttpClients.createDefault(); // 創(chuàng)建HttpGet請求,相當于在瀏覽器輸入地址 HttpGet httpGet = new HttpGet("http://www.baidu.com/"); CloseableHttpResponse response = null; try { // 執(zhí)行請求,相當于敲完地址后按下回車。獲取響應 response = httpclient.execute(httpGet); // 判斷返回狀態(tài)是否為200 if (response.getStatusLine().getStatusCode() == 200) { // 解析響應,獲取數(shù)據(jù) String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { // 關閉資源 response.close(); } // 關閉瀏覽器 httpclient.close(); } } }
執(zhí)行日志:
請求頭:
響應頭:
數(shù)據(jù):
1.3.2、 帶參數(shù)的Get請求
- 1創(chuàng)建一個客戶端 CloseableHttpClient
- 2通過URIBuilder傳遞參數(shù)
- 3創(chuàng)建一個get方法請求實例 HttpGet
- 4發(fā)送請求 execute
- 5獲取響應的頭信息
- 6獲取響應的主題內(nèi)容
- 7關閉響應對象
訪問網(wǎng)站的爬蟲協(xié)議:
public class DoGETParam { public static void main(String[] args) throws Exception { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpclient = HttpClients.createDefault(); // 創(chuàng)建URI對象,并且設置請求參數(shù) URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build(); // 創(chuàng)建http GET請求 HttpGet httpGet = new HttpGet(uri); // HttpGet get = new HttpGet("http://www.baidu.com/s?wd=java"); CloseableHttpResponse response = null; try { // 執(zhí)行請求 response = httpclient.execute(httpGet); // 判斷返回狀態(tài)是否為200 if (response.getStatusLine().getStatusCode() == 200) { // 解析響應數(shù)據(jù) String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { response.close(); } httpclient.close(); } } }
1.3.3、 發(fā)起POST請求
/* * 演示:使用HttpClient發(fā)起POST請求 */ public class DoPOST { public static void main(String[] args) throws Exception { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpclient = HttpClients.createDefault(); // 創(chuàng)建http POST請求 HttpPost httpPost = new HttpPost("http://www.oschina.net/"); // 把自己偽裝成瀏覽器。否則開源中國會攔截訪問 httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); CloseableHttpResponse response = null; try { // 執(zhí)行請求 response = httpclient.execute(httpPost); // 判斷返回狀態(tài)是否為200 if (response.getStatusLine().getStatusCode() == 200) { // 解析響應數(shù)據(jù) String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { response.close(); } // 關閉瀏覽器 httpclient.close(); } } }
1.3.4、 帶參數(shù)POST請求
/* * 演示:使用HttpClient發(fā)起帶有參數(shù)的POST請求 */ public class DoPOSTParam { public static void main(String[] args) throws Exception { // 創(chuàng)建Httpclient對象 CloseableHttpClient httpclient = HttpClients.createDefault(); // 創(chuàng)建http POST請求,訪問開源中國 HttpPost httpPost = new HttpPost("http://www.oschina.net/search"); // 根據(jù)開源中國的請求需要,設置post請求參數(shù) List<NameValuePair> parameters = new ArrayList<NameValuePair>(0); parameters.add(new BasicNameValuePair("scope", "project")); parameters.add(new BasicNameValuePair("q", "java")); parameters.add(new BasicNameValuePair("fromerr", "8bDnUWwC")); // 構造一個form表單式的實體 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters); // 將請求實體設置到httpPost對象中 httpPost.setEntity(formEntity); CloseableHttpResponse response = null; try { // 執(zhí)行請求 response = httpclient.execute(httpPost); // 判斷返回狀態(tài)是否為200 if (response.getStatusLine().getStatusCode() == 200) { // 解析響應體 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { response.close(); } // 關閉瀏覽器 httpclient.close(); } } }
二、項目整合HttpClient―與SpringBoot整合
SpringBoot官方并沒有對HttpClient的啟動器。所以我們需要自己完成配置,還好,我們剛才在測試案例中已經(jīng)寫過了。
不過,SpringBoot雖然沒有提供啟動器,但是卻提供了一個統(tǒng)一的對Restful服務進行調(diào)用的模板類:RestTemplate,底層可以使用HttpClient來實現(xiàn)。有了這個我們就無需自己定義APIService了。
1、導入maven坐標
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、在項目中創(chuàng)建HttpClientConfig類C類似util
3、在application.properties添加如下配置:
#The config for HttpClient http.maxTotal=300 http.defaultMaxPerRoute=50 http.connectTimeout=1000 http.connectionRequestTimeout=500 http.socketTimeout=5000 http.staleConnectionCheckEnabled=true
4、在類中編寫代碼
/** * HttpClient的配置類 * */ @Configuration @ConfigurationProperties(prefix = "http", ignoreUnknownFields = true) public class HttpClientConfig { private Integer maxTotal;// 最大連接 private Integer defaultMaxPerRoute;// 每個host的最大連接 private Integer connectTimeout;// 連接超時時間 private Integer connectionRequestTimeout;// 請求超時時間 private Integer socketTimeout;// 響應超時時間 /** * HttpClient連接池 * @return */ @Bean public HttpClientConnectionManager httpClientConnectionManager() { PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); connectionManager.setMaxTotal(maxTotal); connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); return connectionManager; } /** * 注冊RequestConfig * @return */ @Bean public RequestConfig requestConfig() { return RequestConfig.custom().setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout) .build(); } /** * 注冊HttpClient * @param manager * @param config * @return */ @Bean public HttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) { return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config) .build(); } /** * 使用連接池管理連接 * @param httpClient * @return */ @Bean public ClientHttpRequestFactory requestFactory(HttpClient httpClient) { return new HttpComponentsClientHttpRequestFactory(httpClient); } /** * 使用HttpClient來初始化一個RestTemplate * @param requestFactory * @return */ @Bean public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory) { RestTemplate template = new RestTemplate(requestFactory); List<HttpMessageConverter<?>> list = template.getMessageConverters(); for (HttpMessageConverter<?> mc : list) { if (mc instanceof StringHttpMessageConverter) { ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8")); } } return template; } public Integer getMaxTotal() { return maxTotal; } public void setMaxTotal(Integer maxTotal) { this.maxTotal = maxTotal; } public Integer getDefaultMaxPerRoute() { return defaultMaxPerRoute; } public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) { this.defaultMaxPerRoute = defaultMaxPerRoute; } public Integer getConnectTimeout() { return connectTimeout; } public void setConnectTimeout(Integer connectTimeout) { this.connectTimeout = connectTimeout; } public Integer getConnectionRequestTimeout() { return connectionRequestTimeout; } public void setConnectionRequestTimeout(Integer connectionRequestTimeout) { this.connectionRequestTimeout = connectionRequestTimeout; } public Integer getSocketTimeout() { return socketTimeout; } public void setSocketTimeout(Integer socketTimeout) { this.socketTimeout = socketTimeout; } }
三、RestTemplate使用詳解
1、概述:
RestTemplate是Spring提供的用于訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。
之前的HTTP開發(fā)是用apache的HttpClient開發(fā),代碼復雜,還得操心資源回收等。代碼很復雜,冗余代碼多。
導入坐標:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、創(chuàng)建RestTemplate對象
第一步:創(chuàng)建RestTemplate類,在類中創(chuàng)建RestTemplate對象
/** * Created by yxq on 2020/08/05. * RestTemplate工具類,主要用來提供RestTemplate對象 */ @Configuration//加上這個注解作用,可以被Spring掃描 public class RestTemplateConfig { /** * 創(chuàng)建RestTemplate對象,將RestTemplate對象的生命周期的管理交給Spring * @return */ @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
第二步:創(chuàng)建RestTempController,注入RestTemplate
/** * Created by yxq on 2019/11/29. * 本項目不連接數(shù)據(jù)庫,通過RestTemplate發(fā)出get、post、put、delete請求,請求admin-project項目中controller的方法 * * */ @RestController @RequestMapping("/rest") public class RestTempController { // 從Spring的容器中獲取restTemplate @Autowired private RestTemplate restTemplate; }
3、get請求
第一步:在RestTempController中編寫代碼,發(fā)起get請求:
/** * 發(fā)起get請求,請求admin-project * http://localhost:8088/admin -->分頁查找 */ @GetMapping public ResponseEntity<String> findByPage(){ /** * 第一個參數(shù):url * 第二個參數(shù):返回值類型 */ ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8088/admin?page=1&rows=3", String.class); System.out.println("狀態(tài)碼:"+entity.getStatusCode()); System.out.println("響應體"+entity.getBody()); return ResponseEntity.ok(entity.getBody()); }
測試結果:
4、post請求
第一步:創(chuàng)建實體類Admin
public class Admin { /** * 編號 */ private Integer id; /** * 管理員名 */ private String adminname; /** * 密碼 */ private String password; /** * 郵箱 */ private String email; /** * 手機號 */ private String phone; /** * 狀態(tài),0禁用,1啟用 */ private Integer state; /** * 時間 */ private Date time; /** * 角色id */ private String rid; // 省略getter和setter方法 }
第二步:在RestTempController中編寫方法,發(fā)送post請求
@PostMapping public ResponseEntity<String> addAdmin(@RequestBody Admin admin){ /** * 第一個參數(shù):url * 第二個參數(shù):數(shù)據(jù) * 第三個參數(shù):返回值類型 */ ResponseEntity<String> entity = restTemplate.postForEntity("http://localhost:8088/admin", admin, String.class); return entity; }
第三步:采用postman測試
5、post請求的中文亂碼bug
在RestTemplateConfig中編寫處理亂碼的問題:
/** * Created by yxq on 2020/08/05. * RestTemplate工具類,主要用來提供RestTemplate對象 */ @Configuration//加上這個注解作用,可以被Spring掃描 public class RestTemplateConfig { /** * 創(chuàng)建RestTemplate對象,將RestTemplate對象的生命周期的管理交給Spring * @return */ @Bean public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); // 設置中文亂碼問題方式一 restTemplate.getMessageConverters().add(1,new StringHttpMessageConverter(Charset.forName("UTF-8"))); // 設置中文亂碼問題方式二 // restTemplate.getMessageConverters().set(1, // new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 支持中文編碼 return restTemplate; } }
6、put請求
第一步:在RestTempController中編寫方法,發(fā)送put請求
/** * 修改數(shù)據(jù) * */ @PutMapping public ResponseEntity<String> updateAdmin(@RequestBody Admin admin){ // 第一個參數(shù):url // 第二個參數(shù):對象,數(shù)據(jù) restTemplate.put("http://localhost:8088/admin",admin); return ResponseEntity.ok("修改成功"); }
7、delete請求
第一步:在RestTempController中編寫方法,發(fā)送delete請求
@DeleteMapping("/{id}") public ResponseEntity<String> deleteAdmin(@PathVariable("id") Integer id){ restTemplate.delete("http://localhost:8088/admin/"+id); return ResponseEntity.ok("刪除成功"); }
到此這篇關于Java HttpClient技術詳解的文章就介紹到這了,更多相關Java HttpClient內(nèi)容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_45752540/article/details/120684190