mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add brotli support
This commit is contained in:
parent
51e4a14388
commit
79e7e51727
@ -22,6 +22,12 @@
|
||||
<artifactId>hutool-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.soap</groupId>
|
||||
<artifactId>javax.xml.soap-api</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-json</artifactId>
|
||||
@ -29,10 +35,10 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.soap</groupId>
|
||||
<artifactId>javax.xml.soap-api</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<scope>provided</scope>
|
||||
<groupId>org.brotli</groupId>
|
||||
<artifactId>dec</artifactId>
|
||||
<version>0.1.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
57
hutool-http/src/main/java/cn/hutool/http/GlobalCompressStreamRegister.java
Executable file
57
hutool-http/src/main/java/cn/hutool/http/GlobalCompressStreamRegister.java
Executable file
@ -0,0 +1,57 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import cn.hutool.core.map.CaseInsensitiveMap;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 全局响应内容压缩解压器注册中心<br>
|
||||
* 通过注册指定Accept-Encoding的流,来包装响应内容流,从而支持特殊压缩算法
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public enum GlobalCompressStreamRegister {
|
||||
/**
|
||||
* 单例对象
|
||||
*/
|
||||
INSTANCE;
|
||||
|
||||
/**
|
||||
* 存储内容压缩流信息
|
||||
*/
|
||||
private final Map<String, Class<? extends InputStream>> compressMap = new CaseInsensitiveMap<>();
|
||||
|
||||
GlobalCompressStreamRegister() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取解压器
|
||||
*
|
||||
* @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
|
||||
* @return 解压器
|
||||
*/
|
||||
public Class<? extends InputStream> get(final String contentEncoding) {
|
||||
return compressMap.get(contentEncoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册解压器
|
||||
*
|
||||
* @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
|
||||
* @param streamClass 解压类
|
||||
*/
|
||||
synchronized public void register(final String contentEncoding, final Class<? extends InputStream> streamClass) {
|
||||
this.compressMap.put(contentEncoding, streamClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销压缩器
|
||||
*
|
||||
* @param contentEncoding Accept-Encoding名称,如gzip、defalte、br等,不区分大小写
|
||||
*/
|
||||
synchronized public void unRegister(final String contentEncoding) {
|
||||
this.compressMap.remove(contentEncoding);
|
||||
}
|
||||
}
|
@ -18,6 +18,9 @@ import java.util.Map.Entry;
|
||||
* @author looly
|
||||
*/
|
||||
public enum GlobalHeaders {
|
||||
/**
|
||||
* 单例对象
|
||||
*/
|
||||
INSTANCE;
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import cn.hutool.core.reflect.ConstructorUtil;
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -92,17 +93,27 @@ public class HttpInputStream extends InputStream {
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.isGzip() && false == (response.in instanceof GZIPInputStream)) {
|
||||
final String contentEncoding = response.contentEncoding();
|
||||
if (StrUtil.equalsIgnoreCase("gzip", contentEncoding) && false == (response.in instanceof GZIPInputStream)) {
|
||||
// Accept-Encoding: gzip
|
||||
try {
|
||||
this.in = new GZIPInputStream(this.in);
|
||||
} catch (final IOException e) {
|
||||
} catch (final IOException ignore) {
|
||||
// 在类似于Head等方法中无body返回,此时GZIPInputStream构造会出现错误,在此忽略此错误读取普通数据
|
||||
// ignore
|
||||
}
|
||||
} else if (response.isDeflate() && false == (this.in instanceof InflaterInputStream)) {
|
||||
} else if (StrUtil.equalsIgnoreCase("deflate", contentEncoding) && false == (this.in instanceof InflaterInputStream)) {
|
||||
// Accept-Encoding: defalte
|
||||
this.in = new InflaterInputStream(this.in, new Inflater(true));
|
||||
} else{
|
||||
final Class<? extends InputStream> streamClass = GlobalCompressStreamRegister.INSTANCE.get(contentEncoding);
|
||||
if(null != streamClass){
|
||||
try {
|
||||
this.in = ConstructorUtil.newInstance(streamClass, this.in);
|
||||
} catch (final Exception ignore) {
|
||||
// 对于构造错误的压缩算法,跳过之
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,27 +143,6 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为gzip压缩过的内容
|
||||
*
|
||||
* @return 是否为gzip压缩过的内容
|
||||
*/
|
||||
public boolean isGzip() {
|
||||
final String contentEncoding = contentEncoding();
|
||||
return "gzip".equalsIgnoreCase(contentEncoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为zlib(Deflate)压缩过的内容
|
||||
*
|
||||
* @return 是否为zlib(Deflate)压缩过的内容
|
||||
* @since 4.5.7
|
||||
*/
|
||||
public boolean isDeflate() {
|
||||
final String contentEncoding = contentEncoding();
|
||||
return "deflate".equalsIgnoreCase(contentEncoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为Transfer-Encoding:Chunked的内容
|
||||
*
|
||||
|
20
hutool-http/src/test/java/cn/hutool/http/IssueI5XBCFTest.java
Executable file
20
hutool-http/src/test/java/cn/hutool/http/IssueI5XBCFTest.java
Executable file
@ -0,0 +1,20 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import org.brotli.dec.BrotliInputStream;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class IssueI5XBCFTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void getTest() {
|
||||
GlobalCompressStreamRegister.INSTANCE.register("br", BrotliInputStream.class);
|
||||
|
||||
final HttpResponse s = HttpUtil.createGet("https://static-exp1.licdn.com/sc/h/br/1cp0oqz322bdprj3qd4pojqix")
|
||||
.header(Header.ACCEPT_ENCODING, "br")
|
||||
.execute();
|
||||
Console.log(s.body());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user