2012-03-01 108 views
5

我正在嘗試爲校園網絡創建一個登錄應用程序。我已經很遠了,但現在我卡住了。用java提交html表單

我在那裏的Java返回我包含一個簡單的表格應自動提交頁面的一點:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
<body onload="document.forms[0].submit()">  
<noscript>  
    <p>  
     <strong>Note:</strong> Since your browser does not support JavaScript,    you must press the Continue button once to proceed.    
    </p>   
</noscript>     

<form action="url" method="post"> 
    <div> 
     <input type="hidden" name="RelayState" value="ss:mem:43141e4108638211a81427d145c7e9de"/>   

     <input type="hidden" name="SAMLResponse" value="base64string"/>   
    </div>  
    <noscript>   
     <div>  
      <input type="submit" value="Continue"/>  
     </div>  
    </noscript>  
</form>  
</body></html> 

當我複製此字符串到一個.html文件,並點擊提交,它記錄我很好。現在,我試圖做到這一點在Java中,所以我提取的RelayState和SAMLResponse和使用下面的代碼提交:

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

String params = "RelayState="+relayState+"&SAMLResponse="+saml; 
System.out.println(params.length()); 

urlConnection.setRequestMethod("POST"); 
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
urlConnection.setRequestProperty("Content-Length", Integer.toString(params.getBytes().length)); 
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2"); 


urlConnection.setDoInput(true); 
urlConnection.setDoOutput(true); 

DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream()); 
wr.writeBytes(params); 
wr.flush(); 
wr.close(); 

InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 

DataInputStream dis = new DataInputStream(new BufferedInputStream(in)); 

String fullPage = ""; 
String s; 
while ((s = dis.readLine()) != null) 
{ 
    fullPage += s; 
} 

urlConnection.disconnect(); 

此代碼返回一個500 - 內部服務器錯誤。我錯過了什麼?

爲了測試正在發送的內容,我改變了鏈接到一個簡單的print_r($ _ POST)和print_r的(getallheaders()可以),這是我得到:

//when I submit using java: 
Array( 
    [Accept] => text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2  
    [Connection] => keep-alive  
    [Content-Length] => 14176  
    [Content-Type] => application/x-www-form-urlencoded  
    [Host] => xxx 
    [User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 
) 

Array( 
    [RelayState] => ss:mem:43141e4108638211a81427d145c7e9de 
    [SAMLResponse] => base64string 
) 



//when I submit by copying the string to my browser and clicking submit 
Array 
(
    [Accept] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
    [Accept-Encoding] => gzip, deflate 
    [Accept-Language] => en-us,en;q=0.5 
    [Connection] => keep-alive 
    [Content-Length] => 14204 
    [Content-Type] => application/x-www-form-urlencoded 
    [DNT] => 1 
    [Host] => xxx 
    [User-Agent] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 
) 
Array 
(
    [RelayState] => ss:mem:43141e4108638211a81427d145c7e9de 
    [SAMLResponse] => base64string 
) 

我注意到內容 - 在這兩種情況下,長度標題並不相同,但我不知道這是爲什麼,或者與此有什麼關係。

+0

嘗試獲取有關此錯誤500的更多詳細信息。檢查cookie。也許你應該有一個會議ID somwhere。 String.getBytes()使用平臺默認字符串將字符轉換爲字節。嘗試指定字符集(例如ISO-8859-2)。 – 2012-03-01 14:31:13

+1

不一定與您的問題有關,但我使用Apache Commons中的類HttpClient來完成這種工作 - http://hc.apache.org/httpclient-3.x/ – 2012-03-01 14:40:07

+0

我已經使用DefaultHttpClient。我也有'CookieHandler.setDefault(新的CookieManager(null,CookiePolicy.ACCEPT_ALL));'在我的代碼頂部。 – Dauntless 2012-03-01 17:50:40

回答

2

如果您有權訪問服務器日誌,它可以提供幫助。發生內部服務器錯誤時會引發狀態500。這意味着您正在做某些,無法由服務器成功處理。

如果您無法訪問服務器,請嘗試以下操作。 首先,再次檢查從java發送的請求(幾乎)與從瀏覽器發送的請求相同。你可以爲此使用WireShark。

如果您認爲一切正常,但仍然無法正常工作,原因在於您無國籍。當瀏覽器第一次到達該站點時,它會接收到作爲特殊cookie發送的會話ID。 Cookies響應標題爲Set-Cookie。瀏覽器獲取該標題的內容並將其作爲請求標題「Cookie」發回。這是你的應用程序和瀏覽器的區別。

理論上,服務器不應該在此請求上失敗。它只是應該再次將您重定向到登錄頁面。但似乎在服務器端存在一個錯誤:它只是無法處理您的「錯誤」請求並拋出異常。

順便說一句,如果你想讓事情變得更容易用戶從jakarta.apache.org HttpClient。它支持會話完整模式,所以你不必處理HTTP協議的血腥細節。但是如果你願意的話,你也可以使用常規的HttpConnection。 \

祝你好運。

+0

用於提示Wireshark。這麼好用,感覺就像在作弊! – TMN 2012-03-01 15:15:56

+0

我忘了提及實際的網址是https,所以我打賭我不能真正使用WireShark。 (我沒有自己的服務器) 另外,我首先運行一個java程序,它以這個html表單字符串結束。然後我將它複製到一個temp.html文件並在瀏覽器中打開它。當我點擊'提交'時,它會登錄我。由於我的瀏覽器和JRE不共享cookie,我不認爲這是一個州/ cookie問題(糾正我,如果我錯了) 正如我在我的其他評論中說的,我使用Apache的DefaultHttpClient。這與你所建議的不一樣嗎? – Dauntless 2012-03-01 17:54:55