zoukankan      html  css  js  c++  java
  • 使用HttpURLConnection请求multipart/form-data类型的form提交

    写一个小程序,模拟Http POST请求来从网站中获取数据。使用Jsoup(http://jsoup.org/)来解析HTML

    Jsoup封装了HttpConnection的功能,可以向服务器提交请求。但分析了目标网站(http://rapdb.dna.affrc.go.jp/tools/converter/run)的数据提交方式后,决定自己用代码来模拟Content-typemultipart/form-dataform表单提交。

    1、HttpURLConnection :A URLConnection with support for HTTP-specific features.一个可以支持HTTPURL连接。

     

    connection.setRequestMethod("POST");
    connection.setConnectTimeout(5 * 60 * 1000);
    connection.setReadTimeout(5 * 60 * 1000);
    connection.addRequestProperty(“User-Agent”, “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36”);
    connection.addRequestProperty(
    "Content-Type", "multipart/form-data; boundary=--testsssssss"); //若需要向服务器请求数据,需要设定为true,默认为false connection.setDoOutput(true); //若提交为post方式,需要修改为false connection.setUseCaches(false); //向报务器连接 Connection.connect(); output = connection.getOutputStream(); //向服务器传送post数据 output.write(bodyStr.getBytes());

     

    向服务器发送请求后,服务器应该能接收到类似的数据:

    POST /test HTTP/1.1
    Accept-Language: zh-CN,zh;q=0.8
    //connection.addestProperty设定的Http请求头信息
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Content-Type: multipart/form-data; boundary=--testsssssss
    Cache-Control: no-cache
    Pragma: no-cache
    Host: localhost
    Connection: keep-alive
    //Http请求的正文大小,未手工设定,程序自动生成?
    Content-Length: 224
    
    --HrOGHuIjDhR_gtUesEBnpWxVp9JH209p
    Content-Disposition: form-data; name="keyword"
    
    test
    --HrOGHuIjDhR_gtUesEBnpWxVp9JH209p
    Content-Disposition: form-data; name="submit"
    
    Convert
    --HrOGHuIjDhR_gtUesEBnpWxVp9JH209p--
    

    2、向服务器请求数据时常用的方式:

      • GET:当form提交时,请求参数拼接在URl上,使用&来分隔。
      • POST:提交form时,请求参数封装在请求body中,可传递大批量数据。请求时数据封装类型有很多种(http://en.wikipedia.org/wiki/Internet_media_type),常用的不多:
        • application/x-www-form-urlencoded 默认的提交方式,同GET类似,将参数组装成Key-value方式,用&分隔,但数据存放在body中提交
        • multipart/form-data 这种方式一般用来上传文件,或大批量数据时。

      该网站的提交方式为post,MIME类型为multipart/form-data类型。需要组装相应的数据。

      该类型的数据提交时需要在HTTP请求头中的content-type添加boundary字段,正文的数据就以该字段来区分:

      

    //boundary为--testsssssss

    connection.addRequestProperty("Content-Type", "multipart/form-data; boundary=--testsssssss");

      在封装Http请求的Body中,要以boundary来区分开各个字段:String mimeBoundary = "--testsssssss";

    StringBuffer sb = new StringBuffer();
    //在boundary关需添加两个横线
    sb = sb.append("--").append(mimeBoundary);
    sb.append("
    ");
    sb.append("Content-Disposition: form-data; name="keyword"");
    //提交的数据前要有两个回车换行
    sb.append("
    
    ");
    sb.append(queryText); sb.append(
    " "); //第二个提交的参数 sb.append("--").append(mimeBoundary); sb.append(" "); sb.append("Content-Disposition: form-data; name="submit""); sb.append(" "); sb.append("Convert"); sb.append(" "); //body结束时 boundary前后各需添加两上横线,最添加添回车换行 sb.append("--").append(mimeBoundary).append("--").append(" ");

      若提交的数据为文件或图片类型,需要读取文件内容。http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

     3、jsoup解析数据:

      jsoup解析HTML代码的方式类似于javascript。

      可以将HttpUrlConnection接收到的html字符串来组装 Document:

      

    Document doc = Jsoup.parse(html);
    //获取html中id为tools_converter的元素
    //假设html代码如:<a id="tools_converter" href="http://localhost">测试</a>
    Element element = doc.getElementById("tools_converter");
    //可获取text的数据为:测试
    String text = element.text();
    //可获得attr的数据为:http://localhost
    String attr = element.attr("href");
    
    //也可以直接使用Jsoup封装的HttpConnection来请求数据器:
    Document document = Jsoup.connect(url)
                    .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36").get();

      Jsoup提供的部分方法如下:

      getElementsByTag(String):按Tag标签来获取:Elements divs = document.getElementsByTag("div")

      getElementById(String):按id标签来获取:Element idEle = document.getElementById("blogId")

      getElementsByClass(String):按CSS的Class名称来获取:Elements divs = document.getElementsByClass("redClass")

      children():返回Elements,某元素的所有子元素。

      child(int index):返回Element,某元素的第几个子元素:

      参考Jsoup API

      

      链接:

      JDK中的URLConnection参数详解

     

  • 相关阅读:
    POJ 2018 二分
    873. Length of Longest Fibonacci Subsequence
    847. Shortest Path Visiting All Nodes
    838. Push Dominoes
    813. Largest Sum of Averages
    801. Minimum Swaps To Make Sequences Increasing
    790. Domino and Tromino Tiling
    764. Largest Plus Sign
    Weekly Contest 128
    746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/zyzl/p/4526914.html
Copyright © 2011-2022 走看看