java http请求设置代理Proxy的两种常见方法
HttpURLConnection、HttpClient设置代理Proxy
有如下一种需求,原本A要给C发送请求,但是因为网络原因,需要借助B才能实现,所以由原本的A->C变成了A->B->C。
这种情况,更多的见于内网请求由统一的网关做代理然后转发出去,比如你本地的机器想要对外上网,都是通过运营商给的出口IP也就是公网地址实现的。这种做法就是代理了。
研究了一下针对 HttpURLConnection和HttpClient这两种常见的http请求的代理:
一、HttpURLConnection设置请求代理
贴出一个utils类
具体代码如下:
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 { //设置proxy Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); URL proxyUrl = new URL(url); //判断是哪种类型的请求 if (url.startsWith("https")) { HttpsURLConnection httpsURLConnection = (HttpsURLConnection) proxyUrl.openConnection(proxy); httpsURLConnection.setRequestProperty("Content-Type", CONTENT_TYPE); //允许写入 httpsURLConnection.setDoInput(true); //允许写出 httpsURLConnection.setDoOutput(true); //请求方法的类型 POST/GET httpsURLConnection.setRequestMethod("POST"); //是否使用缓存 httpsURLConnection.setUseCaches(false); //读取超时 httpsURLConnection.setReadTimeout(15000); //连接超时 httpsURLConnection.setConnectTimeout(15000); //设置SSL httpsURLConnection.setSSLSocketFactory(getSsf()); //设置主机验证程序 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; } } }
上面的代码就是对httpsURLConnection设置了Proxy代理,也就是请求先会发到proxyHost:proxyPort,然后由其代理发到url。
二、HttpClient设置请求代理
贴出一个utils类
具体代码如下:
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); //设置请求配置类 重点就是在这里添加setProxy 设置代理 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(); } }
以上就是针对http、https的代理汇总,其实想想,就是通过 Proxy 对象,添加对应的代理地址和端口,实现了一层转发,可以想到nginx、gateway这种思想。
总结
到此这篇关于java http请求设置代理Proxy的两种常见方法的文章就介绍到这了,更多相关java http请求设置代理Proxy内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringMVC将请求和响应的数据转换为JSON格式的几种方式
这篇文章主要给大家介绍饿了SpringMVC将请求和响应的数据转换为JSON格式的几种方式,文中通过代码示例和图文结合给大家介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下2023-11-11Java中的Set接口实现类HashSet和LinkedHashSet详解
这篇文章主要介绍了Java中的Set接口实现类HashSet和LinkedHashSet详解,Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了,需要的朋友可以参考下2024-01-01spring boot实现超轻量级网关的方法(反向代理、转发)
这篇文章主要介绍了spring boot实现超轻量级网关(反向代理、转发)的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-11-11
最新评论