淺析幾種Java Http請求庫的使用:HttpURLConnection、RestTemplate、OKhttp、Feign/OpenFeign


  轉載於:https://www.modb.pro/db/69232

  java常見的http請求庫有HttpURLConnection、httpclient、RestTemplate、OKhttp,更高層次封裝的 feign、retrofit

一、HttpURLConnection

HttpURLConnection 是 JDK 自帶的標准庫;

【優點】:不需要引入額外的依賴

【缺點】:缺乏連接池管理、域名機械控制等特性支持,在java9才支持 HTTP/2

public class HttpUrlConnectionDemo { public static void main(String[] args) throws Exception { String urlString = "https://httpbin.org/post"; String bodyString = "password=e10adc3949ba59abbe56e057f20f883e&username=test3"; URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); os.write(bodyString.getBytes("utf-8")); os.flush(); os.close(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream is = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line); } System.out.println("rsp:" + sb.toString()); } else { System.out.println("rsp code:" + conn.getResponseCode()); } } }

二、OkHttp

【優點】:OkHttp 接口設計友好,支持 HTTP/2,並且在弱網和無網環境下有自動檢測和恢復機制,因此,是當前 Android APP 開發中使用最廣泛的 HTTP clilent lib 之一。

當網絡出現問題的時候 OkHttp 依然堅守自己的職責,它會自動恢復一般的連接問題,如果你的服務有多個IP地址,當第一個IP請求失敗時,OkHttp 會交替嘗試你配置的其他IP,OkHttp使用現代TLS技術(SNI, ALPN)初始化新的連接,當握手失敗時會回退到TLS 1.0。

1、導入依賴

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.10.0</version>
</dependency>

2、簡單使用

import okhttp3.*; import org.apache.http.util.CharsetUtils; import java.util.HashMap; import java.util.Map; public class OkHttpDemo { OkHttpClient client = new OkHttpClient(); private String sendPostForm(String url, final Map&lt;String, String&gt; params) throws Exception { FormBody.Builder builder = new FormBody.Builder(CharsetUtils.get("UTF-8")); if (params != null) { for (Map.Entry&lt;String, String&gt; entry: params.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } RequestBody requestBody = builder.build(); Request request = new Request.Builder().url(url).post(requestBody).build(); return client.newCall(request).execute().body().string(); } private String sendGet(String url) throws Exception { Request request = new Request.Builder().url(url).build(); return client.newCall(request).execute().body().string(); } public static void main(String[] args) throws Exception { OkHttpDemo okHttpDemo = new OkHttpDemo(); String url = "https://httpbin.org/post"; params = new HashMap(); params.put("foo", "bar中文"); // Post請求
        String rsp = okHttpDemo.sendPostForm(url, params); System.out.println("http post rsp:" + rsp); // Get請求
        url = "https://httpbin.org/get"; System.out.println("http get rsp:" + okHttpDemo.sendGet(url)); } }

3、項目應用

(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); } }

(2)utils 工具類

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; } }

三、RestTemplate

RestTemplate: 是 Spring 提供的用於訪問Rest服務的客戶端, RestTemplate 提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。

1、導入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、關於注入RestTemplate對象

  RestTemplate 在源碼中是沒有@Bean注入的,因此,我們不能直接使用如下方式直接注入

@Autowired private RestTemplate restTemplate;

【解決方案】

(1)方式一:如果要使用,可以編寫配置文件自己注入

@Configuration public class ApiConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory) { return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { //默認的是JDK提供http連接,需要的話可以//通過setRequestFactory方法替換為例如Apache HttpComponents、Netty或//OkHttp等其它HTTP library。
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(5000);//單位為ms
        factory.setConnectTimeout(5000);//單位為ms
        return factory; } }

(2)也可以通過自己新建對象直接使用

RestTemplate restTemplate = new RestTemplate();

3、如何使用

(1)Get 請求

// 方式一
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 請求

// 方式一
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); // 方式二
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", "844072586@qq.com"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class ); System.out.println(response.getBody());

四、Feign/OpenFeign

  可以看這篇:Spring Cloud OpenFeign詳解  ——  https://blog.csdn.net/taiyangdao/article/details/81359394


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM