2012-10-17 318 views
0

我正在構建需要登錄到某個頁面並進行導航的應用程序。我可以登錄,只要響應包含一個標識它的字符串。但是,當我導航到第二頁時,我無法將該頁面視爲已登錄的用戶,只能以匿名形式顯示。登錄後丟失會話

我會提供我的代碼:

import java.net.*; 
import java.security.*; 
import java.security.cert.*; 
import javax.net.ssl.*; 
import java.io.*; 
import java.util.*; 

public class PostTest { 
    static HttpsURLConnection conn = null; 
    static String sessionId = null; 
    private static class DefaultTrustManager implements X509TrustManager { 

     @Override 
     public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} 

     @Override 
     public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} 

     @Override 
     public X509Certificate[] getAcceptedIssuers() { 
      return null; 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      SSLContext ctx = SSLContext.getInstance("TLS"); 
      ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); 
      SSLContext.setDefault(ctx); 


      String data = URLEncoder.encode("txtUserName", "UTF-8") + "=" + URLEncoder.encode(/*username*/, "UTF-8"); 
      data += "&" + URLEncoder.encode("txtPassword", "UTF-8") + "=" + URLEncoder.encode(/*password*/", "UTF-8"); 
      data += "&" + URLEncoder.encode("envia", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8"); 

      connectToSSL(/*login url*/); 

        //throws java.lang.IllegalStateException: Already connected 
      conn.setDoOutput(true); 

      OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); 
      wr.write(data); 
      wr.flush(); 

      BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
      String line; 
      String resposta = ""; 
      while((line = rd.readLine()) != null) { 
       resposta += line + "\n"; 
      } 
      System.out.println("valid login -> " + resposta.contains(/*string that assures me I'm looged in*/)); 

      connectToSSL(/*first navigation page*/); 

      rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
      while((line = rd.readLine()) != null) { 
       System.out.println(line); 
      } 


     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    private static void connectToSSL(String address) { 
     try { 
      URL url = new URL(address); 
      conn = (HttpsURLConnection) url.openConnection(); 
      conn.setHostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String arg0, SSLSession arg1) { 
        return true; 
       } 
      }); 
        if(sessionId == null) { 
          sessionId = conn.getHeaderField("Set-Cookie"); 
        } 
     } catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 

任何進一步的信息,只問。

回答

2

connectToSSL中,您每次都打開一個新連接。在第二個連接中,它不會有第一個連接的任何屬性。

您可能希望在第一次登錄連接後設置獲取某個標記/ cookie值,並在隨後的調用中使用該值。

第一連接之後:

 String sessionId = conn.getHeaderField("Set-Cookie"); 

在隨後的連接:

 conn.setRequestProperty("Cookie", sessionId); 
+0

沒錯,我現在看到了。然後,我將如何更改我的連接當前的URL? –

+0

不確定,如果我的問題正確嗎?如果它關於訪問第二個URL,那麼在嘗試從第二個連接打開流之前,除了調用'conn.setRequestProperty()'外,還要做** **。 –

+0

是的,我這樣做了,但我得到一個異常告訴我,我已經打開了一個連接。 –

0

看看在Apache Commons項目HttpClient。它會幫助你做你正在努力完成的事情。你需要比URL類複雜得多的時間。它需要維護大量的信息,從一個認證請求到後續的認證請求。

+0

我會看看,但現在我很好奇如何更改HttpsURLConnection的URL。謝謝,altought。 –

0

您正在訪問的網站可能使用cookie來識別已登錄的會話。您需要保存在第一個請求中設置的cookie,並在隨後的請求中發送它們。

如果您使用HttpsURLConnection的,看到Cookie Managementjava.net.CookieManager。另一種選擇是Apache HttpComponents默認進行cookie管理。

0

http是一種無狀態協議。 保留狀態(會話)存儲從服務器收到的cookie。 List<String> cookies = conn.getHeaderFields().get("Set-Cookie");

它們發送到服務器的後續請求

for (String cookie : cookies) { 

//remove expires and path from cookie

String cookieValue=cookie.substring(0, cookie.indexOf(';'); conn.addRequestProperty("Cookie",cookieValue);
}

OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

wr.write(data);