应用程序中免不了要上传下载文件,实现方式由简单到复杂有很多种:

  1. 最简单的,文件上传后服务端程序将文件写到服务器上一个指定的目录
  2. 稍微复杂一点,我们需要和应用服务器分开的单独文件服务器
  3. 再复杂一点,需要用到分布式文件存储。文件在多个文件服务器之间做冗余备份

使用单独文件服务器

各种方案没有好坏之分,要根据系统场景看是否适用。
第一种方式非常简单,适用于一些访问量小,存储文件不多的应用程序。
多数应用系统其实第二种方案就可以了。
很复杂的采用第三种。

选择独立文件服务要求

  • 有基本的权限控制。不做控制的话,一个爬虫就连锅端了。
  • 使用单独文件服务器。上传下载的压力由文件服务器承担
  • API支持,方便Java程序进行文件存储

Filebrowser + OkHttp 方案

不用自己造轮子。Filebrowser + OkHttp是一个不错的方案。

  • Filebrowser满足上面文件服务的所有要求。Filebrower提供了基于Http的接口让客户端上传下载文件。
  • Java发送Http请求有很多可选方案。JDK自带的库,apache 的 http component, 以及OkHttp开源库。相比之下 OkHttp比较好,主要是API封装得不错,简单易懂,功能全面,效率也不错。实际上在Android程序中OkHttp得到了广泛使用。发送Http请求的任务就靠他了。

实施

Filebrowser安装

按照 Filebrowser的官方安装文档进行安装。

安装完成之后,在浏览器中打开UI, 确认安装正确

分流服务器java代码实现 java分布式文件服务器_分流服务器java代码实现

写文件服务器工具

此工具的作用是把controller收到的multipart file存储到文件服务器上去。

文件存储助手代码

/**
     * 文件上传
     * @param bytes 文件数据
     * @param storedFileName 文件存储名称
     * @return 上传是否成功
     * @throws IOException
     */
    public boolean upload(byte[] bytes, String storedFileName) throws IOException {
        OkHttpClient httpClient = new OkHttpClient();
        MediaType mediaType = MediaType.Companion.parse("application/octet-stream");
        RequestBody requestBody = RequestBody.Companion.create(bytes, mediaType);
        Request request = new Request.Builder()
                .url(fileServerUrl + "/api/resource/" + storedFileName)
                .post(requestBody)
                .build();
        try(Response response = httpClient.newCall(request).execute()){
            return response.isSuccessful();
        }
    }

Controller代码

@PostMapping("/upload/boardImg")
    public ApiResp uploadBoardImg(MultipartFile file) throws IOException {
        String storedFileName = FOLDER_NAME_BOARD + SEPARATOR + FileUtils.genUniqueName(file.getOriginalFilename());
        if(fileStorageClient.upload(file.getBytes(), storedFileName)){
            return ApiResp.ok(storedFileName);
        } else {
            return ApiResp.failed("图片上传失败");
        }
    }

这样文件就通过应用服务器上传到单独的文件服务器去了。

查看文件

每个上传的文件在文件服务器上都有一个相对路径。应用系统中只需要存相对路径即可。查看的时候把文件服务器下载API地址和相对路径拼接起来就可以拿到文件了。具体形式为:
http://文件服务器IP/api/download/ + 相对路径

至此,拥有单独文件服务器的文件上传下载就实现了。

Next

下一篇文章,我将介绍如何进一步做权限控制。