1 问题:
JavaWeb如何实现文件上传?
2 解决的一般思路:
- 首先于html或者jsp中创建一个表单,把表单的encType属性改成 multipart/form-data,且表单必须是post方式
- 后台设法拿到这个文件对象,并且存入到磁盘中的一个位置即可。
3 具体实现方式:
一种是传统的servlet方式,一种是SpringMvc方式。
3.1 servlet方式:
(1)实现文件上传,我们需要导入文件上传相关的依赖,然后通过依赖中的一些类来实现文件上传的功能。
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
</dependency>
(2)前端form表单编写(注意:enctype为:mutipart/form-data时,提交表单,表单的内容时分成多个部分的,即普通表单内容属于一部分,上传的文件属于另一部分)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传Demo</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
描述信息: <input type="text" name="describe">
选择文件:<input type="file" name="myFile">
<input type="submit" value="上传">
</form>
</body>
</html>
(3)后台接口编写—定义一个Servlet,然后在web.xml文件下配置一下Servlet,并且设置< url -pattern>为/upload
public class FileUploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取应用打包后的根目录下的一个路径
String path = req.getServletContext().getRealPath("/upload/");
File file=new File(path);
if(!file.exists()){
// 不存在,则创建此路径
file.mkdirs();
}
String fileName=null;
// 创建一个磁盘文件项对象
FileItemFactory fileItemFactory=new DiskFileItemFactory();
// 关键所在,文件上传的Servlet,用来解析请求,获取其中的文件项(包含普通表单内容和上传的文件)
ServletFileUpload fileUpload=new ServletFileUpload(fileItemFactory);
try {
//解析请求,得到其中的文件项
List<FileItem> fileItems = fileUpload.parseRequest(req);
for (FileItem fileItem : fileItems) {
//便利文件项List,并且判断其是不是上传的文件
if (fileItem.isFormField()) {
//不是文件,跳过此次循环
continue;
}
fileName = fileItem.getName();
String uuid = UUID.randomUUID().toString();
fileName=uuid+"_"+fileName;
//上传的文件写入磁盘
fileItem.write(new File(path,fileName));
//删除产生的临时文件
fileItem.delete();
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("文件上传成功");
}
以上,文件就被上传到了项目打包目录下的upload文件夹中。
3.2 SpringMvc方式
SpringMvc毕竟是框架,对很多细节都做了封装,使用起来非常方便,比Servlet实现方式简洁了不少。
(1)导入SpringMvc的依赖即可
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
(2)前端form表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传Demo</title>
</head>
<body>
<form action="/uploadByMvc" method="post" enctype="multipart/form-data">
描述信息: <input type="text" name="describe">
选择文件:<input type="file" name="myFile">
<input type="submit" value="上传">
</form>
</body>
</html>
(3)配置一个文件解析器–作用:解析请求,拿到请求中的文件。跟Servlet方式的差别就是:Servlet方式是使用一个ServletFileUpload对象解析请求,从而获取文件;而SpringMvc可以直接使用其封装好的文件解析器,简单配置一下就好了。(注意:bean的名称必须是multipartResolver,我猜测:前端控制器是通过名字来找的这个bean)
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置上传文件的大小限制-->
<property name="maxUploadSize" value="10000000"></property>
</bean>
(4)后台接口编写
@Controller
public class FileUploadController {
@RequestMapping("/uploadByMvc")
public String uploadFile(@RequestParam("myFile") MultipartFile file,
Model model) throws IOException {
String filePath="D:\\JavaCode\\SpringMvc\\fileUpload\\src\\main\\resources\\upload";
File targetFile=new File(filePath);
if(!targetFile.exists()){
targetFile.mkdirs();
}
String filename = UUID.randomUUID().toString()+"_" +file.getOriginalFilename();
//将文件写入磁盘
file.transferTo(new File(filePath,filename));
model.addAttribute("msg",filename+"上传成功了");
return "success";
}
以上是不是简单了很多呢?配置一个文件解析器,然后在后台接口直接用一个MutipartFile对象去接收上传的文件就可以了。
总结:
以上就是文件上传的两种方式,SpringMvc真的方便多了。。。