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)文章
maven依賴(lài)關(guān)系中的<scope>provided</scope>使用詳解
這篇文章主要介紹了maven依賴(lài)關(guān)系中的<scope>provided</scope>使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
SpringBoot動(dòng)態(tài)修改配置的十種方法
在SpringBoot應(yīng)用中,配置信息通常通過(guò)application.properties或application.yml文件靜態(tài)定義,應(yīng)用啟動(dòng)后這些配置就固定下來(lái)了,但我們常常需要在不重啟應(yīng)用的情況下動(dòng)態(tài)修改配置,本文將介紹SpringBoot中10種實(shí)現(xiàn)配置動(dòng)態(tài)修改的方法,需要的朋友可以參考下2025-05-05
利用Java實(shí)現(xiàn)在PDF中添加工具提示
這篇文章主要介紹了如何通過(guò)Java在PDF中添加工具提示,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定的參考價(jià)值,感興趣的可以學(xué)習(xí)一下2022-01-01
DolphinScheduler容錯(cuò)Master源碼分析
這篇文章主要為大家介紹了DolphinScheduler容錯(cuò)Master源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
mysql數(shù)據(jù)庫(kù)忘記密碼時(shí)如何修改
本文主要介紹了mysql數(shù)據(jù)庫(kù)忘記密碼時(shí)如何修改的步驟方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02
Spring?Boot?3.x開(kāi)發(fā)中MySQL?8.x窗口函數(shù)在JPA中的使用限制問(wèn)題詳解
開(kāi)窗函數(shù)是在MySQL8.0以后才新加的功能,因此要想直接使用開(kāi)窗函數(shù),則mysql版本要8.0以上,這篇文章主要介紹了Spring Boot 3.x開(kāi)發(fā)中MySQL 8.x窗口函數(shù)在JPA中的使用限制問(wèn)題的相關(guān)資料,需要的朋友可以參考下2026-04-04
idea 自動(dòng)生成類(lèi)注釋和方法注釋的實(shí)現(xiàn)步驟
這篇文章主要介紹了idea 自動(dòng)生成類(lèi)注釋和方法注釋的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Java獲取手機(jī)號(hào)碼歸屬地的實(shí)現(xiàn)
這篇文章主要介紹了Java獲取手機(jī)號(hào)碼歸屬地的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
配置java.library.path加載庫(kù)文件問(wèn)題
這篇文章主要介紹了配置java.library.path加載庫(kù)文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12

