SpringBoot + Swagger2 文件上传、下载、直接响应图片

概要

代码的整体逻辑是,文件上传到服务器后,我们把文件以IO的形式写到磁盘中,然后返回一个网络路径。

当我们要请求文件时,先将URL过滤,那么分两种情况,第一种情况是 我们的文件是图片类型,我们就直接响应回图片;如果是非图片类型,那么就提供下载功能

单文件上传

    /**
     * 上传接口
     * @param file
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    @ApiOperation(value = "上传接口")
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file)
            throws IllegalStateException, IOException {
        return this.fileService.upload(file);
    }
    @Value("${upload.localPath}")
    private String localPath;

    @Value("${upload.netPath}")
    private String netPath;

    @Override
    public String upload(MultipartFile file) throws IOException {

        if(file == null) {
            throw new BaseException(Constant.BUSINESS, ResultEnum.FILE_NOT_FOUND);
        }

        String originalFileName = file.getOriginalFilename();
        String[] arr = originalFileName.split("\\.");
        String prefix = arr[arr.length - 1];
        String fileName = System.currentTimeMillis() + "." + prefix;
        Boolean res = IMAGE_TYPE_LIST.contains(prefix);
        String path;

        if(res) {
            path = localPath + "\\image";
        } else {
            path = localPath + "\\file";
        }
        path += LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        File filePath = new File(path, fileName);
        // 如果文件目录不存在,创建目录
        if (!filePath.getParentFile().exists()) {
            filePath.getParentFile().mkdirs();
        }
        // 写入文件
        file.transferTo(filePath);
        return netPath +"/"+ fileName;
    }

其中@value是SpringBoot在配置文件中查找自定义的配置,直接映射到相应的变量中,这里需要自己配置

多文件上传

    /**
     * 多文件上传
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "文件上传",notes = "文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "files",value = "多个文件,",paramType = "formData",allowMultiple=true,required = true,dataType = "file"),
            @ApiImplicitParam(name = "uId",value = "上传用户ID,",paramType = "query",required = true,dataType = "Long")
    })
    @PostMapping(value = "/uplode/files", headers = "content-type=multipart/form-data")
    public void uplodeFiles(@RequestParam(value = "files") MultipartFile[] files,Long uId) throws IOException {
        int maxCount = files.length;
        for (int i = 0; i < maxCount; i ++) {
            this.fileService.upload(files[i]);
        }
    }

单文件下载

    @ApiOperation(value = "下载接口")
    @ApiImplicitParam(name = "downloadFilePath", value = "文件地址", paramType = "query", required = true)
    @GetMapping("/download")
    public void download(HttpServletResponse response, @RequestParam String downloadFilePath) {
        this.fileService.download(response, downloadFilePath);
    }   
    @Override
    public void download(HttpServletResponse response, String downloadFilePath) {
        String[] arr = downloadFilePath.split("\\.");
        String fileName = arr[arr.length - 2] + "." + arr[arr.length - 1];//被下载文件的名称
        File file = new File(downloadFilePath);
        if (file.exists()) {
            response.setContentType("application/force-download");// 设置强制下载不打开            
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream outputStream = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    outputStream.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

图片文件直接响应到页面(使用过滤器)

@SpringBootApplication
@ServletComponentScan
public class CarpBusinessApplication {

    public static void main(String[] args) {
        SpringApplication.run(CarpBusinessApplication.class, args);
    }
}
/**
 * @Description: TODO
 * @Author yjw
 * @Date 2020/4/2
 **/
@WebFilter(filterName = "ImageFilter", urlPatterns = "/a/q/upload/download/*")
public class ImageFilter implements Filter {

    @Autowired
    FileService fileService;

    private static final List<String> IMAGE_TYPE_LIST = Arrays.asList("bmp","jpg","png",
            "tif","gif","pcx","tga","exif","fpx","svg","psd","cdr",
            "pcd","dxf","ufo","eps","ai","raw","WMF","webp","pdf");

    @Value("${upload.netPath}")
    private String netPath;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String Uri = ((HttpServletRequest) request).getRequestURI();
        String[] arr = Uri.split("/");
        String fileName = arr[arr.length - 1];

        String[] nameArr = fileName.split("\\.");
        if(IMAGE_TYPE_LIST.contains(nameArr[nameArr.length - 1])) {
            fileService.downloadImage((HttpServletResponse) response, fileName);
        } else {
            chain.doFilter(request, response);
        }
    }
}

@WebFilter注解中不包括Component注解,所以需要在主类上加@ServletComponentScan注解。

这里过滤器中的逻辑是如果是图片那么我就把图片直接响应回去,如果是其他的文件,那么就取消过滤这个请求,让他进入相应的Controller

需要注意的是,过滤器过滤的是http://ip地址:端口/项目名 后面的东西,而不包括项目名,这里一定要注意。

    @Override
    public void downloadImage(HttpServletResponse response, String fileName) {
        File file = new File(localPath + "\\image\\" + fileName);
        if (file.exists()) {
            try {
                FileCopyUtils.copy(new FileInputStream(file), response.getOutputStream());

                response.setContentType("image/jpg");
                return;
            } catch (IOException e) {
                throw new BaseException(Constant.BUSINESS, ResultEnum.IMAGE_CANNOT_FOUND);
            }
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值