Spring Boot 中集成 Knife4j:解決文件上傳不顯示文件域的問題
在使用 Knife4j 為 Spring Boot 項目生成 API 文檔時,開發者可能會遇到文件上傳功能不顯示文件域的問題。本文將詳細介紹如何解決這一問題,并提供完整的解決方案。
Knife4j官網
一、環境版本
- Spring Boot:2.7.4
- Knife4j:3.0.3
二、問題描述
在使用 Knife4j 配置文件上傳接口時,文件上傳的表單域可能無法正常顯示,導致無法選擇文件進行上傳。即使使用了 @ApiParam
注解的 type
或 format
屬性,問題仍然存在。
三、解決方案
1. 使用 @RequestPart
注解
在 Spring Boot 中,@RequestPart
注解用于處理 multipart/form-data
類型的請求參數,適用于文件上傳場景。通過正確使用 @RequestPart
注解,可以確保 Knife4j 能夠正確識別文件上傳的表單域。
示例代碼
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;@RestController
@RequestMapping("/file")
public class FileController {@ApiOperation(value = "文件上傳接口")@PostMapping("/upload")public String uploadFile(@RequestPart @RequestParam("file") MultipartFile file) {if (file.isEmpty()) {return "文件為空,請選擇文件";}// 處理文件上傳邏輯return "文件上傳成功";}
}
2. 配置 Knife4j
確保 Knife4j 的配置類正確配置了 API 文檔的路徑和包掃描。以下是一個典型的 Knife4j 配置類示例:
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration
@EnableSwagger2
@EnableKnife4j
public class Knife4jConfig {@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.your.package")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("API 文檔").description("API 文檔描述").version("1.0").build();}
}
3. 檢查 Spring Security 配置
如果項目中使用了 Spring Security,確保放行了 Knife4j 和 Swagger 相關的路徑。例如:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.requestMatchers("/api/auth/**").permitAll().requestMatchers("/doc.html", "/webjars/**", "/swagger-resources/**", "/v3/**").permitAll().anyRequest().authenticated();}
}
4. 兼容性處理
對于 Spring Boot 2.6+,可能需要額外的兼容性處理。以下是一個兼容性處理的示例:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import java.util.List;
import java.util.stream.Collectors;@Configuration
public class Knife4jCompatibilityConfig {@Beanpublic static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {return new BeanPostProcessor() {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof RequestMappingHandlerMapping) {customizeSpringfoxHandlerMappings(((RequestMappingHandlerMapping) bean).getHandlerMethods().keySet());}return bean;}private void customizeSpringfoxHandlerMappings(List<String> mappings) {List<String> copy = mappings.stream().filter(mapping -> !mapping.contains("PatternParser")).collect(Collectors.toList());mappings.clear();mappings.addAll(copy);}};}
}
四、驗證結果
按照上述步驟配置后,文件上傳接口的文件域將能夠正常顯示。在 Knife4j 生成的文檔中,文件上傳的表單域將正確顯示,用戶可以正常選擇文件進行上傳。