文件上传下载是客户端与服务器端交互数据的一种体现方式,核心仍然是http
报文,文件上传下载的具体原理如下所示
JAVA 文件上传:
一、前端界面(略显简陋):
(1)未选择文件
(2)选择文件
点击上传后即可上传文件。
二、前端代码:
<form action="/teacher/tTeacher/upload" method="post" id="form1" enctype="multipart/form-data">
<input type="file" name="file" class="" /><br />
<button type="submit" onclick="" class="">上传</button>
</form>
①上传文件依然是在from表单中提交的,通过表单形成请求体传输至服务器端。
②标签存储需要上传的文件,需要设置type=“file”,点击input会使浏览器调用操作系统API选择文件并暂存()。
③点击submit将数据封装至请求体,发送至指定url(action的值)
④服务器端程序接受请求体并解析获取文件,再存储(File对象、I/O流存储)
三、请求头:
四、后端接收文件代码:
/**
* 文件上传
*
* @param multipartFile
* @return
*/
@PostMapping("upload")
@ResponseBody
public AjaxResult upload(@RequestParam("file") MultipartFile multipartFile) {
return success(FileUtil.uploadFile(multipartFile));
}
接收文件的方法参数为MultipartFile,此类用于接收文件并存储在实例化对象中,
并在后续程序中处理存储到计算机中。
处理文件的代码:
public static String uploadFile(MultipartFile multipartFile){
if(multipartFile == null){
return null;
}
//获取文件相对路径
String fileName = getUploadFileName(multipartFile.getOriginalFilename());
String dateDir = DateUtil.format(null,DateUtil.PATTERN_yyyyMMdd);
File destFileDir = new File(uploadLocalPath + File.separator + dateDir);
if(!destFileDir.exists()){
destFileDir.mkdirs();
}
try {
File destFile = new File(destFileDir.getAbsoluteFile()+File.separator+fileName);
multipartFile.transferTo(destFile);
logger.info("文件【"+multipartFile.getOriginalFilename()+"】上传成功");
return uploadSuffixPath + "/" + dateDir+"/"+fileName;
} catch (IOException e) {
logger.error("文件上传异常:"+multipartFile.getOriginalFilename(),e);
return null;
}
}
JAVA 文件下载:
一、前端界面:
点击下载后:
二、前端代码:
<table border="1" class="layui-table">
<tr>
<th>序号</th>
<th>文件名</th>
<th> 下载</th>
</tr>
<tr th:each="file,status:${Filename}">
<td th:text="${status.count}"></td>
<td th:text="${file.fileName}"></td>
<td ><a th:href="@{'/teacher/tTeacher/download/'+${file.fileName}}" class="layui-btn layui-btn-normal radius">下载</a></td>
</tr>
</table>
下载是一个a标签,href为处理文件下载的controller,文件名放在url中,在controller可以取出文件信息(下边会指出)。效果相当于带着文件名的form表单。
三、后端提供下载文件代码:
@RequestMapping("download/{filepath}")
public ResponseEntity<byte[]> download(@PathVariable("filepath") String filepath) throws IOException {
//根据文件名加上路径形成文件的绝对路径。
String Filepath=FileSolution.PAth+File.separator+filepath;
//根据文件的绝对路径通过File类生成file文件对象
File file=new File(Filepath);
//新建一个HTTpHeaders类用于设置响应体头信息
HttpHeaders headers = new HttpHeaders();//http头信息
//设置响应头
String downloadFileName = new String(filepath.getBytes("UTF-8"),"iso-8859-1");//设置编码
headers.setContentDispositionFormData("attachment", downloadFileName);
//设置Content-Type(重要),设置响应体的数据类型(浏览器会根据不同的数据类型做出不同的操作,比如text/html类型,浏览器会解析为网页,比如MediaType.APPLICATION_OCTET_STREAM(二进制流)类型,浏览器会将响应体内容以文件形式保存至计算机。)
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息
//将文件转为字节数组并与请求头状态等一同放在响应体中返回给请求方
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
}
之后,客户端的浏览器收到响应体解析数据保存文件,上图所示
文件上传下载示意图
文件上传示意图:
文件下载示意图: