SpringMVC中處理檔案上傳的兩種方式
阿新 • • 發佈:2021-08-01
前言
檔案上傳在web開發中很多地方都會用到,如使用者頭像上傳,商品圖片上傳。檔案上傳的請求的 content-type 必須為 multipart/form-data
請求內容
SpringMVC處理
SpringMVC中提供了兩種檔案解析器,CommonsMultipartResolver 和 StandardServletMultipartResolver。
示例
@GetMapping("testFileUpload1") public void testFileUload1(MultipartFile file) { System.out.println(file); }
CommonsMultipartResolver
這種方式依賴於Apache的fileupload元件
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
簡單原始碼如下
public class CommonsMultipartResolver extends CommonsFileUploadSupport implements MultipartResolver, ServletContextAware { private boolean resolveLazily = false; }
public abstract class CommonsFileUploadSupport { protected final Log logger = LogFactory.getLog(getClass()); private final DiskFileItemFactory fileItemFactory; private final FileUpload fileUpload; private boolean uploadTempDirSpecified = false; private boolean preserveFilename = false; }
核心為FileUpload類,將請求內容解析為一個包含檔名稱和檔案內容的物件。
StandardServletMultipartResolver
Servlet3.0對檔案上傳提供了支援
public interface HttpServletRequest extends ServletRequest {
/**
* 獲取檔案
*/
public Part getPart(String name) throws IOException,
ServletException;
/**
* 獲取一個請求上傳的所有檔案
*/
public Collection<Part> getParts() throws IOException,
ServletException;
}
Tomcat中對檔案上傳的實現
/**
* Wrapper object for the Coyote request.
*
* @author Remy Maucherat
* @author Craig R. McClanahan
*/
public class Request implements HttpServletRequest {
/**
* {@inheritDoc}
*/
@Override
public Collection<Part> getParts() throws IOException, IllegalStateException,
ServletException {
parseParts(true);
if (partsParseException != null) {
if (partsParseException instanceof IOException) {
throw (IOException) partsParseException;
} else if (partsParseException instanceof IllegalStateException) {
throw (IllegalStateException) partsParseException;
} else if (partsParseException instanceof ServletException) {
throw (ServletException) partsParseException;
}
}
return parts;
}
// 解析出檔案內容
private void parseParts(boolean explicit) {
// Create a new file upload handler
DiskFileItemFactory factory = new DiskFileItemFactory();
try {
factory.setRepository(location.getCanonicalFile());
} catch (IOException ioe) {
parameters.setParseFailedReason(FailReason.IO_ERROR);
partsParseException = ioe;
return;
}
factory.setSizeThreshold(mce.getFileSizeThreshold());
ServletFileUpload upload = new ServletFileUpload();
upload.setFileItemFactory(factory);
upload.setFileSizeMax(mce.getMaxFileSize());
upload.setSizeMax(mce.getMaxRequestSize());
parts = new ArrayList<>();
try {
List<FileItem> items =
upload.parseRequest(new ServletRequestContext(this));
int maxPostSize = getConnector().getMaxPostSize();
int postSize = 0;
Charset charset = getCharset();
for (FileItem item : items) {
ApplicationPart part = new ApplicationPart(item, location);
parts.add(part);
}
}
}
}
Tomcat中對檔案上傳的實現就是參考的Apache的commons-fileupload元件
SpringBoot預設使用的StandardServletMultipartResolver來處理檔案上傳