Secure File Upload, Download, and Preview with MinIO and SpringBoot

This article demonstrates how to securely implement file upload, download, and preview in a SpringBoot application using MinIO, token validation, and base64‑encoded URLs, while also providing complete code snippets and practical usage notes for backend developers.

Top Architect
Top Architect
Top Architect
Secure File Upload, Download, and Preview with MinIO and SpringBoot

Preface

The previous article exposed the MinIO address when previewing files; this guide improves security by using file streams, token validation, and base64‑encoded URLs.

1. File Upload

Upload service implementation:

public void uploadFile(MultipartFile file) throws Exception {
    String fileName = System.currentTimeMillis() + "-" + file.getOriginalFilename();
    PutObjectArgs args = PutObjectArgs.builder()
        .bucket(minioConfig.getBucketName())
        .object(fileName)
        .stream(file.getInputStream(), file.getSize(), -1)
        .contentType(file.getContentType())
        .build();
    client.putObject(args);
}

Upload controller:

@PostMapping("upload")
public RestResult<SysFile> upload(MultipartFile file) {
    try {
        sysFileService.uploadFile(file);
    } catch (Exception e) {
        log.error("上传文件失败", e);
        return RestResult.fail(e.getMessage());
    }
}

2. File Download

Download service implementation:

public void download(String filename, HttpServletResponse response) throws ServiceException {
    try {
        InputStream inputStream = client.getObject(GetObjectArgs.builder()
            .bucket(minioConfig.getBucketName())
            .object(filename)
            .build());
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        OutputStream outputStream = response.getOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        inputStream.close();
        outputStream.close();
    } catch (Exception e) {
        log.error("文件下载失败:" + e.getMessage());
        throw new ServiceException("文件下载失败");
    }
}

Download controller (token validation required):

@ApiOperation("文件下载")
@GetMapping("/download/{token}/{filename}")
public void getDownload(@PathVariable("token") String token,
                        @PathVariable("filename") String filename,
                        HttpServletResponse response) {
    tokenUtils.validateToken(token);
    sysFileService.download(filename, response);
}

Key notes:

The @GetMapping("/download/{token}/{filename}") path must place filename last.

Token validation should be performed in an interceptor; the endpoint must be whitelisted for kkfile preview requests.

3. File Preview URL Generation

Service that creates a preview URL (token is appended but not validated here):

public String getPreviewUrl(String filename) throws UnsupportedEncodingException {
    ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = sra.getRequest();
    if (request == null || StringUtils.isBlank(request.getHeader(TokenConstants.AUTHENTICATION))) {
        throw new ServiceException("未获取到有效token");
    }
    String previewUrl = filePreviewUrl + FileUploadUtils.base64UrlEncode(fileDownloadUrl + "/" + token + "/" + filename);
    return previewUrl + "&fullfilename=" + URLEncoder.encode(filename, "UTF-8");
}

Utility for base64 URL encoding:

public static String base64UrlEncode(String url) throws UnsupportedEncodingException {
    String base64Url = Base64.getEncoder().encodeToString(url.getBytes(StandardCharsets.UTF_8));
    return URLEncoder.encode(base64Url, "UTF-8");
}

Controller to obtain the preview URL:

@GetMapping("/getPreviewUrl")
public RestResult<String> getPreviewUrl(String filename) throws UnsupportedEncodingException {
    return RestResult.ok(sysFileService.getPreviewUrl(filename));
}

Test Scenario

Assumptions:

File service address: http://file-server kkfile service address: http://kkfile-server File name: xxxx.docx Resulting preview URL example:

http://kkfile-server/onlinePreview?url=aHR0cDovLzE3Mi4xNi41MC4y....&fullfilename=xxxx.docx

The aHR0cDovLzE3Mi4xNi41MC4y.... part is produced by:

FileUploadUtils.base64UrlEncode("http://file-server" + "/" + token + "/" + filename);
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

FileDownloadFileUploadTokenAuthentication
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.