2012-01-22 33 views
0

我需要做的是将Java直接导入到HTTPS网页,接受所有证书,填写表单,通过POST提交数据,然后输出结果页面。在Java中这怎么可能(特别是在Android应用程序的范围内)?使用Java输入并向HTTPS网站提交POST表单

我从“http://alien.dowling.edu/~vassil/tutorials/javapost.php”和Kevin的答案“http://stackoverflow.com/questions/1828775/httpclient-”中汇总了下面的代码-ssl“,但打印BufferedReader只打印填充信息而不是结果页面源的表单。

调用提交时,使用JavaScript在页面上运行脚本,并且URL本身不会更改,但页面内容确实会更改以反映脚本的返回结果。但是,当前程序仍然不会返回新更新页面的来源。 - Paradius刚才

你们中的任何人都可以告诉我这段代码出错的地方吗?提前致谢!

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

import java.security.SecureRandom; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

public class JavaPOST 
{ 

    public static void doSubmit(String url, Map<String, String> data) throws Exception 
    { 

      //SSL Certificate Acceptor 
      SSLContext ctx = SSLContext.getInstance("TLS"); 
      ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); 
      SSLContext.setDefault(ctx); 

      URL siteUrl = new URL(url); 
      HttpsURLConnection conn = (HttpsURLConnection)siteUrl.openConnection(); 
      conn.setRequestMethod("POST"); 
      conn.setDoOutput(true); 
      conn.setDoInput(true); 

      conn.setHostnameVerifier(
      new HostnameVerifier() 
      { 
       @Override 
       public boolean verify(String arg0, SSLSession arg1) 
       { 
        return true; 
       } 
      }); 

      DataOutputStream out = new DataOutputStream(conn.getOutputStream()); 

      Set keys = data.keySet(); 
      Iterator keyIter = keys.iterator(); 
      String content = ""; 
      for(int i=0; keyIter.hasNext(); i++) 
      { 
       Object key = keyIter.next(); 
       if(i!=0) 
       { 
        content += "&"; 
       } 
       content += key + "=" + URLEncoder.encode(data.get(key), "UTF-8"); 
      }   
      //System.out.println(content); 
      out.writeBytes(content); 
      out.flush(); 
      out.close(); 
      BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
      String line = ""; 
      while((line=in.readLine())!=null) 
      { 
       System.out.println(line); 
      } 

      System.out.println(conn.getURL()); 

    } 

    public static void main(String[] args) 
    { 
     Map<String, String> data = new HashMap<String, String>(); 
     data.put("start_time", "103000"); 
     data.put("end_time", "210000"); 

     try 
     { 
      doSubmit("https://somedomain/webpage.html", data); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

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

    } 

回答

0

首先:不要使用化妆转变,信任大家X509TrustManager,这是一个坏主意。如果您对服务器使用自签名证书,请将其嵌入到应用程序中,并使用它初始化信任管理器。有很多关于如何正确使用它的文章。

如果您的POST后重定向到HTTP页面(而不是 HTTPS),HttpURLConnection将不会自动执行重定向。您必须手动解析响应(检查状态码302等),并使用另一个HttpURLConnection实例获取该页面。

+0

事实证明,我忘记提到当调用submit时,使用JavaScript在页面上运行脚本,并且URL本身不会更改,但页面内容确实会发生变化以反映脚本的返回结果。但是,当前程序仍然不会返回新更新页面的来源。 – Paradius

+0

那么,你的Android客户端对JavaScript一无所知,所以它不可能得到结果。如果您需要运行脚本,则可能需要使用WebView。 –

+0

如果页面本身运行脚本页面将用户重定向到同一页面但具有不同的外观并因此具有不同的来源,那么这甚至是真的吗? – Paradius