开发过程中要写文件的上传下载删除功能,自己整理了开发过程文档,仅供大家参考,如有不足之处,请各位指教,谢谢!
在开发Web应用程序时比较常见的功能之一,SpringMVC其中的一个优势就是允许用户利用multipart请求将本地文件上传到服务器。
Spring通过对ServletAPI的HttpServletRequest接口进行扩展,使其能够很好地处理文件上传。
扩展后的接口名为org.springframework.web.multipart.MultipartHttpServletRequest,内容如下:
public interface MultipartHttpServletRequest extends HttpServletRequest, MultipartRequest{
HttpMethod getRequestMethod();
HttpHeaders getRequestHeaders();
HttpHeaders getMultipartHraders(String paramOrFileName);
}
MultipartHttpServletRequest接口简单地扩展了默认的HttpServletRequest接口和MultipartRequest接口,并提供一些用来处理请求文件的方法。
MultipartRequest接口,内容如下:
public interface MultipartRequest {
Iterator<String> getFileNames();
MultipartFile getFile(String name);
List<MultipartFile> getFiles(String name);
Map<String, MultipartFile> getFileMap();
MultiValueMap<String, MultipartFile> getMultiFileMap();
String getMultipartContentType(String paramOrFileName);
}
使用multipart请求:
实际上只要发现一个multipart请求,就表明在控制器实例中存在一个实现MultipartHttpServletRequest接口的request对象。我们可以通过清单所示的方法来访问multipart请求中的上传文件,不过在处理上传文件之前,先来看一下上传表单的内容:
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>File upload download delete</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form id="submitForm" method="post" th:action="@{/test/upload}" action=""
enctype="multipart/form-data">
<input type="file" name="file" id="file"/>
<input id="saveButton" type="submit" th:value="上传" />
</form>
<a href="/download">下载</a>
</html>
需要注意的部分,实际上一个上传表单只需要满足如下两点:
1) enctype属性的属性值设为multipart/form-data。
2) input的type属性的属性值设为file。
<input>标签中属性type的值为file,且name属性的值为file,需要name属性值,是因为在使用接口MultipartRequest的getFile方法时需要使用name属性的值。upload操作会从请求中读取上传文件。
后端代码:
FileController.Scala
package com.yltest.controller
import java.net.URLEncoder
import com.yltest.service.FileService
import org.springframework.http.{HttpHeaders, HttpStatus, MediaType, ResponseEntity}
import org.springframework.web.multipart.MultipartFile
import org.springframework.sterrotype.Controller
import org.springframework.ui.model
import org.springframework.web.bind.annotation.{RequestMapping, ResponseBody}
@RestController
@RequestMapping(Array("/yl"))
class FileController(fileService:FileService){
@RequestMappy(Array("list"))
def list(model:Model, mess:String) :String = {
model.addAttribute("mess",mess)
"yl/list"
}
/*
* 文件上传
*/
@RequestMapping(Array("upload"))
def upload(file:MultipartFile):String={
val mess = fileService.upload(file)
"redirect:yl/list?mess=" + URLEncoder.encode(mess, "UTF-8")
}
/*
* 文件下载
*/
@RequestMapping(Array("download"))
def download(id:String):ResponseEntity[Array[Byte]]={
val (filename, downloadByte) = fileService.download(id)
val headers = new HttpHeaders()
headers.setContentDispositionFormData("attachment", filename)
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM)
new ResponseEntity[Array[Byte]](downloadByte, headers, HttpStatus.OK)
}
/*
* 删除
*/
@RequestMapping(Array("delete"))
def delete(id:String):String = {
val mess = fileService.delete(file)
"redirect:yl/list?mess=" + URLEncoder.encode(mess, "UTF-8")
}
}
FileService.Scala
注意:@Value("${testPath}") testPath : String 为配置文件中配置的绝对路径
import com.yltest.util.FileNameCheck 为自己编写的工具类,用于过滤文件名中的特殊字符
package com.yltest.service
import java.io.{File, FileInputStream}
import java.net.URLEncoder
import java.nio.file.Paths
import java.util
import com.yltest.util.FileNameCheck
import org.springframework.stereotype.Service
import org.slf4j.{Logger, LoggerFactory}
import org.springframework.bean.factory.annotation.Value
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.FileCopyUtils
import org.springframework.web.multipart.MultipartFile
import scala.collection.convert.decorateAll._
@Service
@Transactional
class FileService(fileDao:FileDao,
@Value("${testPath}") testPath : String){
val logger : Logger = LoggerFactory.getLogger(this.getClass)
//上传
def upload(file:MultipartFile) :Int = {
val fileTest = new FileTest
logger.info(s"file [$file]")
if(!file.isEmpty){
val fileName = FileNameCheck(file.getOriginalFilename)
val filePath = s"$testPath$fileName"
if(!Path.get(filePath).getParent.toFile.exists()){
Path.get(filePath).getParent.toFile.mkdirs()
}
val targetFile = new File(filePath)
file.transferTo(targetFile)
fileTest.fileUrl = filePath
}
//文件信息入库
fileDao.insert(fileTest)
}
//下载
def download(id:String):(String, Array[Byte]) = {
val fileTest = fileDao.getById(id).asJava
val fileName=URLEncoder.encode(fileTest.get(0).fileUrl.split("\\\\").last, "UTF-8")
val in = new FileInputStream(fileTest.get(0).fileUrl)
val fileBytes = FileCopyUtils.copyToByteArray(in)
(fileName, fileBytes)
}
//删除
def delete(id:String):String = {
val fileTest = fileDao.getById(id)
Paths.get(fileTest.get(0).fileUrl).toFile.delete()
val count = fileDao.delete(id)
if(count > 0) "删除成功!" else "删除失败!"
}
}
package com.yltest.util
import java.util.regex.Pattern
object FileNameUtil{
def checkFileName(fileName : String) : String = {
//空格:全角
val reg = "([\\s\\p{Zs}]*)+"
//文件名中不可出现的特殊字符
val filePatter = Pattern.compile("[\\s*\\\\/:*?\"<>|]")
val name = if(null == fileName) {
null
} else {
filePatter.matcher(fileName).replaceAll("")
}
name.replaceAll(reg, "")
}
}
//配置文件内容
testPath: D:\文件\
程序中dao部分的代码不做展示了,dao层操作数据库,获取数据信息。
关于org.springframework.web.multipart.MultipartFile的详细信息,如下展示:如果在请求中没有找到文件则getFile方法返回null。
package org.springframework.web.multipart;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.InputStreamSource;
public interface MultipartFile extends InputStreamSource {
String getName();
String getOriginalFilename();
//获得文件类型,以此决定允许上传的文件类型
String getContentType();
//判断上传文件是否为空文件,以此决定是否拒绝空文件
boolean isEmpty();
//获得文件长度,以此决定允许上传的文件大小
long getSize();
byte[] getBytes() throws IOException;
//将文件读取为java.io.InputStream流对象
@Override
InputStream getInputStream() throws IOException;
//将上传文件写到服务器上指定的文件
void transferTo(File dest) throws IOException, IllegalStateException;
}
- 支持多种文件格式,后端不用改
- 需要在springboot的配置文件里面指定上传下载的文件大小上限(如配置文件内容)
注意:MultipartFile.transferTo()需要的是相对路径
file.transferTo 方法调用时,判断如果是相对路径,则使用temp目录,为父目录一则,位置不对,二则没有父目录存在,因此产生上述错误。
-------------------------------------------------------------遇到的问题-------------------------------------------------------------------
上传附件报超出自带tomacat限制大小(默认1M)
解决方案 :
(1)在配置文件(application.yml)代码如下:
spring:
http:
multipart:
max-file-size: 20MB
max-request-size: 100MB
maxFileSize 单个数据大小
maxRequestSize 是总数据大小
-------------------------------------------------------------效果图-------------------------------------------------------------------
1.页面展示
2.上传文件
3.下载文件
4.删除文件,直接点击也买你中的删除按钮