JAVA通過代理訪問外部資源__JAVA

來源:互聯網
上載者:User

代碼中通過代理訪問外部資源
目前網路上最流行的協議就是HTTP協議。HTTP協議有許多優點,例如它能夠穿越防火牆。同時HTTP也是很多其他協議的基礎,例如SOAP協議就是建立在HTTP協議之上的。

Java通過兩種API對HTTP提供支援,一種是servlet API,它覆蓋了伺服器端的編程問題;另一種是java.net包,它通過HttpURLConnection類在用戶端提供了對HTTP協議的支援。但是我在使用servlet API的時候曾經遇到過一些問題。本文將介紹我曾遇到過的一些問題和相應的解決辦法。

基礎知識

通常在商業網路中,一個終端通過Proxy 伺服器同互連網串連起來,Proxy 伺服器負責監視網路流量和執行安全規則。在java.net API中,軟體可以通過兩個屬性來支援Proxy 伺服器,它們分別是http.proxyHost和http.proxyPort。它們必須被設定為相應的Proxy 伺服器和連接埠,下面的代碼展示了如何設定這兩個屬性:

String url = "http://www.digitalcq.com/",
   proxy = "proxy.digitalcq.com",
   port = "8080";
URL server = new URL(url);
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port);
HttpURLConnection connection = (
    HttpURLConnection)server.openConnection();
connection.connect();
InputStream in = connection.getInputStream();
readResponse(in);
 


在上面的程式中,你需要根據實際情況設定Proxy 伺服器和連接埠。如果你不知道該如何設定的話,可以詢問你們公司的網路系統管理員。

使用驗證

通常公司會要求員工在串連到互連網之前登入到Proxy 伺服器。通過登入這種機制使公司可以更好的監控員工對互連網的使用,例如監控員工都訪問了哪些網站。HttpURLConnection通過驗證類支援Proxy 伺服器驗證。下面是一個如何利用HttpURLConnection類進行驗證的例子。首先需要實現一個驗證者:

public class SimpleAuthenticator
   extends Authenticator
{
   private String username,
                  password;
    public SimpleAuthenticator(String username,String password)
   {
      this.username = username;
      this.password = password;
   }
    protected PasswordAuthentication getPasswordAuthentication()
   {
      return new PasswordAuthentication(
             username,password.toCharArray());
   }
}
 


然後,通過Authenticator.setDefault()方法註冊驗證者:

String url = "http://www.digitalcq.com/",
       proxy = "proxy.digitalcq.com",
       port = "8080",
       username = "usr",
       password = "pwd";
Authenticator.setDefault(new SimpleAuthenticator(
       username,password));
URL server = new URL(url);
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost",proxy);
systemProperties.setProperty("http.proxyPort",port);
HttpURLConnection connection = (
    HttpURLConnection)server.openConnection();
connection.connect();
InputStream in = connection.getInputStream();
readResponse(in);
 


問題

上面介紹的都是HttpURLConnection類能夠正常工作的情況。但是我在實際情況中遇到了一些網路,在這些網路中,HttpURLConnection類無法正常工作。最後我發現關鍵的問題在於使用了不正確的DNS配置。在實際情況中,HttpURLConnection類總是先嘗試利用DNS伺服器來解析位址名稱。通常情況下,這種嘗試會失敗,而Proxy 伺服器會將串連重新定向。但是某些DNS伺服器會返回一些不正確的響應,從而導致程式拋出UnknownHostException異常。作為一個程式員,系統不會為了你的程式更改DNS伺服器的配置,因此你需要找出解決這個問題的方法。我的方案是通過自己實現HTTP協議來解決這個問題。例如一個GET命令可以用下面的代碼來實現:

String url = "http://www.digitalcq.com/",
       proxy = "proxy.digitalcq.com",
       port = "8080",
       authentication = "usr:pwd";
URL server = new URL(url);
Socket socket = new Socket(proxy,port);
Writer writer = new OutputStreamWriter(socket.getOutputStream(),
                                       "US-ASCII");
writer.write("GET " + server.toExternalForm() + " HTTP/1.0/r/n");
writer.write("Host: " + server.getHost() + "/r/n");
writer.write("Proxy-Authorization: Basic "
             + new sun.misc.BASE64Encoder().encode(
               authentication.getBytes())
             + "/r/n/r/n");
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(
                            socket.getInputStream(),"US-ASCII"));
String line = reader.readLine();
if(line != null && line.startsWith("HTTP/"))
{
   int sp = line.indexOf(' ');
   String status = line.substring(sp + 1,sp + 4);
   if(status.equals("200"))
   {
      while(line.length() != 0)
         line = reader.readLine();
      readResponse(reader);
   }
   else
      throw new FileNotFoundException("Host reports error " +
                                       status);
}
else
   throw new IOException("Bad protocol");
reader.close();
writer.close();
socket.close();
 


在上面的代碼中,大家可以注意到Proxy 伺服器的使用者名稱和密碼的格式是:

username:password,

並且程式對它們基於Base 64進行了編碼。如果需要參考HTTP協議,可以到http://www.ietf.org/rfc/rfc2616.txt。  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.