浅析几种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