当前位置: 首页 > 面试题库 >

Java通信通过使用Apache HttpClient的Web代理失败

公良浩邈
2023-03-14
问题内容

我有一个将数据发送到Web服务器的桌面客户端,但是我似乎无法通过代理服务器。

更新 :尝试通过代理进行通信时,我收到407 HTTP错误。

从我的Web服务器下载信息时,一切都很好。用户配置代理服务器后(使用我编写的对话框),下载工作正常。但是使用org.apache.http.client.HttpClient上传数据不起作用。

从JDialog收集信息后,我将使用以下代码配置代理服务器。

        System.setProperty("http.proxyHost", proxyHost);
        System.setProperty("http.proxyPort", "" + portNumber);

现在,一旦我们这样做,简单的下载就可以正常工作。例如,我有从我的Web服务器读取一些xml数据的代码(请参见下文)。在客户的网络上,在配置代理服务器设置之前就显示了我的catch块中的错误,然后在设置了正确的代理服务器后一切正常。

/**
 * Loads a collection of exams from the web site. The URL is determined by
 * configuration or registration since it is State specific.
 */
public static int importExamsWS(StringBuilder msg) {
    try {
        java.net.URL onlineExams = new URL(examURL);
        //Parse the XML data from InputStream and store it.
        return importExams(onlineExams.openStream(), msg);

    } 
    catch (java.net.UnknownHostException noDNS) {
        showError(noDNS, "Unable to connect to proctinator.com to download the exam file.\n"
                + "There is probably a problem with your Internet proxy settings.");
    }
    catch (MalformedURLException | IOException duh) {
        showFileError(duh);
    }
    return 0;
}

但是,当我尝试将数据发送到Web服务器时,就好像代理设置被忽略并且抛出IOException一样。即:

org.apache.http.conn.HttpHostConnectException: Connection to http://proctinator.com:8080 refused

现在,我知道客户的Web过滤器未阻止端口8080,因为我们在Web浏览器中测试了该地址。

这是我用于验证用户输入的注册ID的代码: 更新:现在,我也在此方法中设置了代理。

//Registered is just an enum with ACTIVE, INACTIVE, NOTFOUND, ERROR
public static Registered checkRegistration(int id) throws IOException {    
    httpclient = new DefaultHttpClient();
    Config pref = Config.getConfig(); //stores user-entered proxy settings.
    HttpHost proxy = new HttpHost(pref.getProxyServer(), pref.getProxyPort());
    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
    URIBuilder builder = new URIBuilder();
    String path = "/Proctorest/rsc/register/" + id;
    try {
        builder.setScheme("http").setHost(server).setPort(8080).setPath(path);
        URI uri = builder.build();
        System.out.println("Connecting to " + uri.toString());
        HttpGet httpget = new HttpGet(uri);
        HttpResponse response = httpclient.execute(httpget);
        System.out.println(response.getStatusLine().toString());
        if(response.getStatusLine().getStatusCode()==200) {
            String msg = EntityUtils.toString(response.getEntity());
            GUI.globalLog.log(Level.INFO, "Server response to checkRegistration(" + id + "): " + msg);
            return Registered.stringToRegistered(msg);
        }
        else {
            GUI.globalLog.log(Level.INFO, "Server response status code to checkRegistration: " + 
                    response.getStatusLine().getStatusCode());
            return Registered.ERROR;
        }
    }
    catch(java.net.URISyntaxException bad) {
        System.out.println("URI construction error: " + bad.toString());
        return Registered.ERROR;
    }
}

我几乎肯定地说,问题出在代理服务器配置上,但是SystemDefaultHttpClient的文档声称它对http.proxyHost和使用了System属性
http.proxyPort。我知道属性已正确设置,但是仍然出现此身份验证错误。查看从我的程序生成的日志,向我显示了以下内容:

checkRegistration INFO: Server response status code to checkRegistration: 407

如何解决此身份验证错误?


问题答案:

我会开枪。如果代理服务器使用的是基本身份验证,则可以使用以下代码段作为示例:

DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
    new AuthScope("PROXY HOST", 8080),
    new UsernamePasswordCredentials("username", "password"));

HttpHost targetHost = new HttpHost("TARGET HOST", 443, "https");
HttpHost proxy = new HttpHost("PROXY HOST", 8080);

httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

如果代理服务器正在使用NTLM身份验证,则我不认为NTLM支持可用于所有代理服务器版本(它将与某些NTLM身份验证代理服务器版本一起使用-
检查代理是否正在使用v1或v2的NTLM身份验证)。有关参考和解决方法,您可以检查以下内容:

http://hc.apache.org/httpcomponents-client-
ga/ntlm.html

http://htmlunit.sourceforge.net/ntlm.html

http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-
apache.html

根据您的代理服务器,您可能需要查看NTCredentials而不是UserPasswordCredentials。

我还建议您不妨考虑使用Wireshark捕获网络数据包并检查代理服务器的响应,以完全确定是什么引起了该问题。



 类似资料:
  • 我读过一些文章,其中他们建议使用手动密钥,我在上面也这样做了,但身份验证仍然失败。我错过了什么?

  • 问题内容: 我需要将node-XMLHttpRequest应用程序部署到使用代理访问Internet的服务器上。在该服务器上的终端中,我可以并且运行正常。我认为在这种情况下可以识别环境变量。节点应用超时,因为它看不到代理。如何获取节点应用程序以使用代理? 例如,我可以使用http.globalAgent通过代理发送请求吗? 问题答案: 该派生添加了一个配置对象,该对象可以指定要使用的代理。 htt

  • 问题内容: 在程序中使用用户身份验证的代理的最佳/最简便方法是什么?我目前有这个,但是打开浏览器时我需要输入用户名和密码。 问题答案: 您可以使用Proxy Auto auth插件实现相同的功能 使用以下扩展程序下载扩展程序 https://chrome.google.com/webstore/detail/get- crx/dijpllakibenlejkbajahncialkbdkjc/rel

  • 如果我在端口80上的有一个mongo。我不能打开这里的任何端口。我如何用Java连接到它? 这不起作用: 30sec后的例外情况: 在server.com/dbname上连接时出错:等待与ReadPreferenceServerSelector{ReadPreference=Primary}匹配得服务器时,在30000 ms后超时.群集状态的客户端视图为{type=unknown,servers=

  • 我尝试做的是:Processing 3通过我的网络摄像头接收一种二维码-- 问题是:Processing 3和Unity都使用相同的端口(COM4,9600)。这将导致Unity中出现IO异常,表示“访问被拒绝”,随后出现串行端口未打开的错误。 处理3代码 Arduino代码 统一代码 我们显然无法在Unity中打开端口,因为它已经被处理3使用。如何解决这个问题?通信流: 最终,Unity需要根据

  • 5.4 通过 HTTPS 的通信 大多数智能手机应用都与互联网上的 Web 服务器通信。 作为通信的方法,我们在这里集中讨论 HTTP 和 HTTPS 的两种方法。 从安全角度来看,HTTPS 通信更为可取。 最近,Google 或 Facebook 等主要 Web 服务已经开始使用 HTTPS 作为默认设置。 自 2012 年以来,Android 应用中 HTTPS 通信实现的许多缺陷已被指出。