springboot项目学习-瑞吉外卖(4)

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创建输出流,将文件写回浏览器
  • 关闭输入和输出流

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 12:02:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 12:02:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 12:02:03       82 阅读
  4. Python语言-面向对象

    2024-03-30 12:02:03       91 阅读

热门阅读

  1. 常用设计模式

    2024-03-30 12:02:03       36 阅读
  2. Flume和Kafka的区别

    2024-03-30 12:02:03       42 阅读
  3. c语音函数大全(W开头)

    2024-03-30 12:02:03       43 阅读
  4. ORACLE 存中文

    2024-03-30 12:02:03       35 阅读
  5. LeetCode 345. 反转字符串中的元音字母

    2024-03-30 12:02:03       39 阅读
  6. CentOS 7.9上创建Redis用户和组

    2024-03-30 12:02:03       41 阅读
  7. MySQL的索引

    2024-03-30 12:02:03       32 阅读
  8. Redis中Hash数据结构的底层实现

    2024-03-30 12:02:03       45 阅读
  9. RISC-V单板计算机模拟和FPGA板多核IP实现

    2024-03-30 12:02:03       42 阅读
  10. axios详解

    2024-03-30 12:02:03       31 阅读