【Java Web开发学习】Spring MVC文件上传
【Java Web开发学习】Spring MVC文件上传
转载:https://www.cnblogs.com/yangchongxing/p/9290489.html
文件上传临时路径配置
方式一、在java启动命令中加入这个参数
mkdir -p /ycx/tmp -java.tmp.dir=/ycx/tmp 方式二、在Spring配置文件中配置 spring: servlet: multipart: location: /ycx/tmp max-file-size: 500MB max-request-size: 500MB
文件上传有两种实现方式,都比较简单
方式一、使用StandardServletMultipartResolver
依赖Servlet3.0对Multipart请求的支持,需要MultipartConfigElement配置请求的相关参数
Java配置方式
@Bean public MultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); }
在Servlet中指定multipart配置,通过MultipartConfigElement设置上传临时路径,上传文件大小,上传请求的大小。
通过重载protected void customizeRegistration(ServletRegistration.Dynamic registration)方法实现,看代码
package cn.ycx.web.config; import java.io.IOException; import java.util.Properties; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletRegistration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // 将一个或多个路径映射到DispatcherServlet上 @Override protected String[] getServletMappings() { return new String[] {"/"}; } // 返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的bean @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] {RootConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] {ServletConfig.class}; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { // 上传文件的临时目录 String location = "/tmp"; // 上传文件的最大容量 long maxFileSize = 3145728; // 请求的最大容量 long maxRequestSize = 3145728; // 上传的最小临界值,大于该值才会被写入文件保存 // int fileSizeThreshold = 0; try { Properties prop = new Properties(); prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("upload.properties")); location = prop.getProperty("temporary.location"); maxFileSize = Long.parseLong(prop.getProperty("max.file.size")); maxRequestSize = Long.parseLong(prop.getProperty("max.request.size")); } catch (IOException e) {} // 文件上传配置 registration.setMultipartConfig(new MultipartConfigElement(location, maxFileSize, maxRequestSize, 0)); // 没有找到处理的请求抛出异常 boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); if(!done) throw new RuntimeException("设置异常(throwExceptionIfNoHandlerFound)"); } }
xml-base方式
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></bean>
web.xml配置DispatcherServlet初始化参数
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> ...省略... <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> <multipart-config> <!--临时文件的目录--> <location>E:/tmp</location> <!-- 上传文件最大3M --> <max-file-size>3145728</max-file-size> <!-- 上传文件整个请求不超过3M --> <max-request-size>3145728</max-request-size> </multipart-config> </servlet> ...省略... </web-app>
Html代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="/mvc/upload" enctype="multipart/form-data" method="post"> <input name="fileData" type="file"> <input type="submit" value="上传"> </form> </body> </html>
1、控制器接受文件原始byte[]。这种方式不可取,虽然能保存文件,但是我们不知道文件原始名称,也不知道文件类型。
@RequestMapping("/upload") public Map<String, String> upload(@RequestPart("fileData") byte[] fileData) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); if (fileData != null) { FileOutputStream out = new FileOutputStream(new File("F:\\war\\" + format.format(new Date()))); out.write(fileData); out.close(); } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
2、控制器接受MultipartFile类型
Multipart接口
public interface MultipartFile extends InputStreamSource { String getName();//参数名字 String getOriginalFilename();//原始文件名 String getContentType();//类型 boolean isEmpty();//文件是否空 long getSize();//文件字节大小 byte[] getBytes() throws IOException;//返回字节数组 @Override InputStream getInputStream() throws IOException;//输入流 void transferTo(File dest) throws IOException, IllegalStateException;//转换文件 }
控制器代码
@RequestMapping("/upload") public Map<String, String> upload(MultipartFile fileData) throws Exception { if (fileData != null) { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); fileData.transferTo(new File("F:\\war\\" + format.format(new Date()) + "_" + fileData.getOriginalFilename()));//保存文件 } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
3、控制器接受Part类型
Part接口
public interface Part { public InputStream getInputStream() throws IOException;//输入流 public String getContentType();//类型 public String getName();//参数名 public String getSubmittedFileName();//原始文件名 public long getSize();//字节大小 public void write(String fileName) throws IOException;//保存文件 public void delete() throws IOException;//删除文件 public String getHeader(String name);//获取头信息 public Collection<String> getHeaders(String name);//获取头信息 public Collection<String> getHeaderNames();//获取头信息 }
控制器代码
@RequestMapping("/upload") public Map<String, String> upload(@RequestPart("fileData") Part fileData) throws Exception { if (fileData != null) { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); fileData.write("F:\\war\\" + format.format(new Date()) + "_" + fileData.getSubmittedFileName());//保存文件 } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
方式二、使用CommonsMultipartResolver
依赖 commons-fileupload.jar 和 commons-io.jar。上传临时路径,文件大小都在对象中设置。
code-base方式
@Bean public MultipartResolver multipartResolver() throws IOException { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setUploadTempDir(new FileSystemResource(config.uploadTemporaryLocation())); multipartResolver.setMaxUploadSize(config.uploadMaxFileSize()); multipartResolver.setMaxInMemorySize(0); return multipartResolver; }
xml-base方式
<!-- 上传文件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"/> <!-- 最大内存大小 --> <property name="maxInMemorySize" value="10240"/> <!-- 最大文件大小,-1为不限制大小 --> <property name="maxUploadSize" value="-1"/> </bean>
示例代码:
实现了核心部分仅供参考。
package cn.ycx.web.controller; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import cn.ycx.web.config.PropertyConfig; /** * 上传 * @author 杨崇兴 2018-07-09 */ @Controller @RequestMapping("/upload") public class UploadController extends BaseController { /** * 属性配置 */ @Autowired private PropertyConfig config; @RequestMapping(value="/image", method=RequestMethod.POST, produces="application/json;charset=UTF-8") public String image(@RequestParam(value = "imageFile", required = false) MultipartFile multipartFile) { try { String serverPath = config.uploadImageSavePath() + new SimpleDateFormat("yyyy/MM/dd/").format(new Date()); File serverPathFile = new File(serverPath); //目录不存在则创建 if (!serverPathFile.exists()) { serverPathFile.mkdirs(); } String fileName = multipartFile.getOriginalFilename(); multipartFile.transferTo(new File(serverPath + fileName)); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return "success"; } }
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>上传</title> </head> <body> <form action="/ycxcode/upload/image" method="post" enctype="multipart/form-data"> <input type="text" name="discription" value="discription"/> <input type="file" name="imageFile"> <input type="submit" value="submit"/> </form> </body> </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端