spring - SpringMvc host 通过 request.getInputStream 获取请求数据时有时会花费太多时间
问题描述
在SpringMvc中,有时工作线程在获取请求数据时会被阻塞并托管太多时间(10s-60s)request.getInputStream
。但通常它运行良好。从调试日志中,我找到了所有主机的时间bufferedReader.read
,以及请求正文不是太大。
环境:
- webServer:undertow 1.3.23 最终版
- 弹簧网:4.3.2.RELEASE
代码如下:
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
@Autowired
private Logger logger = LoggerFactory.getLogger(this.getClass());
private final String body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
logger.error("close bufferedReader exception, detail:", ex);
}
}
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
解决方案
推荐阅读
- c++ - 是否可以展开可变参数 (lambda) 模板并将这些函数的返回值传递给另一个可变参数函数?
- php - 使用 PHP 将 txt 文件上传到数据库,然后返回 Excel 文件
- authorize.net - 在 Authorize.net 中进行实时付款
- c - 将 wchar_t *buff 与变量一起使用
- javascript - 无法为 chrome 扩展创建 webpack 包
- android - 使用 BroadcastReceiver 实现 Android 通知操作时出错
- mysql - 仅显示用户未订购的产品
- python - 如何使用 pathlib 循环多个路径
- swiftui - 如何使用 ScrollView 使图形居中 - 按像素滚动
- logging - Fluentd:有没有办法在单个匹配块中添加多个标签