首頁 > 軟體

Springboot上傳檔案時提示405問題及排坑過程

2022-07-01 14:03:49

Springboot上傳檔案時提示405

問題描述:上傳檔案時請求不通,狀態碼返回405,如下圖:

 問題分析:405 Method Not Allowed,請求行中指定的請求方法不能被用於請求相應的資源。該響應必須返回一個Allow 頭資訊用以表示出當前資源能夠接受的請求方法的列表。簡單說就是請求方法不支援,這樣就找到了一個解決方向。(以下分析了3種返回該錯誤的情況)

解決方案1

看下介面是否支援請求的方式,檔案上傳使用的POST方法,看下介面是否支援。後臺紀錄檔如下:

解決方案2

發現介面確實支援POST請求,那麼問題就不是這麼明顯了。因為該介面是用於檔案上傳,所以問題應該是在這裡。由於Springboot預設的檔案上傳大小為1MB,自己再看發現檔案大小超過了限制(上傳的7.13MB),後臺紀錄檔如下:

修改Springboot組態檔:

# 找到Springboot的application.properties組態檔,新增以下設定
spring.servlet.multipart.enabled=true #是否啟用http上傳處理
spring.servlet.multipart.max-request-size=10MB #最大請求檔案的大小
spring.servlet.multipart.max-file-size=10MB #設定單個檔案最大長度

解決方案3:修改檔案大小設定後,發現還是報405,這就懵了,繼續看後臺紀錄檔:

明白了,發現後端使用@RequestParam(“file”) 註解標註的MultipartFile引數沒有獲取到檔案,對比前端請求引數名發現不一致造成的。

問題解決。 

Springboot使用過程中遇到的一些問題

僅記錄個人遇到的一些問題及原因,和解決方案。

異常一

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: ContextPath must start with '/' and not end with '/'
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at com.pjx.Application.main(Application.java:15) [classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: ContextPath must start with '/' and not end with '/'
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:199) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:162) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    ... 8 common frames omitted
Caused by: java.lang.IllegalArgumentException: ContextPath must start with '/' and not end with '/'
    at org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer.checkContextPath(AbstractConfigurableEmbeddedServletContainer.java:132) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.AbstractConfigurableEmbeddedServletContainer.setContextPath(AbstractConfigurableEmbeddedServletContainer.java:120) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.autoconfigure.web.ServerProperties.customize(ServerProperties.java:198) ~[spring-boot-autoconfigure-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:73) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:59) ~[spring-boot-1.5.10.RELEASE.jar:1.5.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.14.RELEASE.jar:4.3.14.RELEASE]
    ... 16 common frames omitted

原因:設定專案名稱設定錯誤

錯誤設定:

server:
  context-path: admin

正確設定:

server:
  context-path: /admin

異常二:Mysql連線報錯

Could not create connection to database server

原因:MySql版本(8.0.28)和MySql驅動版本(5.1.45)不匹配,驅動版本換成8.0+就ok了。

使用:select version() from DUAL查詢mysql版本。

異常三:整合Druid密碼解密失敗

異常棧:Caused by: com.mysql.cj.exceptions.CJException: Access denied for user 'root'@'localhost' (using password: YES)

分析:密碼使用明文時,能正常連線資料庫,查詢到表資料。分析是密碼沒有成功解密。

pom新增的Druid依賴如下:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
</dependency>

Druid解密是在ConfigFilter中init中進行的,斷點跟蹤如下圖,設定中的config.decrypt,config.decrypt.key是連在一起的,沒有分開,所以decrypt=false,沒有對密碼進行解密操作

 檢查設定,資料庫設定如下圖

原因:connect-properties是druid-spring-boot-starter包下的設定引數,沒有對properties進行解析處理,換成Druid報下的設定引數connection-properties。properties引數會進行按 ; 進行分隔處理,獲取到具體的設定資訊。

解決方案:換成connection-properties即可

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com