调用公共API报java.net.UnknownHostException的解决方法咨询
问题原因确认
你遇到的java.net.UnknownHostException大概率是代理配置问题导致的:Postman默认会复用操作系统的代理配置,所以你本地配置过代理的情况下可以正常访问公共API;但JVM默认不会自动读取系统代理配置,无法完成域名解析,就会抛出该异常。
RestTemplate代理配置方案
有两种常用配置方式,按需选择即可:
代码局部配置(推荐)
自定义RestTemplate的请求工厂,指定代理配置,不会影响其他业务的请求逻辑:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import java.net.*; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); // 配置HTTP/HTTPS代理 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("代理主机地址", 代理端口)); factory.setProxy(proxy); // 若代理需要身份认证,添加以下配置 Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("代理用户名", "代理密码".toCharArray()); } }); return new RestTemplate(factory); } }
JVM全局参数配置
启动Java服务时添加以下启动参数,全局生效,无需修改代码:
# HTTP代理配置 -Dhttp.proxyHost=代理主机地址 -Dhttp.proxyPort=代理端口 -Dhttp.proxyUser=代理用户名(无认证可省略) -Dhttp.proxyPassword=代理密码(无认证可省略) # HTTPS代理配置 -Dhttps.proxyHost=代理主机地址 -Dhttps.proxyPort=代理端口 -Dhttps.proxyUser=代理用户名(无认证可省略) -Dhttps.proxyPassword=代理密码(无认证可省略)
不使用代理发起请求的实现方法
如果需要绕开代理直接发起请求,可通过以下方式实现:
RestTemplate指定无代理
构造RestTemplate时强制设置不使用代理:
@Bean public RestTemplate noProxyRestTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); // 强制不走任何代理 factory.setProxy(Proxy.NO_PROXY); return new RestTemplate(factory); }
你原有的业务代码直接注入这个无代理的RestTemplate即可正常使用。
JDK原生API实现(无框架依赖)
用JDK自带的HttpURLConnection直接指定无代理发起请求:
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.Proxy; import java.net.URL; public String callApiWithoutProxy(String apiUrl) throws Exception { URL url = new URL(apiUrl); // 显式指定无代理打开连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); StringBuilder response = new StringBuilder(); try (InputStream is = connection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is))) { String line; while ((line = br.readLine()) != null) { response.append(line); } } finally { connection.disconnect(); } return response.toString(); }
内容的提问来源于stack exchange,提问作者poo
相关产品推荐
相关产品推荐

