mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add HttpInputStream
This commit is contained in:
111
hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java
Normal file
111
hutool-http/src/main/java/cn/hutool/http/HttpInputStream.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.DeflaterInputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* HTTP输入流,此流用于包装Http请求响应内容的流,用于解析各种压缩、分段的响应流内容
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class HttpInputStream extends InputStream {
|
||||
|
||||
/** 原始流 */
|
||||
private volatile InputStream in;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param response 响应对象
|
||||
*/
|
||||
public HttpInputStream(HttpResponse response) {
|
||||
init(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return this.in.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return this.in.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return this.in.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return this.in.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.in.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
this.in.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
this.in.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return this.in.markSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化流
|
||||
*
|
||||
* @param response 响应对象
|
||||
*/
|
||||
private void init(HttpResponse response) {
|
||||
try {
|
||||
this.in = (response.status < HttpStatus.HTTP_BAD_REQUEST) ? response.httpConnection.getInputStream() : response.httpConnection.getErrorStream();
|
||||
} catch (IOException e) {
|
||||
if (e instanceof FileNotFoundException) {
|
||||
// 服务器无返回内容,忽略之
|
||||
} else {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 在一些情况下,返回的流为null,此时提供状态码说明
|
||||
if (null == this.in) {
|
||||
this.in = new ByteArrayInputStream(StrUtil.format("Error request, response status: {}", response.status).getBytes());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO 分段响应内容解析
|
||||
if(response.isChunked()) {
|
||||
}
|
||||
|
||||
if (response.isGzip() && false == (response.in instanceof GZIPInputStream)) {
|
||||
// Accept-Encoding: gzip
|
||||
try {
|
||||
this.in = new GZIPInputStream(this.in);
|
||||
} catch (IOException e) {
|
||||
// 在类似于Head等方法中无body返回,此时GZIPInputStream构造会出现错误,在此忽略此错误读取普通数据
|
||||
// ignore
|
||||
}
|
||||
} else if (response.isDeflate() && false == (this.in instanceof DeflaterInputStream)) {
|
||||
// Accept-Encoding: defalte
|
||||
this.in = new DeflaterInputStream(this.in);
|
||||
}
|
||||
}
|
||||
}
|
@@ -12,8 +12,6 @@ import java.net.HttpCookie;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.DeflaterInputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.io.FastByteArrayOutputStream;
|
||||
@@ -38,13 +36,13 @@ import cn.hutool.log.StaticLog;
|
||||
public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
|
||||
/** 持有连接对象 */
|
||||
private HttpConnection httpConnection;
|
||||
protected HttpConnection httpConnection;
|
||||
/** Http请求原始流 */
|
||||
private InputStream in;
|
||||
protected InputStream in;
|
||||
/** 是否异步,异步下只持有流,否则将在初始化时直接读取body内容 */
|
||||
private volatile boolean isAsync;
|
||||
/** 响应状态码 */
|
||||
private int status;
|
||||
protected int status;
|
||||
/** 是否忽略读取Http响应体 */
|
||||
private boolean ignoreBody;
|
||||
/** 从响应中获取的编码 */
|
||||
@@ -373,9 +371,9 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
* @throws HttpException IO异常
|
||||
*/
|
||||
private HttpResponse init() throws HttpException {
|
||||
// 获取响应状态码
|
||||
try {
|
||||
this.status = httpConnection.responseCode();
|
||||
this.in = (this.status < HttpStatus.HTTP_BAD_REQUEST) ? this.httpConnection.getInputStream() : this.httpConnection.getErrorStream();
|
||||
} catch (IOException e) {
|
||||
if (e instanceof FileNotFoundException) {
|
||||
// 服务器无返回内容,忽略之
|
||||
@@ -394,31 +392,15 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
// 存储服务端设置的Cookie信息
|
||||
GlobalCookieManager.store(httpConnection);
|
||||
|
||||
// 获取响应编码
|
||||
final Charset charset = httpConnection.getCharset();
|
||||
this.charsetFromResponse = charset;
|
||||
if (null != charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
if (null == this.in) {
|
||||
// 在一些情况下,返回的流为null,此时提供状态码说明
|
||||
this.in = new ByteArrayInputStream(StrUtil.format("Error request, response status: {}", this.status).getBytes());
|
||||
} else {
|
||||
// TODO 分段响应内容解析
|
||||
|
||||
if (isGzip() && false == (in instanceof GZIPInputStream)) {
|
||||
// Accept-Encoding: gzip
|
||||
try {
|
||||
in = new GZIPInputStream(in);
|
||||
} catch (IOException e) {
|
||||
// 在类似于Head等方法中无body返回,此时GZIPInputStream构造会出现错误,在此忽略此错误读取普通数据
|
||||
// ignore
|
||||
}
|
||||
} else if (isDeflate() && false == (in instanceof DeflaterInputStream)) {
|
||||
// Accept-Encoding: defalte
|
||||
in = new DeflaterInputStream(in);
|
||||
}
|
||||
}
|
||||
// 获取响应内容流
|
||||
this.in = new HttpInputStream(this);
|
||||
|
||||
// 同步情况下强制同步
|
||||
return this.isAsync ? this : forceSync();
|
||||
|
@@ -63,7 +63,8 @@ public class HttpUtilTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void getTest5() {
|
||||
String res = HttpUtil.get("https://comment.bilibili.com/67573272.xml");
|
||||
String res = HttpRequest.get("https://comment.bilibili.com/67573272.xml")
|
||||
.execute().body();
|
||||
Console.log(res);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user