赞
踩
接下来将文件上传和下载的相关知识结合起来,实现一个文件上传和下载的案例。在实现案例之前,首先分析案例的功能需求。本案例要实现的功能为,将文件上传到项目的文件夹下,文件上传成功后将上传的文件名称记录到一个文件中,并将记录的文件列表展示在页面,单击文件列表的链接实现文件下载。
• 搭建文件上传和下载的环境。• 实现文件上传功能。• 实现获取文件列表功能。• 编写文件上传和下载页面。• 实现文件下载。
接下来按照分析思路实现文件上传和下载,具体步骤如下所示。
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.4</version>
- </dependency>
在spring-mvc.xml中配置多部件解析器,具体配置如下所示。
- <bean id="multipartResolver" class=
- "org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
- <property name="maxUploadSize" value="2097152" />
- </bean>
为了便于对files.json文件内容的存取,创建和files.json内容对应的资源类Resource,Resource类的具体代码如下所示。
- public class Resource {
- private String name; //name属性表示文件名称
-
- public Resource() {
- }
-
- public Resource(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
- import org.apache.commons.io.IOUtils;
-
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
-
- public class JSONFileUtils {
- public static String readFile(String filepath) throws Exception {
- FileInputStream fis = new FileInputStream(filepath);
- return IOUtils.toString(fis);
- }
-
- public static void writeFile(String data, String filepath)
- throws Exception {
- FileOutputStream fos = new FileOutputStream(filepath);
- IOUtils.write(data, fos);
- }
- }
- import com.fasterxml.jackson.core.type.TypeReference;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.itheima.pojo.Resource;
- import com.itheima.utils.JSONFileUtils;
- import org.apache.commons.io.FileUtils;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.http.ResponseEntity;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.multipart.MultipartFile;
- import sun.misc.BASE64Encoder;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.List;
-
- @Controller
- public class FileController {
- /**
- * 文件上传
- */
- @RequestMapping("fileload")
- public String fileLoad(MultipartFile[] files,
- HttpServletRequest request) throws Exception {
- //设置上传的文件所存放的路径
- String path = request.getServletContext().getRealPath("/") + "files/";
- ObjectMapper mapper = new ObjectMapper();
- if (files != null && files.length > 0) {
- //循环获取上传的文件
- for (MultipartFile file : files) {
- //获取上传文件的名称
- String filename = file.getOriginalFilename();
- ArrayList<Resource> list = new ArrayList<>();
- //读取files.json文件中的文件名称
- String json = JSONFileUtils.readFile(path + "/files.json");
- if (json.length() != 0) {
- //将files.json的内容转为集合
- list = mapper.readValue(json,
- new TypeReference<List<Resource>>() {
- });
- for (Resource resource : list) {
- //如果上传的文件在files.json文件中有同名文件,将当前上传的文件重命名,以避免重名
- if (filename.equals(resource.getName())) {
- String[] split = filename.split("\\.");
- filename = split[0] + "(1)." + split[1];
- }
- }
- }
- // 文件保存的全路径
- String filePath = path + filename;
- // 保存上传的文件
- file.transferTo(new File(filePath));
- list.add(new Resource(filename));
- json = mapper.writeValueAsString(list); //将集合中转换成json
- //将上传文件的名称保存在files.json文件中
- JSONFileUtils.writeFile(json, path + "/files.json");
- }
- request.setAttribute("msg", "(上传成功)");
- return "forward:fileload.jsp";
- }
- request.setAttribute("msg", "(上传失败)");
- return "forward:fileload.jsp";
- }
- }
在FileController中新增获取文件列表的方法getFilesName(),getFilesName()方法获取files.json文件中的内容,并且以JSON格式返回数据。
- @ResponseBody
- @RequestMapping(value = "/getFilesName",
- produces = "text/html;charset=utf-8")
- public String getFilesName(HttpServletRequest request,
- HttpServletResponse response) throws Exception {
- String path = request.getServletContext().
- getRealPath("/") + "files/files.json";
- String json = JSONFileUtils.readFile(path);
- return json;
- }
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>文件上传和下载</title>
- <script src="${ pageContext.request.contextPath }/js/jquery-3.6.0.js" type="text/javascript"></script>
- </head>
- <body>
- <table border="1">
- <tr>
- <td width="200" align="center">文件上传${msg}</td>
- <td width="300" align="center">下载列表</td>
- </tr>
- <tr>
- <td height="100">
- <form action="${pageContext.request.contextPath}/fileload"
- method="post" enctype="multipart/form-data">
- <input type="file" name="files" multiple="multiple"><br/>
- <input type="reset" value="清空"/>
- <input type="submit" value="提交"/>
- </form>
- </td>
- <td id="files"></td>
- </tr>
- </table>
- </body>
- </html>
-
- <script>
- $(document).ready(function () {
- var url = "${pageContext.request.contextPath }/getFilesName";
- $.get(url, function (files) {
- var files = eval('(' + files + ')');
- for (var i = 0; i < files.length; i++) {
- $("#files").append("<li>" +
- "<a href=${pageContext.request.contextPath }" + "" +
- "\\" + "download?filename=" + files[i].name + ">" +
- files[i].name + "</a></li>");
- }
- })
- })
- </script>
在实现文件下载的功能时,还需要注意文件中文名称的乱码问题。在使用Content-Disposition设置参数信息时,如果Content-Disposition中设置的文件名称出现中文字符,需要针对不同的浏览器设置不同的编码方式。目前Content-Disposition支持的编码方式有UrlEncode编码、Base64编码、RFC2231编码和ISO编码。本案例不对全部浏览器的编码方式进行设置,只对FireFox浏览器和非FireFox浏览器(如IE)分别进行编码设置。
- /**
- * 根据浏览器的不同进行编码设置,返回编码后的文件名
- */
- public String getFileName(HttpServletRequest request,
- String filename) throws Exception {
- BASE64Encoder base64Encoder = new BASE64Encoder();
- String agent = request.getHeader("User-Agent");
- if (agent.contains("Firefox")) {
- // 火狐浏览器
- filename = "=?UTF-8?B?" + new String
- (base64Encoder.encode(filename.getBytes("UTF-8"))) + "?=";
- } else {
- // IE及其他浏览器
- filename = URLEncoder.encode(filename, "UTF-8");
- }
- return filename;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。