1.任务
这一节主要的任务是解决文件的上传和下载功能
2.文件上传
概念:将本地的图片上传到浏览器上面
点击文件上传,前端就会发送如上的请求,服务端应该根据URL和请求方法来处理请求
CommonController类:
@RestController
@Slf4j
@RequestMapping("/common")
public class CommonController {//将在配置文件中的路径参数赋给basePath@Value("${reggie.path}")private String basePath;/*** 文件上传* @param file* @return*/@PostMapping("/upload")public R<String> upload (MultipartFile file){//file是一个临时文件(上传文件之后会放在临时文件夹里)本次请求结束之后,文件就会删除log.info(file.toString());//获取原始文件名String originalFilename = file.getOriginalFilename();//将原始文件名后缀拿到String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//使用UUID重新生成文件名并且拼接了后缀,为了防止重名String fileName = UUID.randomUUID().toString() + suffix;//如果存储路径不存在,则要先新建一个文件夹//创建一个目录对象File dir = new File(basePath);if (!dir.exists()){dir.mkdir();}//将文件存储在指定位置(防止临时文件删除)try {//basePath:存储路径//filename:文件名加后缀file.transferTo(new File(basePath+fileName));} catch (IOException e) {throw new RuntimeException(e);}//为什么返回文件名,因为当添加菜品的时候,我们需要把图片也存到菜品的表里,所以要知道文件名return R.success(fileName);}
}
前端input标签:
application.properties:
reggie.path=E:/springbootPicture/
分三个部分来介绍上面的代码
- 首先是要接收前端传过来的文件,这里springmvc给我们提供了一个文件处理类MultipartFile,参数名这里由于是前端input标签里指定的name为file,所以参数名也必须是file
- 当服务端接收到前端传来的图片之后,会把图片存放在临时文件中,当这个请求结束后,图片就会删除,所以接下来应该做的就是把图片存放在我们指定的目录下。这里的文件目录是放在了application.properties配置文件中了,然后在controller层中用@Value注解引入
- 最后一步做了一个简单的判断,如果本地没有指定的文件目录,则就生成该目录,反之,就直接将获取的文件存放在该目录下
3.文件下载
前端页面先发送请求,然后服务端再通过输出流的方式,把它写回到浏览器页面,这样就能实现文件(图片)的展现
当把图片上传之后,浏览器立马就会再次发送请求,路径里会把图片的name发送过来
/**** @param name 获取文件名* @param response 来操作流*/@GetMapping("/download")public void download(String name, HttpServletResponse response){try {//输入流(读取文件内容)FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));//输出流(将文件写回浏览器,在浏览器展示图片)//这里不new一个输出流,而是用response来get一个输出流,因为要返回给浏览器ServletOutputStream outputStream = response.getOutputStream();//设置响应类型(类型为图片)response.setContentType("image/jpeg");//通过输入流来读取文件byte[] bytes = new byte[1024];int length = 0;//如果length不为-1表示还没有读完,则一边读一边写while((length = fileInputStream.read(bytes)) != -1) {//向浏览器写文件内容,从0开始写到length为止outputStream.write(bytes,0,length);}//关闭资源fileInputStream.close();outputStream.close();} catch (Exception e) {throw new RuntimeException(e);}}
上面的方法主要有以下几步:
- new一个输入流,读取文件内容
- 用response创建输出流,将文件写回浏览器
- 关闭输入和输出流