[原創]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");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM