感谢大佬:https://blog.csdn.net/qq_40036754/article/details/102554755
文章目录
一、前言二、HttpURLConnection 介绍三、GET、POST请求1、GET请求2、POST请求3、总结a、connect()方法调用不调用:b、是否调用connect方法?c、openConnection()方法到底是如何返回URLConnection对象的:d、必须调用getResponseCode()方法 。
四、小方法解释1、flush()
一、前言
实习第二个月了,遇到了一个问题,需求使用Java 的 HttpURLConnection 来转发请求。需求也给了示例,但是流程不明白,所以再网上查找了很长时间之后,特来总结一番。
3.3中,是关于这次的问题总结,建议大家看一下。
二、HttpURLConnection 介绍
JDK的java.net包中提供了访问HTTP协议的基本功能的类:HttpURLConnection。
URLConnection是个抽象类,它有两个直接子类分别是HttpURLConnection和JarURLConnection。另外一个重要的类是URL,通常URL可以通过传给构造器一个String类型的参数来生成一个指向特定地址的URL实例。
HttpURLConnection是Java的标准类,它继承自URLConnection,可用于向指定网站发送GET请求、POST请求。它在URLConnection的基础上提供了如下便捷的方法:
int getResponseCode();
String
getResponseMessage();
String
getResponseMethod();
void setRequestMethod(String method
);
每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字。
三、GET、POST请求
1、GET请求
package com
.feng
.demo
;
import java
.io
.BufferedReader
;
import java
.io
.IOException
;
import java
.io
.InputStreamReader
;
import java
.net
.HttpURLConnection
;
import java
.net
.URL
;
public class GetDemo {
public void doGet(String
[] args
) {
HttpURLConnection httpURLConnection
= null
;
try {
URL url
= new URL(
"http://localhost:8080/Servlet/do_login.do?username=test&password=123456");
httpURLConnection
= (HttpURLConnection
) url
.openConnection();
httpURLConnection
.setDoOutput(false);
httpURLConnection
.setDoInput(true);
httpURLConnection
.setRequestMethod("GET");
httpURLConnection
.setUseCaches(true);
httpURLConnection
.setInstanceFollowRedirects(true);
httpURLConnection
.setConnectTimeout(3000);
httpURLConnection
.connect();
int code
= httpURLConnection
.getResponseCode();
String msg
= "";
if (code
== 200) {
BufferedReader reader
= new BufferedReader(new InputStreamReader(httpURLConnection
.getInputStream()));
String line
= null
;
while ((line
= reader
.readLine()) != null
) {
msg
+= line
+ "\n";
}
reader
.close();
}
log
.info(msg
);
} catch (IOException e
) {
log
.error("转发出错,错误信息:"+e
.getLocalizedMessage()+";"+e
.getClass());
}finally {
if (null
!= httpURLConnection
){
try {
httpURLConnection
.disconnect();
}catch (Exception e
){
log
.info("httpURLConnection 流关闭异常:"+ e
.getLocalizedMessage());
}
}
}
}
}
2、POST请求
package com
.feng
.demo
;
import java
.io
.BufferedReader
;
import java
.io
.IOException
;
import java
.io
.InputStreamReader
;
import java
.io
.OutputStream
;
import java
.net
.HttpURLConnection
;
import java
.net
.MalformedURLException
;
import java
.net
.URL
;
public class PostDemo {
public void doPost(String
[] args
) {
HttpURLConnection httpURLConnection
= null
;
try {
URL url
= new URL("http://localhost:8080/Servlet/do_login.do");
httpURLConnection
= (HttpURLConnection
) url
.openConnection();
httpURLConnection
.setRequestMethod("POST");
httpURLConnection
.setConnectTimeout(3000);
httpURLConnection
.setDoOutput(true);
httpURLConnection
.setDoInput(true);
httpURLConnection
.setUseCaches(false);
httpURLConnection
.setInstanceFollowRedirects(true);
httpURLConnection
.addRequestProperty("sysId","sysId");
httpURLConnection
.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection
.connect();
String params
= "username=test&password=123456";
OutputStream out
= httpURLConnection
.getOutputStream();
out
.write(params
.getBytes());
out
.flush();
out
.close();
String msg
= "";
int code
= httpURLConnection
.getResponseCode();
if (code
== 200) {
BufferedReader reader
= new BufferedReader(
new InputStreamReader(httpURLConnection
.getInputStream()));
String line
;
while ((line
= reader
.readLine()) != null
) {
msg
+= line
+ "\n";
}
reader
.close();
}
log
.info(msg
);
} catch (IOException e
) {
log
.error("转发出错,错误信息:"+e
.getLocalizedMessage()+";"+e
.getClass());
}finally {
if (null
!= httpURLConnection
){
try {
httpURLConnection
.disconnect();
}catch (Exception e
){
log
.info("httpURLConnection 流关闭异常:"+ e
.getLocalizedMessage());
}
}
}
}
}
3、总结
从网上找资料的时候,发现 connect() 和 flush() 方法有时写,有时不写,还没有理由,特来总结一番。
a、connect()方法调用不调用:
调用connect()只是建立连接,并不会向服务器传送数据,只要调用getResponseCode(),就不必要调用connect方法(调用也无妨)。
b、是否调用connect方法?
不需要显示调用connect方法
c、openConnection()方法到底是如何返回URLConnection对象的:
openConnection()在你不自己实现网络协议等网络相关抽象类和抽象接口的情况下,此方法最终调用的是sun.net.www.protocol.http.Handler类中的方法
d、必须调用getResponseCode()方法 。
安辰试了一下在不调用getResponseCode()方法的时候,无论是否调用connect()方法,请求都是不能成功的,调用connect()方法只是建立连接,并不会向服务器传递数据。只用调用getRespconseCode()方法时,才会向服务器传递数据(有博文说是getInputStream()才会向服务器传递数据,getResponseCode中会调用getInputStream方法)。跟着getResponseCode()源码发现里面调用了getInputStream()方法,在getInputStream()方法中会判断当前是否连接,如果没有连接,则调用connect()方法建立连接。
四、小方法解释
1、flush()
flush()意思是把**缓冲区的内容强制的写出**。 因为操作系统的某些机制,为了防止一直不停地磁盘读写,所以有了延迟写入的概念,(注意不要和frush()刷新混淆了)
主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是先被读到了内存中,再把数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先flush()。。
为了防止过于频繁的写操作 所以Java提供了一个java.io.BufferedOutputStream类 内部持有一个缓冲区 默认不直接将数据写到硬盘上 而是存到缓冲区中 直到一定条件后触发(就是调用上面的flushBuffer()了) 也可以强制通过flush()方法提前触发。
所以当你认为你完成了某一个比较重要的操作的时候 最好进行一次flush 防止数据在内存中丢失。 多数时候,如果你最后会调用一次close方法,flush方法是可以不使用的,除非你明确的想使数据尽早写到磁盘或者网络上。
补充:注意setRequestMethod()中的字符串参数为大写!