2012-10-17 254 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);