当前位置: 首页 > 图灵资讯 > 技术篇> HttpURLConnection学习

HttpURLConnection学习

来源:图灵教育
时间:2023-05-24 09:20:26

最常用的HTTP请求无非是get和post。get请求可以获得静态页面,也可以将参数放在URL字串后面,传递给servlet。post和get的区别在于post的参数不是放在URL字串中,而是放在http请求的文本中。

HttpurLConection可用于Java中发起这两个要求,了解这些要求对于理解soap和编写servlet的自动测试代码非常有帮助。

以下代码简要描述了如何使用HttpurLConection发起这两个请求,以及传输参数的方法:

public     class   HttpInvoker {       public     static     final   String GET_URL   =     "  http://localhost:8080/welcome1  "  ;       public     static     final   String POST_URL   =     "  http://localhost:8080/welcome1  "  ;       public     static     void   readContentFromGet()   throws   IOException {           //   拼凑get请求的URL字串,使用URLEncoder.encode编码特殊和不可见的字符            String getURL   =   GET_URL   +     "  ?username=  "                     +   URLEncoder.encode(  "  fat man  "  ,   "  utf-8  "  );         URL getUrl   =     new   URL(getURL);           //   打开连接,根据拼凑URL,URL.根据URL的类型,openconection函数,           //   回到URLConection子类的不同对象,这里URL是http,因此,HttpurLConection实际返回            HttpURLConnection connection   =   (HttpURLConnection) getUrl                 .openConnection();           //   进行连接,但实际上是get request应该在下一句conection中.getInputStream()函数只会真正发送到           //   服务器            connection.connect();           //   获取输入流,用Reader读取            BufferedReader reader   =     new   BufferedReader(  new   InputStreamReader(                 connection.getInputStream()));         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of get request  "  );         System.out.println(  "  =============================  "  );         String lines;           while   ((lines   =   reader.readLine())   !=     null  ) {             System.out.println(lines);         }         reader.close();           //   断开连接            connection.disconnect();         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of get request ends  "  );         System.out.println(  "  =============================  "  );     }       public     static     void   readContentFromPost()   throws   IOException {           //   Post请求的url,与get不同的是,不需要带参数            URL postUrl   =     new   URL(POST_URL);           //   打开连接            HttpURLConnection connection   =   (HttpURLConnection) postUrl                 .openConnection();           //   Output to the connection. Default is           //   false, set to true because post           //   method must write something to the           //   connection           //   设置是否输出到connection,因为这是post请求,参数要放在           //   http正文中,因此,需要设置为true            connection.setDoOutput(  true  );           //   Read from the connection. Default is true.            connection.setDoInput(  true  );           //   Set the post method. Default is GET            connection.setRequestMethod(  "  POST  "  );           //   Post cannot use caches           //   Post 请求不能使用缓存            connection.setUseCaches(  false  );           //   This method takes effects to           //   every instances of this class.           //   URLConnection.static函数是static函数,setfollowredirects。作用于所有URLConection对象。           //   connection.setFollowRedirects(true);           //   This methods only           //   takes effacts to this           //   instance.           //   URLConnection.setinstancefollowredirects是成员函数,仅用于当前函数            connection.setInstanceFollowRedirects(  true  );           //   Set the content type to urlencoded,           //   because we will write           //   some URL-encoded content to the           //   connection. Settings above must be set before connect!           //   配置本连接的Contentent-type,application配置x-www-form-urlencoded           //   意思是文本是urlencoded编码的form参数,我们可以看到URLEncoder用于正文内容.encode           //   进行编码            connection.setRequestProperty(  "  Content-Type  "  ,                   "  application/x-www-form-urlencoded  "  );           //   从posturl连接.openConnection()至此配置必须在connect之前完成,           //   注意connection.getoutputstream将隐含connect。            connection.connect();         DataOutputStream out   =     new   DataOutputStream(connection                 .getOutputStream());           //   The URL-encoded contend           //   正文,事实上,正文内容与get的URL相结合。后参数字符串一致            String content   =     "  firstname=  "     +   URLEncoder.encode(  "  一个大肥人  "  ,   "  utf-8  "  );           //   DataOutputStream.writebytes将字符串中的16位unicode字符以8位字符的形式写入流中            out.writeBytes(content);          out.flush();         out.close();   //   flush and close            BufferedReader reader   =     new   BufferedReader(  new   InputStreamReader(                 connection.getInputStream()));         String line;         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of post request  "  );         System.out.println(  "  =============================  "  );           while   ((line   =   reader.readLine())   !=     null  ) {             System.out.println(line);         }         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of post request ends  "  );         System.out.println(  "  =============================  "  );         reader.close();         connection.disconnect();     }       /**     *//**        *   @param   args        */         public     static     void   main(String[] args) {           //   TODO Auto-generated method stub              try   {             readContentFromGet();             readContentFromPost();         }   catch   (IOException e) {               //   TODO Auto-generated catch block                e.printStackTrace();         }     } }

上面的 readContentFromGet()函数产生了一个get请求,传递给servletusername参数,值为“fat man"。

readContentFromPost()函数产生post请求,传递给servletfirstname参数,值为“大肥人”。

HttpURLConnection.事实上,conect函数只与服务器建立了tcp连接,并没有实际发送http请求。http请求实际上直到post和get

HttpURLConnection .getInputStream()这个函数刚刚正式发出。

在 readContentFromPost在()中,顺序是最重要的,所有配置(那堆set函数)都必须在conect()函数执行之前完成。outputstream的写作操作必须在inputstream的读取操作之前进行。这些顺序实际上是由http请求的格式决定的。

http请求实际上由两部分组成,一部分是http头,http请求的所有配置都定义在http头中,另一部分是文本content。在conect()函数中,htttp头将根据httpurlconection对象的配置值生成。因此,在调用conect函数之前,必须准备好所有的配置。

然后http头是http请求的文本。文本的内容通过outputstream写入。事实上,outputstream不是一个网络流。充其量,它是一个字符串流。写入其中的内容不会立即发送到网络,而是在流关闭后根据输入内容生成http文本。

到目前为止,http要求的东西已经准备好了。调用getinputstream()函数时,准备好的http请求将正式发送到服务器,然后返回输入流,读取服务器对http请求的返回信息。由于http请求已经在getinputstream时发送(包括http头和文本),因此在getinputstream()函数后设置conection对象(修改http头的信息)或写入outputstream(修改文本)是没有意义的,执行这些操作会导致异常

上一节说,post请求的outputstream实际上不是网络流,而是写入内存。只有在getinputstream中,写道流中的内容才能真正作为文本,并根据之前的配置生成http request头合并成真正的http request,直到那时,它才真正发送到服务器。

HttpURLConnection.setchunkedstreamingmode函数可以改变此模式。设置chunkedstreamingmode后,不再等待outputstream关闭,生成完整的httprequest一次发送,而是先发送httprequest头,文本内容是通过网络流实时传输到服务器。事实上,它并没有告诉服务器http文本的长度,这种模式适用于向服务器传输较大或不易获取长度的数据,如文件。事实上,它并没有告诉服务器http文本的长度,这种模式适用于向服务器传输较大或不易获取长度的数据,如文件。

public     static     void   readContentFromChunkedPost()   throws   IOException {         URL postUrl   =     new   URL(POST_URL);         HttpURLConnection connection   =   (HttpURLConnection) postUrl                 .openConnection();         connection.setDoOutput(  true  );         connection.setDoInput(  true  );         connection.setRequestMethod(  "  POST  "  );         connection.setUseCaches(  false  );         connection.setInstanceFollowRedirects(  true  );         connection.setRequestProperty(  "  Content-Type  "  ,                   "  application/x-www-form-urlencoded  "  );           /**  //*          * 与readContentfromPost()最大的不同,设置块大小为5字节            */           connection.setChunkedStreamingMode(  5  );         connection.connect();           /**  //*          * 注意,在readContentfromPost()中,下面的getoutstream函数工作模式是不同的          * 该函数在readcontentfrompost()中仍在准备httpp request,没有向服务器发送任何数据          * 在这里,由于Chunkedstreamingmode的设置,getoutputstream函数将根据connect之前的配置进行配置          * 生成http request头,先发送到服务器。            */           DataOutputStream out   =     new   DataOutputStream(connection                 .getOutputStream());         String content   =     "  firstname=  "     +   URLEncoder.encode(  "  一个大肥人                                                                                 "     +                     "                                              "     +                     "  asdfasfdasfasdfaasdfasdfasdfdasfs  "  ,   "  utf-8  "  );         out.writeBytes(content);          out.flush();         out.close();   //   此时,服务器已经收到了完整的http request,在readcontentfrompost()函数中,http请求需要等到下一个服务器。            BufferedReader reader   =     new   BufferedReader(  new   InputStreamReader(                 connection.getInputStream()));                  out.flush();         out.close();   //   flush and close            String line;         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of post request  "  );         System.out.println(  "  =============================  "  );           while   ((line   =   reader.readLine())   !=     null  ) {             System.out.println(line);         }         System.out.println(  "  =============================  "  );         System.out.println(  "  Contents of post request ends  "  );         System.out.println(  "  =============================  "  );         reader.close();         connection.disconnect();     }