zoukankan      html  css  js  c++  java
  • HTTP通信模拟表单提交数据

      前面记录过一篇关于http通信,发送数据的文章:http://www.cnblogs.com/hyyq/p/7089040.html,今天要记录的是如何通过http模拟表单提交数据

    一、通过GET请求方式提交:最简单的一种方式

      直接在链接后面跟上要提交的数据即可,比如: http://yychf.55555.io/get.do?username=yyc&password=yychf,通过http直接发送。然后在服务器端可以通过request.getParameter()方法来获得参数值。如要获得参数username的值可以通过request.getParameter("username");

    二、通过POST请求方式提交:发送更多数据

      post请求方式参数比较隐蔽,数据的传输在请求的数据体中。一般来说,我们用POST提交表单会出现在前端html代码中,通过submit将数据提交到表单地址中,现在需要通过纯java代码实现表单的提交。其实原理也很简单,主要需要注意以下两点:

    1. 作为表单提交数据,需要设置它的请求头,主要是Content-Type的值, 这里的值是application/x-www-form-urlencoded
    2. 需要将参数转换成如key1=urlencode(value1)&key2=urlencode(value2)的形式,这里的urlencode是指将参数值用urlencode编码,其实就是是将表单字段和经过编码的字段值经过组合以数据体的方式做了参数传递。

      下面是具体实现代码:

      1 /**
      2      * 发起http请求
      3      * 发送参数(仿表单提交效果):
      4      * 基本思路:1.请求头“Content-Type”的值为“application/x-www-form-urlencoded”
      5      *           2.将参数拼接成key=value形式的字符串post提交
      6      *            注意:key=value中key,value即参数名、值不能有中文字符,
      7      *            所以发送的数据就是key1=urlencode(value1)&key2=urlencode(value2)&...形式的字符串
      8      * @param urlString
      9      * @param formProperties
     10      * @return
     11      * @throws Exception
     12      */
     13     public static byte[] httpRequestPostForm(String urlString,Properties formProperties) throws Exception{
     14 
     15         //设置http请求头信息
     16         Properties requestProperties = new Properties();
     17         requestProperties.setProperty("Content-Type", "application/x-www-form-urlencoded");
     18 
     19 
     20         //将需要发送的参数拼接成key1=urlencode(value1)&key2=urlencode(value2)&...形式的字符串
     21         StringBuilder sb = new StringBuilder();
     22         if ((formProperties != null) && (formProperties.size() > 0)) {
     23             for (Map.Entry<Object, Object> entry : formProperties.entrySet()) {
     24                 String key = String.valueOf(entry.getKey());
     25                 String value = String.valueOf(entry.getValue());
     26                 sb.append(key);
     27                 sb.append("=");
     28                 sb.append(encode(value));//urlencode编码
     29                 sb.append("&");
     30             }
     31         }
     32 
     33         String str = sb.toString();
     34         str = str.substring(0, (str.length() - 1)); // 截掉末尾字符“&”
     35 
     36         return requestPost(urlString, str.getBytes("UTF-8"), requestProperties);
     37     }
     38 
     39 
     40     /**
     41      * 发送http请求,并获取返回的数据
     42      * @param urlString
     43      * @param requestData
     44      * @param requestProperties
     45      * @return
     46      * @throws Exception
     47      */
     48     private static byte[] requestPost(String urlString, byte[] requestData, Properties requestProperties)
     49             throws Exception {
     50         byte[] responseData = null;
     51         HttpURLConnection con = null;
     52 
     53         try {
     54             URL url = new URL(urlString);
     55             con = (HttpURLConnection) url.openConnection();
     56 
     57             if ((requestProperties != null) && (requestProperties.size() > 0)) {//设置请求头信息
     58                 for (Map.Entry<Object, Object> entry : requestProperties
     59                         .entrySet()) {
     60                     String key = String.valueOf(entry.getKey());
     61                     String value = String.valueOf(entry.getValue());
     62                     con.setRequestProperty(key, value);
     63                 }
     64             }
     65 
     66             con.setRequestMethod("POST"); // 置为POST方法
     67 
     68             con.setDoInput(true); // 开启输入流
     69             con.setDoOutput(true); // 开启输出流
     70 
     71             // 如果请求数据不为空,输出该数据。
     72             if (requestData != null) {
     73                 DataOutputStream dos = new DataOutputStream(con
     74                         .getOutputStream());
     75                 dos.write(requestData);
     76                 dos.flush();
     77                 dos.close();
     78             }
     79 
     80             int length = con.getContentLength();
     81             // 如果回复消息长度不为-1,读取该消息。
     82             if (length != -1) {
     83                 DataInputStream dis = new DataInputStream(con.getInputStream());
     84                 responseData = new byte[length];
     85                 dis.readFully(responseData);
     86                 dis.close();
     87             }
     88         } catch (Exception e) {
     89             throw e;
     90         } finally {
     91             if (con != null) {
     92                 con.disconnect();
     93             }
     94         }
     95 
     96         return responseData;
     97     }
     98 
     99 
    100     /**
    101      * url解码
    102      *
    103      * @param url
    104      * @return 解码后的字符串,当异常时返回原始字符串。
    105      */
    106     private static String decode(String url) {
    107         try {
    108             return URLDecoder.decode(url, "UTF-8");
    109         } catch (UnsupportedEncodingException ex) {
    110             return url;
    111         }
    112     }
    113 
    114     /**
    115      * url编码
    116      *
    117      * @param url
    118      * @return 编码后的字符串,当异常时返回原始字符串。
    119      */
    120     private static String encode(String url) {
    121         try {
    122             return URLEncoder.encode(url, "UTF-8");
    123         } catch (UnsupportedEncodingException ex) {
    124             return url;
    125         }
    126     }

      发送数据前,需要将数据放入Properties对象中再传入,这是java.util包中的一个工具类,本来主要作用是读取java中以.properties结尾的配置文件,关于这个推荐http://www.cnblogs.com/hyyq/p/7399525.html 。当然,这里完全也可以用Map集合来实现。

      发送数据后,服务端可以通过request.getParameter()方法来获得参数值,也可以通过request.getParameterMap()来获取,它返回的是一个Map<String,String[]>类型的值,因为我们知道表单有 如性别之类的属性是有两个值的。

      小结:通过http模拟表单提交数据,其实和普通的数据提交也是换汤不换药。

      参考:http://blog.163.com/xing_mu_1/blog/static/6614290201031310207158/

  • 相关阅读:
    康复计划
    Leetcode 08.02 迷路的机器人 缓存加回溯
    Leetcode 38 外观数列
    Leetcode 801 使序列递增的最小交换次数
    Leetcode 1143 最长公共子序列
    Leetcode 11 盛水最多的容器 贪心算法
    Leetcode 1186 删除一次得到子数组最大和
    Leetcode 300 最长上升子序列
    Leetcode95 不同的二叉搜索树II 精致的分治
    Leetcode 1367 二叉树中的列表 DFS
  • 原文地址:https://www.cnblogs.com/hyyq/p/7425411.html
Copyright © 2011-2022 走看看