Java 代理背后的未知后异常

Java 代理背后的未知后异常,java,networking,proxy,Java,Networking,Proxy,我有一个java程序,它连接到一个网站,从中检索一些XML。这在我的电脑上,以及我们公司以外的其他电脑上都能正常工作。我们的一个客户现在无法连接到该网站。我发现他们背后有个代理人。我现在已经找到了我需要使用的设置,并且在我的测试程序中它可以工作(部分) 在下面的代码中,downloadFile()调用按预期工作,文件可以顺利下载。contactHost()在我们的客户机上失败,出现未知的后异常: java.net.UnknownHostException: No such host is kno

我有一个java程序,它连接到一个网站,从中检索一些XML。这在我的电脑上,以及我们公司以外的其他电脑上都能正常工作。我们的一个客户现在无法连接到该网站。我发现他们背后有个代理人。我现在已经找到了我需要使用的设置,并且在我的测试程序中它可以工作(部分)

在下面的代码中,
downloadFile()
调用按预期工作,文件可以顺利下载。
contactHost()
在我们的客户机上失败,出现未知的后异常:

java.net.UnknownHostException: No such host is known (api.myserver.de)
    at java.base/java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
    at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:925)
    at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1505)
    at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:844)
    at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1495)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1354)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1288)
    at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:45)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:111)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
背景:Windows 10机器,我们的程序附带内部OpenJDK版本“10.0.2”2018-07-17。为了仅使用IP4,并启用代理的基本身份验证,该程序使用以下定义启动:Djdk.http.auth.tunneling.disabledSchemes=“”-Djava.net.preferIPv4Stack=true。通过这些设置,可以下载文件,但是未知的hostException仍然存在

我们还尝试在浏览器中打开使用过的URL,这是例外,即在浏览器中打开网站

以下是我的测试代码:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;

public class LFTProxyTest {

private static String uname = null;
private static String pass = null;

public static void main(String[] args) {
    System.setProperty("java.net.useSystemProxies", "true");
    // uname = "test"; // whatever that user provides
    // pass = "sectret"; // whatever that user provides
    Authenticator.setDefault(new ProxyAuth(uname, pass));

    contactHost();
    downloadFile();
}

private static boolean downloadFile() {
    System.out.println("CHECK connection");
    int cp = contactHost();
    if (cp == 200)
        return true;
    if (cp == 407)
        return false;
    else {
        try {
            System.out.println("Try loading file: ");
            URL url = new URL("https://www.google.de");
            URLConnection urlConnection = url.openConnection();
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            dBuilder.parse(in);
            System.out.println("    FILE DOWNLOAD successfull!");
        } catch (Exception e) {
            System.out.println("    FILE DOWNLOAD failed:");
            System.out.println("***EXCEPTION: " + e.getMessage());
            return false;
        }
    }
    System.out.println("CHECK done");
    return true;
}

private static int contactHost() {
    HttpClient client = HttpClientBuilder.create().build();// new DefaultHttpClient();
    String catalogURI = "https://api.myserver.de/query";
    HttpGet request = new HttpGet(catalogURI);
    try {
        int ret = 0;
        HttpResponse response = client.execute(request);
        ret = response.getStatusLine().getStatusCode();
        System.out.println("PROXY test: " + ret);
        ((CloseableHttpClient) client).close();
        return ret;
    } catch (IOException e) {
        e.printStackTrace();
        return -1;
    }
}

}

我不知道你知道什么,我甚至不知道错误在哪里。任何想法都将受到高度赞赏

UnknownHostException表示一个非常直接的问题。无法解析您尝试访问的远程主机的IP地址。所以解决这个问题的方法很简单。您应该检查Socket(或任何其他抛出未知hostException的方法)的输入,并验证它是否是预期的输入。如果不确定是否具有正确的主机名,则可以启动UNIX终端并使用nslookup命令(以及其他命令)查看DNS服务器是否能够成功地将主机名解析为IP地址


如果您在Windows上,则可以使用host命令。如果这不符合预期,那么您应该检查主机名是否正确,然后尝试刷新DNS缓存。如果这也不起作用,尝试使用不同的DNS服务器,例如Google Public DNS是一个很好的选择。

好的,所以在进一步挖掘之后,我发现
org.apache.http.client.HttpClient
根本不尊重
java.net.useSystemProxies
,无论是通过
System
还是通过
-D
设置的。它还忽略了http.proxyHost等。解决方案是使用如下ProxySelector:

    ProxySelector.setDefault(new ProxySelector() {

        @Override
        public List<Proxy> select(URI uri) {
            ArrayList<Proxy> list = new ArrayList<Proxy>(); 
            list.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy1.de", 8000)));
            list.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy2.de", 8080)));
            return list;
        }

        @Override
        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
            logger.error("Error in ProxySelector, connection Failed: ", ioe);
        }
    });
ProxySelector.setDefault(新的ProxySelector(){
@凌驾
公共列表选择(URI){
ArrayList=新建ArrayList();
添加(新代理(Proxy.Type.HTTP,新的InetSocketAddress(“proxy1.de”,8000));
添加(新的代理(Proxy.Type.HTTP,新的InetSocketAddress(“proxy2.de”,8080));
退货清单;
}
@凌驾
public void connectFailed(URI、SocketAddress sa、IOException ioe){
logger.error(“代理选择器中出错,连接失败:”,ioe);
}
});

我现在遇到另一个异常,但我可能会为此打开另一个线程。

哦,我忘了提到,我们已经检查了主机是否正常工作。我们复制了代码中使用的主机地址(从日志中),并在浏览器中打开了该地址,没有问题……您是否从源(您的客户端)进行了所有检查?来自代理?显然,客户端上的未知主机异常是DNS问题,可能您的客户端无法解析代理的主机。我想。我们现在已经尝试通过-D和System.setProperty设置此选项,但这并没有解决问题,抱歉。我们仍然有未知的例外