由于使用了2.4.1版本的springbootstarter,声明的netty版本为4.1.55 在使用netty进行http服务时,接受参数get方法一切正常 但post方法中的form-data方式一直无法接受参数,程序会卡在
new HttpPostRequestDecoder(request)
这一句,同时cpu观察到100%,猜测为死循环。跟踪代码发现在
private static int findDelimiter(ByteBuf undecodedChunk, String delimiter, int offset) {
....
while (delimiterNotFound && newOffset + delimeterLength <= toRead) {
处一直循环无法退出,搜索到相同问题:https://github.com/netty/netty/issues/10851
只有form-data方式存在这个问题,x-www-form-urlencoded可以正常使用。
最终升级了netty到当前最新的4.1.65 问题解决。
另附接受参数代码:
private Map<String, String> getParamMap(ChannelHandlerContext ctx, FullHttpRequest request) throws IOException, TipException {
Map<String, String> paramMap = new HashMap<>();
paramMap.put("url", StrUtil.subBefore(request.uri(), "?", false));
if (HttpMethod.GET == request.method()) {
try {
QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
decoder.parameters().forEach((k, v) -> paramMap.put(k, v.get(0)));
} catch (Exception e) {
log.error(request.uri() + " 解析参数出错");
throw new ParamErrorException();
}
} else if (HttpMethod.POST == request.method()) {
final String contentType = request.headers().get(HttpHeaderNames.CONTENT_TYPE);
if (StrUtil.equals(HttpHeaderValues.APPLICATION_JSON, contentType)) {
String json = request.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
try {
Map<String, String> map = JsonUtil.fromJson(json, JsonUtil.getMapType(String.class, String.class));
if (map != null) {
paramMap.putAll(map);
}
} catch (Exception e) {
log.error(request.uri() + " 解析参数出错:" + json);
throw new ParamErrorException();
}
} else {
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
List<InterfaceHttpData> httpPostData = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : httpPostData) {
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
Attribute attribute = (Attribute) data;
paramMap.put(attribute.getName(), attribute.getValue());
} else if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
final FileUpload fileUpload = (FileUpload) data;
//这里处理文件参数逻辑
}
}
}
} else {
throw new TipException("不支持的请求方法");
}
return paramMap;