码迷,mamicode.com
首页 > 其他好文 > 详细

httpUrlConnection的参数详解

时间:2014-07-16 16:14:42      阅读:3111      评论:0      收藏:0      [点我收藏+]

标签:httpurlconnection   java   outputstream   inputstream   post   

post方式的的请求过程

// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在

// http正文内,因此需要设为true, 默认情况下是false;

httpUrlConnection.setDoOutput(true);

// 设置是否从httpUrlConnection读入,默认情况下是true;

httpUrlConnection.setDoInput(true);

// Post 请求不能使用缓存

httpUrlConnection.setUseCaches(false);

// 设定传送的内容类型是可序列化的java对象

// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)

httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");

// 设定请求的方法为"POST",默认是GET
httpUrlConnection.setRequestMethod("POST");

//参数配置必须要在connect之前完成,

httpUrlConnection.connect();

// 此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,

// 所以在开发中不调用上述的connect()也可以)。

OutputStream outStrm = httpUrlConnection.getOutputStream();

// 现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。

ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm);

// 向对象输出流写出数据,这些数据将存到内存缓冲区中
objOutputStrm.writeObject(new String("我是测试数据"));

// 刷新对象输出流,将任何字节都写入潜在的流中(些处为ObjectOutputStream)

objOutputStm.flush();

// 关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓//冲区中, 在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器

objOutputStm.close();

// 调用HttpURLConnection连接对象的getInputStream()函数, 
// 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
InputStream inStrm = httpConn.getInputStream(); // <==注意,实际发送请求的代码段就在这里

// 上边的httpConn.getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的//输出已无意义, 既使对象输出流没有调用close()方法,下边的操作也不会向对象输出流//写入任何数据. 因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对//象、重新写数据、 重新发送数据(至于是否不用重新这些操作需要再研究)
objOutputStm.writeObject(new String(""));

httpConn.getInputStream();

OutputStream os = httpConn.getOutputStream();

String param = new String();

param = "CorpID=" + CorpID + "&LoginName=" + LoginName+ "&send_no=" + phoneNumber + 
                    "&msg=" + java.net.URLEncoder.encode(msg,"GBK");

os.write(param.getBytes());

//超时设置,防止网络异常的情况下,可能会导致程序僵死而不继续往下执行

System.setProperty("sun.net.client.defaultConnectTimeout", "30000");

System.setProperty("sun.net.client.defaultReadTimeout", "30000");

其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)
sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)

JDK 1.5以前的版本,只能通过设置这两个系统属性来控制网络超时。在1.5中,还可以使用HttpURLConnection的父类URLConnection的以下两个方法:

setConnectTimeout:设置连接主机超时(单位:毫秒)

setReadTimeout:设置从主机读取数据超时(单位:毫秒)

总结:a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

       b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。如果inputStream读操作在outputStream的写操作之前,会抛出例外: java.net.ProtocolException: Cannot write output after reading input

       c:) http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content。connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。

       d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

------------------------------------------------------------------------------------------------------------------------   

stream应该是水龙头里的水资源
InputStream:是一个出水龙头(把水封装在里头)的一个实物对象,该对象的read方法呢,就想成这个
出水龙头这一机制对象的开关钮,你read或openStream(其他对象包容InputStream对象的对象方法)一下呢,就等于打开了出水龙头的按钮,水就出来了,里头封装的水是什么性质的呢,你就用相应的容器来装,如string或byte[].....
OutputStream:你就在InputStream基础上反着想就ok了 

OutputStream:
(1)输出数据
   void write(int b)往流中写一个字节b
   void write(byte b[])往流中写一个字节数组b
   void write(byte b[],int off,int len)把字节数组b中从下标off开始,长度为len的字节写入流中
 (2)
   flush()刷空输出流,并输出所有被缓存的字节由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
(3)关闭流
   close()流操作完毕后必须关闭。
------------------------------------------------------------------------------------------------------------------------
InputStream:
(1)从流中读取数据
   int read() 读取一个字节,返回值为所读得字节
   int read(byte b[]) 读取多个字节,放置到字节数组b中,通常读取的字节数量为b的长度,返回值为实际独取的字节的数量。
   int read(byte b[] ,int off,int len)读取len个字节,放置到以下标off开始字节数组b中,返回值为实际读取的字节的数量。
   int available() 返回值为流中尚未读取的字节的数量。
   long skip(long n);读指针跳过n个字节不读,返回值为实际跳过的字节数量
(2)关闭流
   close() 流操作完毕后必须关闭
(3)使用输入流中的标记
   void mark(int readlimit)纪录当前指针的所在位置.readlimit表示读指针读出的readlimit个字节后所标记的指针位置才实效。
   void reset() 把读指针重新指向用mark方法所记录的位置
   boolean markSupported() 当前的流是否支持读指针的记录功能。


对于http的POST和PUT请求,发出HTTP请求应该遵循的步骤:

  1. 生成HttpURLConnection实例,并设置http请求参数或者属性;
  2. 调用getOutputStream方法获得OutputStream并且输出数据到输出流。不管你有没有数据需要发送到服务器端,至少你要调用一下getOutputStream()方法之后忽略数据的写入;
  3. 调用getInputStream方法发出真实的http请求,并且等待服务器的响应。不管你需不需要服务器的反馈,这个必须调用。

      对于http的除了POST和PUT的其他请求(如GET,HEAD,DELETE,TRACE,OPTIONS),发出HTTP请求应该遵循的步骤:

  1. 生成HttpURLConnection实例,并设置http请求参数或者属性;
  2. 调用getInputStream方法发出真实的http请求,并且等待服务器的响应。

      我们不能假定调用getOutputStream()获得OutputStream,写入数据,然后调用输出流的flush()/close()方法就把真实的http请求发送到服务器端了。事实上,调用HttpURLConnection的getInputStream()方法是唯一的发出真实请求的方法,而调用getOutputStream()方法并没有发送真实的Http请求。

      除此之外,使用HttpURLConnection的时候一定要根据请求的类型(POST,GET等)去遵循上面描述的执行顺序,比如说你已经调用共getInputStream()方法了,你在调用getOutputStream()方法的时候就抛异常了,HttpURLConnection说这是不合法的。


httpUrlConnection的参数详解,布布扣,bubuko.com

httpUrlConnection的参数详解

标签:httpurlconnection   java   outputstream   inputstream   post   

原文地址:http://blog.csdn.net/fngy123/article/details/37878399

(1)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!