发送一个请求,一直处于pending,服务端请求没有到应用有哪些因素
content-length设置问题
在http4发送请求,会直接提示content-length不应该设置
在http3发送请求,却不会有任何提示
报文格式问题
传输的报文格式没有严格按照HTTP规范来,数据包都是/r/n来分割
从servlet中读取InputStream的时候不要readLine(网上有很多这样的写法是不正确的),这样http body的报文格式化,再还原的时候已经遭到破坏了
关于servlet读取InputStream
InputStream只能消费一次,request.getParameter()本质上也是消费流。
使用HttpServletRequestWrapper
把ServletInputStream缓存成字节流。
public class CacheHttpServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] data;
public CacheHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
data = IOUtils.toByteArray(request.getInputStream());
}
@Override
public ServletInputStream getInputStream() {
return new RequestCacheInputStream(data);
}
private static class RequestCacheInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public RequestCacheInputStream(byte[] bytes) {
inputStream = new ByteArrayInputStream(bytes);
}
@Override
public int read() {
return inputStream.read();
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readlistener) {
}
}
}
// filter 使用
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws
IOException, ServletException {
if (needCache(request)) {
chain.doFilter(new CacheHttpServletRequestWrapper((HttpServletRequest) request), response);
} else {
chain.doFilter(request, response);
}
}