• [原创]SpringBoot上传图片踩的坑


    【原文链接】:https://blog.tecchen.xyz ,博文同步发布到博客园。
    由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容。
    欢迎访问我的个人网站:https://www.tecchen.xyz

    最近项目里面有个需求,要上传图片到阿里云的OSS服务。所以需要写个上传图片的接口给前端。
    这个简单的接口本来就给分配了1个工时,感觉也蛮简单的。但编码过程中遇到了好几个问题,现在一一记录下来,避免再次踩坑。

    • 1、图片不能超过1M
      报错信息:
    org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
    

    分析原因:
    图片大小超过了最大限制大小1048576 bytes=1MB,在org.springframework.boot.autoconfigure.web.MultipartProperties中可以看到默认的maxFileSize为1MB。
    解决方案:
    在application.properties中配置

    spring.http.multipart.maxFileSize = 10MB
    
    • 2、图片不能超过10M,连接重置
      报错信息:
    org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (10559924) exceeds the configured maximum (10485760)
    

    前端报错:
    Status:(failed)net::ERR_CONNECTION_RESET

    分析原因:
    请求大小超过了最大限制大小10485760 bytes=10MB,在org.springframework.boot.autoconfigure.web.MultipartProperties中可以看到默认的maxRequestSize为10MB。

    解决方案:

    @RestControllerAdvice
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public class MultipartExceptionConfigHandler {
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
    
        @ExceptionHandler(MultipartException.class)
        public MsCommonResult handleMultipartException(MultipartException icEx, HttpServletRequest request) {
            logger.warn("请求业务报错 uri: {}, message: {} ", request.getRequestURI(), icEx.getMessage());
            return MsCommonResult.fail("禁止上传大文件到服务器");
        }
    }
    

    配置ExceptionHandler后,但是并没有返回给前端400的状态码。继续研究后注意到org.apache.coyote.http11.AbstractHttp11Protocol的maxSwallowSize为2097152=2MB。
    继续解决:

    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
            if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
                // -1 means unlimited
                ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
            }
        });
        return tomcat;
    }
    

    至此,前台收到返回,返回信息如下:

    HTTP/1.1 400
    X-Application-Context: ms.maker.company:8071
    Content-Type: application/json;charset=UTF-8
    Transfer-Encoding: chunked
    Date: Wed, 05 Dec 2018 09:37:58 GMT
    Connection: close
    
    {"result":500,"detail":"禁止上传大文件到服务器","data":null}
    
    • 3、Linux服务器返回413:Request Entity too large
      报错信息:
    <html>
    <head><title>413 Request Entity Too Large</title></head>
    <body bgcolor="white">
    <center><h1>413 Request Entity Too Large</h1></center>
    <hr><center>nginx/1.12.2</center>
    </body>
    </html>
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    <!-- a padding to disable MSIE and Chrome friendly error page -->
    

    分析原因:
    图片大小超过1M时,提示该信息。经研究nginx的client_max_body_size默认大小为1m。

    解决方案:

    在http/server/location段配置client_max_body_size: 10m即可。
    
    • 4、返回JSON,IE9及低版本接受返回后,提示文件下载
      原因:
      后台响应的Content-Type为“application/json”,IE浏览器不识别。
      将返回的数据由对象转为json字符串,浏览器竟然可以自动识别解析。
      解决方案:
    方案一:
    @PostMapping(value = "/aliyunOssUpload", produces = "text/html;charset=UTF-8")
    public String aliyunOssUpload(@RequestParam("file") MultipartFile uploadFile)
    方案二:
    @PostMapping(value = "/aliyunOssUpload")
    public String aliyunOssUpload(@RequestParam("file") MultipartFile uploadFile, HttpServletResponse response) {
        response.setContentType("text/html;charset=UTF-8");
    }
    方案三:
    @PostMapping(value = "/aliyunOssUpload")
    public String aliyunOssUpload(@RequestParam("file") MultipartFile uploadFile, HttpServletResponse response) {
        response.setHeader("Content-Type", "text/html;charset=UTF-8");
    }
    
  • 相关阅读:
    8、vue_map使用
    10、vue_待续
    vue_ref与reactive响应式数据
    vue
    vue
    9、vue_echarts
    vue
    6、vue_登录页
    7、vue_待续
    vue_axios获取数据
  • 原文地址:https://www.cnblogs.com/Candies/p/10072411.html
Copyright © 2020-2023  润新知