java?http請(qǐng)求設(shè)置代理Proxy的兩種常見(jiàn)方法
HttpURLConnection、HttpClient設(shè)置代理Proxy
有如下一種需求,原本A要給C發(fā)送請(qǐng)求,但是因?yàn)榫W(wǎng)絡(luò)原因,需要借助B才能實(shí)現(xiàn),所以由原本的A->C變成了A->B->C。
這種情況,更多的見(jiàn)于內(nèi)網(wǎng)請(qǐng)求由統(tǒng)一的網(wǎng)關(guān)做代理然后轉(zhuǎn)發(fā)出去,比如你本地的機(jī)器想要對(duì)外上網(wǎng),都是通過(guò)運(yùn)營(yíng)商給的出口IP也就是公網(wǎng)地址實(shí)現(xiàn)的。這種做法就是代理了。
研究了一下針對(duì) HttpURLConnection和HttpClient這兩種常見(jiàn)的http請(qǐng)求的代理:
一、HttpURLConnection設(shè)置請(qǐng)求代理
貼出一個(gè)utils類(lèi)
具體代碼如下:
public class ProxyUtils { public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; public static String getResultByHttpConnectionProxy(String url, String content, String proxyHost, int proxyPort) { String result = ""; OutputStream outputStream = null; InputStream inputStream = null; try { //設(shè)置proxy Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); URL proxyUrl = new URL(url); //判斷是哪種類(lèi)型的請(qǐng)求 if (url.startsWith("https")) { HttpsURLConnection httpsURLConnection = (HttpsURLConnection) proxyUrl.openConnection(proxy); httpsURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE); //允許寫(xiě)入 httpsURLConnection.setDoInput(true); //允許寫(xiě)出 httpsURLConnection.setDoOutput(true); //請(qǐng)求方法的類(lèi)型 POST/GET httpsURLConnection.setRequestMethod("POST"); //是否使用緩存 httpsURLConnection.setUseCaches(false); //讀取超時(shí) httpsURLConnection.setReadTimeout(15000); //連接超時(shí) httpsURLConnection.setConnectTimeout(15000); //設(shè)置SSL httpsURLConnection.setSSLSocketFactory(getSsf()); //設(shè)置主機(jī)驗(yàn)證程序 httpsURLConnection.setHostnameVerifier((s, sslSession) -> true); outputStream = httpsURLConnection.getOutputStream(); outputStream.write(content.getBytes(StandardCharsets.UTF_8)); outputStream.flush(); inputStream = httpsURLConnection.getInputStream(); } else { HttpURLConnection httpURLConnection = (HttpURLConnection) proxyUrl.openConnection(proxy); httpURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE); httpURLConnection.setDoOutput(true); httpURLConnection.setDoInput(true); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setUseCaches(false); httpURLConnection.setConnectTimeout(15000); httpURLConnection.setReadTimeout(15000); outputStream = httpURLConnection.getOutputStream(); outputStream.write(content.getBytes("UTF-8")); outputStream.flush(); inputStream = httpURLConnection.getInputStream(); } byte[] bytes = read(inputStream, 1024); result = (new String(bytes, "UTF-8")).trim(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (outputStream != null) { outputStream.close(); } if (inputStream != null) { inputStream.close(); } } catch (Exception e) { e.printStackTrace(); } } return result; } public static byte[] read(InputStream inputStream, int bufferSize) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[bufferSize]; for (int num = inputStream.read(buffer); num != -1; num = inputStream.read(buffer)) { baos.write(buffer, 0, num); } baos.flush(); return baos.toByteArray(); } private static SSLSocketFactory getSsf() { SSLContext ctx = null; try { ctx = SSLContext.getInstance("TLS"); ctx.init(new KeyManager[0], new TrustManager[]{new ProxyUtils.DefaultTrustManager()}, new SecureRandom()); } catch (Exception e) { e.printStackTrace(); } assert ctx != null; return ctx.getSocketFactory(); } private static final class DefaultTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }
上面的代碼就是對(duì)httpsURLConnection設(shè)置了Proxy代理,也就是請(qǐng)求先會(huì)發(fā)到proxyHost:proxyPort,然后由其代理發(fā)到url。
二、HttpClient設(shè)置請(qǐng)求代理
貼出一個(gè)utils類(lèi)
具體代碼如下:
public class HttpclientUtils { private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; public static String getResultByProxy(String url, String request, String proxyHost, int proxyPort) throws Exception { String response = null; HttpPost httpPost = null; try { HttpClient httpClient = getHttpClient(url); //設(shè)置請(qǐng)求配置類(lèi) 重點(diǎn)就是在這里添加setProxy 設(shè)置代理 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000) .setConnectionRequestTimeout(15000).setProxy(new HttpHost(proxyHost, proxyPort)).build(); httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); httpPost.addHeader("Content-Type", CONTENT_TYPE); httpPost.setEntity(new StringEntity(request, "utf-8")); response = getHttpClientResponse(httpPost, httpClient); } catch (Exception e) { e.printStackTrace(); } finally { if (null != httpPost) { httpPost.releaseConnection(); } } return response; } private static String getHttpClientResponse(HttpPost httpPost, HttpClient httpClient) throws Exception { String result = null; HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity entity = httpResponse.getEntity(); if (null != entity) { try (InputStream inputStream = entity.getContent()) { byte[] bytes = read(inputStream, 1024); result = new String(bytes, StandardCharsets.UTF_8); } } return result; } private static HttpClient getHttpClient(String url) throws Exception { HttpClient httpClient; String lowerURL = url.toLowerCase(); if (lowerURL.startsWith("https")) { httpClient = createSSLClientDefault(); } else { httpClient = HttpClients.createDefault(); } return httpClient; } private static CloseableHttpClient createSSLClientDefault() throws Exception { SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, (s, sslSession) -> true); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } public static byte[] read(InputStream inputStream, int bufferSize) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[bufferSize]; for (int num = inputStream.read(buffer); num != -1; num = inputStream.read(buffer)) { baos.write(buffer, 0, num); } baos.flush(); return baos.toByteArray(); } }
以上就是針對(duì)http、https的代理匯總,其實(shí)想想,就是通過(guò) Proxy 對(duì)象,添加對(duì)應(yīng)的代理地址和端口,實(shí)現(xiàn)了一層轉(zhuǎn)發(fā),可以想到nginx、gateway這種思想。
總結(jié)
到此這篇關(guān)于java http請(qǐng)求設(shè)置代理Proxy的兩種常見(jiàn)方法的文章就介紹到這了,更多相關(guān)java http請(qǐng)求設(shè)置代理Proxy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring中BeanUtils.copyProperties的使用(深拷貝,淺拷貝)
本文主要介紹了spring中BeanUtils.copyProperties的使用(深拷貝,淺拷貝),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置三種方法
時(shí)間和日期的統(tǒng)一設(shè)置在項(xiàng)目中經(jīng)常是會(huì)遇到的,下面這篇文章主要給大家介紹了關(guān)于Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置的三種方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08聊聊@RequestBody和Json之間的關(guān)系
這篇文章主要介紹了@RequestBody和Json之間的關(guān)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06java實(shí)現(xiàn)裝飾器模式(Decorator Pattern)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)裝飾器模式Decorator Pattern,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10java后臺(tái)調(diào)用接口及處理跨域問(wèn)題的解決
這篇文章主要介紹了java后臺(tái)調(diào)用接口,處理跨域的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java設(shè)計(jì)模式之創(chuàng)建者模式簡(jiǎn)介
這篇文章主要介紹了Java設(shè)計(jì)模式之創(chuàng)建者模式,需要的朋友可以參考下2014-07-07使用spring-boot-admin對(duì)spring-boot服務(wù)進(jìn)行監(jiān)控的實(shí)現(xiàn)方法
這篇文章主要介紹了使用spring-boot-admin對(duì)spring-boot服務(wù)進(jìn)行監(jiān)控的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-02-02SpringBoot用JdbcTemplates訪(fǎng)問(wèn)Mysql實(shí)例代碼
本篇文章主要介紹了SpringBoot用JdbcTemplates訪(fǎng)問(wèn)Mysql實(shí)例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05