Java中HttpURLConnection使用详解、总结。
感谢大佬:https://blog.csdn.net/qq_40036754/article/details/102554755
文章目录
一、前言
实习第二个月了,遇到了一个问题,需求使用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;
/**
* GET请求示例
*
* @author 安辰
*
*/
public class GetDemo {
public void doGet(String[] args) {
HttpURLConnection httpURLConnection = null;
try {
// 1. 得到访问地址的URL
URL url = new URL(
"http://localhost:8080/Servlet/do_login.do?username=test&password=123456");
// 2. 得到网络访问对象java.net.HttpURLConnection
httpURLConnection = (HttpURLConnection) url.openConnection();
/* 3. 设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接 */
// 设置是否向HttpURLConnection输出
httpURLConnection.setDoOutput(false);
// 设置是否从httpUrlConnection读入
httpURLConnection.setDoInput(true);
// 设置请求方式 默认为GET
httpURLConnection.setRequestMethod("GET");
// 设置是否使用缓存
httpURLConnection.setUseCaches(true);
// 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
httpURLConnection.setInstanceFollowRedirects(true);
// 设置超时时间
httpURLConnection.setConnectTimeout(3000);
// 连接
httpURLConnection.connect();
// 4. 得到响应状态码的返回值 responseCode
int code = httpURLConnection.getResponseCode();
// 5. 如果返回值正常,数据在网络中是以流的形式得到服务端返回的数据
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 {
// 6. 断开连接,释放资源
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;
/**
* POST请求示例
*
* @author 安辰
*
*/
public class PostDemo {
public void doPost(String[] args) {
HttpURLConnection httpURLConnection = null;
try {
// 1. 获取访问地址URL
URL url = new URL("http://localhost:8080/Servlet/do_login.do");
// 2. 创建HttpURLConnection对象
httpURLConnection = (HttpURLConnection) url.openConnection();
/* 3. 设置请求参数等 */
// 请求方式 默认 GET
httpURLConnection.setRequestMethod("POST");
// 超时时间
httpURLConnection.setConnectTimeout(3000);
// 设置是否输出
httpURLConnection.setDoOutput(true);
// 设置是否读入
httpURLConnection.setDoInput(true);
// 设置是否使用缓存
httpURLConnection.setUseCaches(false);
// 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
httpURLConnection.setInstanceFollowRedirects(true);
// 设置请求头
httpURLConnection.addRequestProperty("sysId","sysId");
// 设置使用标准编码格式编码参数的名-值对
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 连接
httpURLConnection.connect();
/* 4. 处理输入输出 */
// 写入参数到请求中
String params = "username=test&password=123456";
OutputStream out = httpURLConnection.getOutputStream();
out.write(params.getBytes());
// 简化
//httpURLConnection.getOutputStream().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 {
// 5. 断开连接
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()中的字符串参数为大写!
Java中HttpURLConnection使用详解、总结。的更多相关文章
- java中的注解详解和自定义注解
一.java中的注解详解 1.什么是注解 用一个词就可以描述注解,那就是元数据,即一种描述数据的数据.所以,可以说注解就是源代码的元数据.比如,下面这段代码: @Override public Str ...
- Java中dimension类详解
Java中dimension类详解 https://blog.csdn.net/hrw1234567890/article/details/81217788
- [转载]java中import作用详解
[转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...
- Java中日志组件详解
avalon-logkit Java中日志组件详解 lanhy 发布于 2020-9-1 11:35 224浏览 0收藏 作为开发人员,我相信您对日志记录工具并不陌生. Java还具有功能强大且功能强 ...
- Java中反射机制详解
序言 在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射, ...
- JAVA中Object类方法详解
一.引言 Object是java所有类的基类,是整个类继承结构的顶端,也是最抽象的一个类.大家天天都在使用toString().equals().hashCode().waite().notify() ...
- Java中的多线程详解
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- Java中常见方法详解合集(方法的定义及语法结构)
Java的方法定义 1.方法的定义 方法是控制对象的动作行为方式与准则,在Java中方法位于类体下又有另一种含义. 普通的方法在类中称为"实例方法",因为方法的调用需要创建对象,而 ...
- java中Class对象详解和类名.class, class.forName(), getClass()区别
一直在想.class和.getClass()的区别,思索良久,有点思绪,然后有网上搜了搜,找到了如下的一篇文章,与大家分享. 原来为就是涉及到Java的反射----- Java反射学习 所谓反射,可以 ...
随机推荐
- vue基于Blob.js和 Export2Excel.js做前端导出
1安装三个依赖包 npm install -S file-saver@2.0.2 npm install -S xlsx@0.15.6 npm install -D script-loader@0.7 ...
- 简单学生管理系统HTML前端页面
效果图: 实现代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...
- Java初学者作业——编写Java程序, 在控制台输入数字,计算表达式1-2+3-4……+(2*n-1)+2*n的结果。
返回本章节 返回作业目录 需求说明: 编写Java程序, 在控制台输入数字 计算表达式1-2+3-4--+(2*n-1)+2*n的结果. 实现思路: (1)声明变量 n 和 sum,用于存储用户输入的 ...
- Appium安装部署
一.安装JDK 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html JD ...
- 在 CentOS 7 上安装 GitLab
1. 安装和配置必要的依赖库 sudo yum install -y curl policycoreutils-python openssh-server # the commands below w ...
- 微信小程序css继承
在微信小程序里写的全局样式,pages里的组件是可以继承的,但是components里只能继承font和color属性.
- vue-cli axios封装(element-ui)
1.http.js /** * * http配置 */ import axios from 'axios'import { Loading, Message } from 'element-ui' / ...
- spring是线程安全的吗
spring默认bean是单例无状态的,我们交给spring管理的service,controller都是一个单例的bean,也就是说多个线程共享一个实例. 如果你在这种类里写成员变量,那这个变量的访 ...
- dgv 自动换行
//设置自动换行 dgv.DefaultCellStyle.WrapMode = DataGridViewTriState.True; //设置自动调整高度 dgv.AutoSizeRowsMode ...
- Spark-寒假-实验1
(1)切换到目录 /usr/bin: $ cd /usr/bin (2)查看目录/usr/local 下所有的文件: $cd /usr/local $ls (3)进入/usr 目录,创建一个名为 ...