【问题标题】:Spring Boot Rest Service Form too largeSpring Boot Rest 服务表单太大
【发布时间】:2016-08-20 17:32:42
【问题描述】:

我使用的是 Spring Boot 1.3.2,我需要公开一个 REST Web 服务。对于这个 Web 服务,我需要传递一个字符串(包含 xml 数据)作为参数。字符串的大小通常在 2 MB 到 120 MB 之间。问题是我不知道如何配置 REST 方法参数允许的最大大小,并且默认大小太小了。由于其他依赖关系,Spring 配置必须在 java 类中。这是我的配置类:

@Configuration
@ComponentScan("eu.buzea")
@EnableAutoConfiguration
@EnableNeo4jRepositories("eu.buzea.datamodel.repositories")
@EnableTransactionManagement
@SpringBootApplication
public class Application extends Neo4jConfiguration {

    public Application() {
    }
    
    @Override
    public Neo4jServer neo4jServer() {
        return new RemoteServer("http://localhost:7474");
    }
    
    @Override
    public SessionFactory getSessionFactory() {
        return new SessionFactory("eu.buzea.datamodel.entities");
    }
    
    @Override
    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Session getSession() throws Exception {
        return super.getSession();
    }
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

这就是 Rest 端点的样子:

@RequestMapping(method = RequestMethod.POST)
public boolean processing(@RequestParam(value = "xml", required = true) String xml) 

当我向该方法发送一个字符串时,我收到以下错误:

java.lang.IllegalStateException: Form too large: 780963 > 200000
at org.eclipse.jetty.server.Request.extractFormParameters(Request.java:365) ~[jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.Request.extractContentParameters(Request.java:303) ~[jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.Request.extractParameters(Request.java:257) ~[jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.Request.getParameter(Request.java:826) ~[jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:70) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) [jetty-security-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.14.v20151106.jar:9.2.14.v20151106]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_71]
2016-04-26 20:32:44 [qtp2021854618-21] WARN  org.eclipse.jetty.http.HttpParser - badMessage: java.lang.IllegalStateException: too much data after closed for HttpChannelOverHttp@4d208ff0{r=1,c=false,a=IDLE,uri=}
谁能告诉我如何将(最大请求大小)最大表单内容大小设置为 200 MB 或无限?

更新 以下帖子提供了一个解决方案,以防您使用未嵌入 Spring Boot 的码头服务器:stackoverflow.com/questions/3861455/form-too-large-exception

我想设置maxFormContentSize参数,但不确定是Eclipse参数还是Spring参数。

附:我现在知道如何使用 MultipartFile Upload 解决问题。此外,还有另一种选择:在请求正文中发送字符串/数据。它们都很好用,但我想知道是否可以在 Spring 或 Eclipse 中设置 maxFormContentSize

【问题讨论】:

    标签: java spring rest spring-boot jetty


    【解决方案1】:

    对于没有 spring-boot 的简单 jetty-server-9.4.33.v20201020。它通过配置此系统属性来工作。码头使用Integer.getInteger 函数在org.eclipse.jetty.server.handler.ContextHandler 中的静态字段_maxFormContentSize 上获取默认值。

    public static void main(String[] args) {
        System.setProperty("org.eclipse.jetty.server.Request.maxFormContentSize", "20000000");   
        SpringApplication.run(Application.class, args);
    }
    

    对于spring-boot-2.3.5,只有几个值会被覆盖,例如可以配置的org.springframework.boot.autoconfigure.web.ServerProperties.Jetty.maxHttpFormPostSize

    server.jetty.maxHttpFormPostSize=20000001B
    

    【讨论】:

      【解决方案2】:

      Spring Boot 1.4.0.M2 有一个新属性server.max-http-post-size,可用于配置它。里程碑可从https://repo.spring.io/libs-milestone 获得。

      如果您想坚持使用 Spring Boot 1.3.x,您可以通过将以下 bean 添加到应用程序的配置中来自己实现相同的逻辑:

      @Bean
      public EmbeddedServletContainerCustomizer jettyCustomizer() {
          return new EmbeddedServletContainerCustomizer() {
      
              @Override
              public void customize(ConfigurableEmbeddedServletContainer container) {
                  if (container instanceof JettyEmbeddedServletContainerFactory) {
                      ((JettyEmbeddedServletContainerFactory) container)
                              .addServerCustomizers(new JettyServerCustomizer() {
      
                          @Override
                          public void customize(Server server) {
                              setHandlerMaxHttpPostSize(200 * 1024 * 1024, server.getHandlers());
                          }
      
                          private void setHandlerMaxHttpPostSize(int maxHttpPostSize,
                                  Handler... handlers) {
                              for (Handler handler : handlers) {
                                  if (handler instanceof ContextHandler) {
                                      ((ContextHandler) handler)
                                              .setMaxFormContentSize(maxHttpPostSize);
                                  }
                                  else if (handler instanceof HandlerWrapper) {
                                      setHandlerMaxHttpPostSize(maxHttpPostSize,
                                              ((HandlerWrapper) handler).getHandler());
                                  }
                                  else if (handler instanceof HandlerCollection) {
                                      setHandlerMaxHttpPostSize(maxHttpPostSize,
                                              ((HandlerCollection) handler).getHandlers());
                                  }
                              }
                          }
                      });
                  }
              }
          };
      }
      

      【讨论】:

      • 这就是我一直在寻找的答案!就像对后来阅读本文的人的建议:在请求参数中发送这么多数据是愚蠢的主意!更好地使用请求正文。
      【解决方案3】:

      当您处理大文件时,您应该使用 multipart-file-upload。 Spring 3.0 MultipartFile upload

      并且客户端应该以多部分格式向您发送数据 https://stackoverflow.com/a/27097798/5649869

      【讨论】:

      • 我已经研究了 MultipartFile 上传,它可能适合我的需要。然而,创建一个 java 客户端来发送数据并不是那么简单。你建议的帖子没有给我我需要的所有信息。 map.add("file", new ClassPathResource(file));template.get() 太模糊了。
      【解决方案4】:

      您是否尝试过增加您的 HTTP POST maxPostSize?

      在您的application.properties 文件中添加:

      multipart.maxFileSize=20MB

      文档:

      http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/MultipartProperties.html

      如果你想要它的代码,这里是文档:

      Increase HTTP Post maxPostSize in Spring Boot

      【讨论】:

      • 使用此属性添加 application.properties 文件不会影响我的应用程序中的任何内容。您建议的第二个选项是用于 tomacat 服务器...
      猜你喜欢
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 2018-03-25
      • 2015-08-16
      • 2018-12-29
      • 2017-12-15
      • 2020-10-07
      相关资源
      最近更新 更多