由于jfinal开启gzip导致返回头部content-length为0从而导致小程序获取进度失败问题
- 问题原因
gzip会使得content-length不生效,因为服务器认为如果你开启了gzip最后的压缩结果和你提供的length将会不一致,所以会移除content-length
- 处理方法分析
//UndertowServer类中存在此方法
protected HttpHandler configGzip(HttpHandler pathHandler) {
if (config.isGzipEnable()) {
//undertow使用HttpHandler 做为请求处理链,而如果开启了gzip则加入EncodingHandler处理器
//ContentEncodingRepository 中便是最终判断是否需要处理gzip
ContentEncodingRepository repository = new ContentEncodingRepository();
GzipEncodingProvider provider = new GzipEncodingProvider(config.getGzipLevel());
int minLength = config.getGzipMinLength();
Predicate predicate = minLength > 0 ? Predicates.maxContentSize(minLength) : Predicates.truePredicate();
repository.addEncodingHandler("gzip", provider, 100, predicate);
return new EncodingHandler(pathHandler, repository);
}
return pathHandler;
}
}
由上得出两种处理方式1.在ContentEncodingRepository处扩展做手脚2.HttpHandler 处做手脚.
- 处理办法1
protected HttpHandler configGzip(HttpHandler pathHandler) {
if (config.isGzipEnable()) {
ContentEncodingRepository repository = new ContentEncodingRepositoryExt();
GzipEncodingProvider provider = new GzipEncodingProvider(config.getGzipLevel());
int minLength = config.getGzipMinLength();
Predicate predicate = minLength > 0 ? Predicates.maxContentSize(minLength) : Predicates.truePredicate();
repository.addEncodingHandler("gzip", provider, 100, predicate);
return new EncodingHandler(pathHandler, repository);
}
return pathHandler;
}
复写UndertowServer重写configGzip,并且新建io.undertow.server.handlers.encoding.ContentEncodingRepository#getContentEncodings子类复写getContentEncodings方法,在处理前判断当前请求的url是否需要过滤,如果过滤则返回null,否则继续执行gzip后续代码.
- 处理办法2
//复写UndertowServer重写configGzip,并且新建HttpHandler 的子类FileHttpHandler
protected HttpHandler configGzip(HttpHandler pathHandler) {
return new FileHttpHandler(super.configGzip(pathHandler));
}
//在FileHttpHandler 内部处理掉由getContentEncodings方法使用的ACCEPT_ENCODING,便可实现
public void handleRequest(HttpServerExchange exchange) throws Exception {
if (exchange.getRequestURI().startsWith("/file")){
exchange.getRequestHeaders().remove(Headers.ACCEPT_ENCODING);
}
next.handleRequest(exchange);
}
笔者采用第二种因为代码少,更容易理解.













网友评论