原文链接地址:(略有改动)
http://www.blogjava.net/supercrsky/articles/247449.html
最常用的http请求无非是get和post,而在java中则可以使用HttpURLConnection发起这两种请求;
1:> URL请求的类别:
分为二类,GET与POST请求。二者的区别在于:
a)get请求可以获取静态页面,也可以把参数放在URL字符串后面,传递给servlet;
b)post与get的不同之处在于post的参数不是放在URL后面,而是放在http请求的正文内;
发送一个http请求的步骤详解
1.根据请求的URL地址构建一个URL对象,然后创建一个HttpURLConnection对象
URL url= new URL("http://localhost:8080/test");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();//打开一个连接,此处返回的是一个URLConnection
对象,所以需要强转;
//HttpURLConnection对象不能直接new,需要通过url.openConnection()来获取;
2.设置HttpURLConnection的参数
conn.setRequestMethod("post");//设置 URL 请求的方法,默认是get方法
conn.setDoOutput(true);//设置是否要将数据写入URL连接;默认值是false
conn.setDoInput(true);//设置是否要从URL连接读取数据;默认值是true;
conn.setUseCaches(false);//post请求不能使用缓存;
conn.setRequestProperty("","");//主要用于设置HttpURLConnection请求头里的属性,具体怎么设置取决于服务器端的约定;
//conn.connect();//打开到此 URL 引用的资源的通信链接;
//URLConnection对象经历两个阶段,首先创建对象,然后创建连接,在创建连接前,必须先进行设置各个属性,先连后设会报错;
3.连接的问题:
OutputStream out = conn.getOutputStream();//此处的getOutputStream()会隐式的进行connect(即如同调用上面的connect()方法),所以在开发中一般不直接使用connect()方法;
4.连接服务端,发送数据
PrintStream ps = new PrintStream(conn.getOutputStream());
ps.print("发送到服务器的数据");//向输入流输入数据
ps.close();//关闭流对象,此时不能向流里写入任何数据,之前写入的数据已经存储在内存缓冲区中,
//在下面调用getInputStream()方法时才将准备好的http请求发送到服务器端
5.发送请求,获取数据
BufferedReader bReader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));//注意:实际发送http请求的代码就在这里
//将准备好的http请求发送到服务端
String line, resultStr = "";
while (null != (line = bReader.readLine())) {
resultStr += line;
}
bReader.close();
System.out.println("RESTRequester():load()2 最终返回的结果:"+resultStr);
总结: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(对正文进行修改)
都是没有意义的了,执行这些操作会导致异常的发生