SpringBoot 处理post消息出错

http post 向后端传送图片,后端报错

遇到的现象和发生背景

使用微信小程序,想后端发送图片,后端直接报错,MalformedStreamException: Header section has more than 10240 bytes (maybe it is not properly terminated)。但是我曾经成功实现过此功能,相关代码应该没动过,就突然报错。
补充:因为怀疑是tomcat的错,清空后重新加载了maven库,现在喜提新的报错:org.apache.tomcat.util.http.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
版本:springboot2.7.7 | tomcat-embed-core-9.0.70.jar:9.0.70 | JAVA11 | 阿里云镜像

代码

前端

wx.uploadFile({
    // 微信小程序前端提供的api
    url: this.data.http+"register",
    filePath: this.data.imagePath,
    header:{
      'content-type': 'multipart/form-data',
      "accept": "application/json"
    },
    name: 'image',
    success(res){
    }
  })

后端

@RestController
public class Controller {
 @PostMapping("/register")//
    public String register(HttpServletRequest request) throws IOException {
        log.info("controller: register");
        return "success";
    }
}

报错内容

org.apache.tomcat.util.http.fileupload.MultipartStream$MalformedStreamException: Header section has more than 10240 bytes (maybe it is not properly terminated)
    at org.apache.tomcat.util.http.fileupload.MultipartStream.readHeaders(MultipartStream.java:523) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:243) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
  at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:142) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:252) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:276) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
org.apache.tomcat.util.http.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.tomcat.util.http.fileupload.MultipartStream.readHeaders(MultipartStream.java:520) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.findNextItem(FileItemIteratorImpl.java:243) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl.<init>(FileItemIteratorImpl.java:142) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:252) ~[tomcat-embed-core-9.0.70.jar:9.0.70]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:276) ~[tomcat-embed-core-9.0.70.jar:9.0.70]

我的解答思路和尝试过的方法,

网上搜过解答,最多的是要透 传网关(原因:原消息经过网关后没有以/r/n/r/n结束消息头),但是我都是使用springboot默认配置,并且曾经成功实现了此功能,网关应该没问题。
曾怀疑微信小程序穿过来的有错,但是使用wireshark,确认消息是没问题的,问题出在JAVA后端。
代码应该没问题,可能是我的配置有冲突,但是我重新开了一个springboot项目,没有修改xml文件,问题依旧。
此外,网上还找到一种解决思路:在applicant.properties文件中添加:server.max-http-header-size=102400, 此时,改报:

org.apache.tomcat.util.http.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly

尝试使用filter看看,结果无法断点,直接报错

补充xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>helloSpringBoot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>helloSpringBoot</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 导入配置文件处理器,配置文件进行绑定就会有提示,需要重启 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>mysql</groupId>-->
<!--            <artifactId>mysql-connector-java</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--thymeleaf模板引擎配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- mybatis依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- Apache Http Begin -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>fluent-hc</artifactId>
            <version>4.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.intellij</groupId>
            <artifactId>annotations</artifactId>
            <version>6.0.3</version>
        </dependency>
     <!-- Apache Http End -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.4</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.6</version>
            </plugin>
        </plugins>

    </build>

    <repositories>
        <repository>
            <id>alimaven</id>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>

    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>alimaven</id>
            <url>https://maven.aliyun.com/repository/public</url>
        </pluginRepository>
    </pluginRepositories>

</project>

希望能告知原因及解决思路

springboot内置的Tomcat存在bug,进行升级即可。

将版本升级到2.3.0.RELEASE 以上。

使用以下版本升级你的依赖项:

org.apache.tomcat.embed tomcat-embed-core 9.0.33 org.springframework.boot spring-boot-starter-parent 2.3.0.RELEASE

有尝试过抓包分析不?
建议先尝试下抓包分析
1、初步怀疑是文件的部分原因。
2、去掉网关的解密处理
3、是否是某个环境依赖升级过版本?存在匹配问题?

抓包看看,就这点东西,请求头不会超过限制,超过限制只可能是文件数据走了header

  1. 去掉header试试看
  2. 抓包截图看看
  3. 你的小程序直接访问你的springboot项目,没有啥中转吧?

SpringBoot中post
可以借鉴下
https://blog.csdn.net/m0_67394002/article/details/126114363

MalformedStreamException: Header section has more than 10240 bytes (maybe it is not properly terminated) 这个错误通常表示请求头中的信息过大。

当 HTTP POST 请求发送图片时,请求头中会包含图片的相关信息(例如图片的大小、MIME 类型等)。如果这些信息过大,可能会导致 MalformedStreamException 异常。

在您的情况下,可能是因为您发送的图片过大,导致请求头中的信息过大,从而导致了这个错误。

为了解决这个问题,您可以尝试以下几种方法:

  1. 减小图片的大小:可以使用图片压缩工具将图片压缩到更小的大小,以减小请求头中的信息量。
  2. 增大请求头的大小限制:如果是服务器端的问题,可以尝试增大服务器端请求头的大小限制,以减小图片的大小:可以使用图片压缩工具将图片压缩到更小的大小,以减小请求头中的信息量。
  3. 增大请求头的大小限制:如果是服务器端的问题,可以尝试增大服务器端请求头的大小限制,以便能够处理更大的请求头。
  4. 检查代码是否有问题:如果您的代码中有任何错误,可能会导致请求头不正确,从而导致 MalformedStreamException 异常。因此,应该检查代码,确保代码正确无误。

我之前也遇到过这个请求头超过最大现在问题 之前有过header是因为nginx的问题 你可以试试这个ng设置

你的前端请求的请求方式没写呀,加个post请求方式呀

这个错误很可能是由于您的 HTTP 请求的头部信息有问题导致的。在这种情况下,您可能需要检查以下内容:

1.确保您在请求头中使用了正确的 Content-Type。对于发送图片,您应该使用 Content-Type: multipart/form-data。

2.确保您在请求头中正确指定了边界。对于 multipart/form-data 请求,边界用于标记不同部分的分隔符。您可以使用以下代码生成边界字符串:

String boundary = "-----" + System.currentTimeMillis();


然后,在请求头中使用以下代码设置边界:

request.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);


3.确保您的图片数据正确的编码成二进制格式。在发送请求之前,您可以使用以下代码将图片数据编码成二进制格式:


byte[] imageData = // 图片数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();

4.确保您的 HTTP 请求正确的发送了图片数据。在发送请求之前,您可以使用以下代码将图片数据添加到请求体中:

OutputStream out = connection.getOutputStream();
out.write(("--" + boundary + "\r\n").getBytes());
out.write(("Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"\r\n").getBytes());
out.