2012-06-28 33 views
5

Tôi có một ứng dụng khách trên máy tính để bàn gửi dữ liệu đến máy chủ web và dường như tôi không thể truy cập máy chủ proxy.Giao tiếp Java không thành công thông qua proxy web bằng cách sử dụng Apache HttpClient

Cập nhật: Tôi gặp phải lỗi HTTP 407 khi cố giao tiếp thông qua proxy.

Khi tải xuống thông tin từ máy chủ web của tôi, mọi thứ đều ổn. Một khi người dùng cấu hình máy chủ proxy (sử dụng một hộp thoại tôi đã viết) tải xuống hoạt động tốt. Tuy nhiên, việc tải lên dữ liệu bằng cách sử dụng org.apache.http.client.HttpClient không hoạt động.

Tôi định cấu hình máy chủ proxy có mã như sau sau khi thu thập thông tin từ JDialog.

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

Bây giờ, khi chúng tôi làm điều đó, tải xuống đơn giản hoạt động tốt. Ví dụ, tôi có mã đọc một số dữ liệu xml từ máy chủ web của tôi (xem bên dưới). Trên mạng của khách hàng, lỗi trong khối catch của tôi được hiển thị trước khi cài đặt proxy được định cấu hình và sau đó mọi thứ hoạt động tốt khi proxy đã được đặt chính xác.

/** 
* 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; 
} 

Tuy nhiên, khi tôi cố gắng gửi dữ liệu đến máy chủ web, như thể cài đặt proxy bị bỏ qua và IOException bị ném. Cụ thể:

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

Bây giờ tôi biết rằng cổng 8080 không bị chặn bởi bộ lọc web của khách hàng vì chúng tôi đã kiểm tra địa chỉ trong trình duyệt web.

Đây là mã của tôi để xác minh ID đăng ký được người dùng nhập: Cập nhật: Bây giờ tôi cũng đặt proxy trong phương thức này.

//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; 
    } 
} 

Tôi gần như tích cực rằng vấn đề xuất phát từ cấu hình máy chủ proxy, nhưng các docs for SystemDefaultHttpClient tuyên bố rằng nó cần sử dụng thuộc tính hệ thống cho http.proxyHosthttp.proxyPort. Tôi biết rằng các thuộc tính đã được đặt đúng, nhưng tôi vẫn nhận được lỗi xác thực này. Xem nhật ký được tạo từ chương trình của tôi đã cho tôi biết điều này:

checkRegistration INFO: Server response status code to checkRegistration: 407 

Làm cách nào để giải quyết lỗi xác thực này?

+0

Bạn gửi dữ liệu bằng cách nào? một POST? một PUT? GET với các tham số? Xin lỗi, tôi không thể tìm ra câu hỏi của bạn. –

+0

Chúng tôi đang sử dụng GET tại đây. Các phương pháp khác không được hiển thị sử dụng POST. Trong đoạn mã trên, hãy chú ý HttpGet httpget = new HttpGet (uri); – Thorn

+0

Bạn có thể thiết lập một proxy trong môi trường dev của bạn, sau đó trên máy dev của bạn, sử dụng tường lửa để chặn tất cả http đi, khác với proxy? – artbristol

Trả lời

5

Tôi sẽ chụp. Nếu máy chủ proxy được sử dụng xác thực cơ bản, bạn có thể sử dụng đoạn mã sau đây là một ví dụ:

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); 

Nếu máy chủ proxy được sử dụng xác thực NTLM, tôi không tin hỗ trợ NTLM hiện có sẵn cho tất cả các phiên bản máy chủ proxy (nó sẽ làm việc với một số phiên bản máy chủ proxy xác thực NTLM - hãy kiểm tra xem proxy có đang sử dụng xác thực NTLM hoặc v1 hay không).Để tham khảo & cách giải quyết, bạn có thể kiểm tra như sau:

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

Tùy thuộc vào máy chủ proxy của bạn, bạn có thể cần phải nhìn vào NTCredentials thay vì UserPasswordCredentials. Tôi cũng sẽ gợi ý rằng bạn có thể muốn xem xét sử dụng wireshark để nắm bắt các gói mạng và kiểm tra phản hồi từ máy chủ proxy để chắc chắn điều gì đang gây ra sự cố.

+0

Đó có thể là nó. – Thorn

+0

để xác nhận, tôi sẽ đề nghị sử dụng wireshark để nắm bắt các gói mạng. Nếu mất quá nhiều thời gian, bạn có thể xác nhận máy chủ proxy nào (nếu là môi trường công ty, họ có thể có máy chủ proxy trong cài đặt IE hoặc trỏ tới tập lệnh trong cài đặt IE hoặc có thể có ứng dụng máy chủ proxy đang chạy máy tính để bàn để định tuyến lưu lượng truy cập). –

+0

Đề nghị tốt, nhưng wireshark có lẽ là quá giết. Tôi đã xác nhận cài đặt proxy với trình quản lý CNTT cho mạng này. Nhưng ông không bao giờ nói với tôi xác thực là bắt buộc. Khi tôi cố gắng kết nối với máy tính xách tay của mình, tôi đã được yêu cầu nhập tên người dùng/mật khẩu cho máy chủ proxy. Nhưng người dùng đăng nhập vào mạng hợp tác không bao giờ được nhắc nhở về điều này. Nhưng có vẻ như phần mềm của tôi sẽ cần phải nhắc đến nó. – Thorn

1

Chỉ cần cho đầy đủ, kể từ khi câu hỏi này được tìm thấy tìm kiếm bất động sản http.proxy JVM, nếu sử dụng cơ sở hạ tầng JVM tên truy cập và mật khẩu proxy có thể được cung cấp sử dụng:

System.setProperty("http.proxyUser",proxyUserName) 
System.setProperty("http.proxyPassword",proxyUsePassword). 
0

Đối với một số lý do, thiết lập các thông số trên didn khách hàng 't làm việc cho tôi.

Nhưng đã làm việc trên phương pháp http.

Các vấn đề liên quan