今天做项目的时候遇到一个很奇怪的问题, 开发环境没有问题, 生产环境却提示java.lang.IllegalStateException: Form too large 和java.lang.IllegalStateException: Form too many keys异常.
追朔了一下堆栈和源码, 发现在 org.eclipse.jetty.server.Request 类中发现这段代码:
public void extractFormParameters(MultiMap<String> params)
{
try
{
int maxFormContentSize = -1;
int maxFormKeys = -1;
if (_context != null)
{
maxFormContentSize = _context.getContextHandler().getMaxFormContentSize();
maxFormKeys = _context.getContextHandler().getMaxFormKeys();
}
if (maxFormContentSize < 0)
{
Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
if (obj == null)
maxFormContentSize = 200000;
else if (obj instanceof Number)
{
Number size = (Number)obj;
maxFormContentSize = size.intValue();
}
else if (obj instanceof String)
{
maxFormContentSize = Integer.valueOf((String)obj);
}
}
if (maxFormKeys < 0)
{
Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
if (obj == null)
maxFormKeys = 1000;
else if (obj instanceof Number)
{
Number keys = (Number)obj;
maxFormKeys = keys.intValue();
}
else if (obj instanceof String)
{
maxFormKeys = Integer.valueOf((String)obj);
}
}
int contentLength = getContentLength();
if (contentLength > maxFormContentSize && maxFormContentSize > 0)
{
throw new IllegalStateException("Form too large: " + contentLength + " > " + maxFormContentSize);
}
InputStream in = getInputStream();
if (_input.isAsync())
throw new IllegalStateException("Cannot extract parameters with async IO");
UrlEncoded.decodeTo(in,params,getCharacterEncoding(),contentLength<0?maxFormContentSize:-1,maxFormKeys);
}
catch (IOException e)
{
if (LOG.isDebugEnabled())
LOG.warn(e);
else
LOG.warn(e.toString());
}
}
很明显在这段代码中获取了两个配置项:
1.org.eclipse.jetty.server.Request.maxFormContentSize: 请求头中 Content-Length 的最大值, 单位:字节, 默认200000字节
2.org.eclipse.jetty.server.Request.maxFormKeys: 请求参数的最大个数, 默认1000
显然我现在需要重新设置这两个参数, 百度得到的多数结果都是在WEB-INF目录下创建jetty配置文件来解决. 但我们的项目是基于spring-boot 1.3x, 使用的是内嵌Web容器, 没有WEB-INF目录.
最后在我们公司大神推荐的网址 https://stackoverflow.com/questions/36872540/spring-boot-rest-service-form-too-large 中得到答案.
private static void setHandlerMaxHttpPostSize(int maxHttpPostSize, int maxFormKeys, Handler... handlers) {
for (Handler handler : handlers) {
if (handler instanceof ContextHandler) {
((ContextHandler) handler).setMaxFormContentSize(maxHttpPostSize);
((ContextHandler) handler).setMaxFormKeys(maxFormKeys);
} else if (handler instanceof HandlerWrapper) {
setHandlerMaxHttpPostSize(maxHttpPostSize, maxFormKeys, ((HandlerWrapper) handler).getHandler());
} else if (handler instanceof HandlerCollection) {
setHandlerMaxHttpPostSize(maxHttpPostSize, maxFormKeys, ((HandlerCollection) handler).getHandlers());
}
}
}
如果是spring-boot 1.4x之后的版本, 则可以通过简单的 server.max-http-post-size=20MB 来解决第 form too large的问题
至于form too many keys的问题, 我还没有发现通过配置解决的.如果可以通过配置解决并且你知道的, 希望能告诉我, 非常感谢




