jeecgboot/JeecgBoot · error · NullPointerException

The file name can not null

Error message

The file name can not null

What it means

In downloadFile, after the file-exists check, if the fileName parameter is null or empty the method throws NullPointerException('The file name can not null'). The fileName is used to set the Content-Disposition header (URL-encoded). A null/empty name would break the header, so the guard rejects it early. Like error 18 it uses NPE for a validation condition rather than IllegalArgumentException.

Source

Thrown at jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/FileDownloadUtils.java:50

public class FileDownloadUtils {

    /**
     * 单文件下载
     *
     * @param response
     * @param storePath 下载文件储存地址
     * @param fileName  文件名称
     * @author: chenrui
     * @date: 2019/5/24 17:10
     */
    public static void downloadFile(HttpServletResponse response, String storePath, String fileName) {
        response.setCharacterEncoding("UTF-8");
        File file = new File(storePath);
        if (!file.exists()) {
            throw new NullPointerException("Specified file not found");
        }
        if (fileName == null || fileName.isEmpty()) {
            throw new NullPointerException("The file name can not null");
        }
        // 配置文件下载
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        // 下载文件能正常显示中文
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        // 实现文件下载
        byte[] buffer = new byte[1024];
        try (FileInputStream fis = new FileInputStream(file);
             BufferedInputStream bis = new BufferedInputStream(fis);) {
            OutputStream os = response.getOutputStream();
            int i = bis.read(buffer);
            while (i != -1) {

View on GitHub (pinned to 96fb33f5ec)

Solutions

  1. Always pass a non-empty fileName to downloadFile; default to the file's actual name if unknown.
  2. In the controller, validate fileName is non-null/non-empty and derive it from the File if missing.
  3. Ensure the DB record storing the display name is populated on upload.

Example fix

// before — fileName omitted/nullable
downloadFile(response, storePath, record.getFileName()); // null -> throws

// after — default to the physical file name
String name = StringUtils.hasText(record.getFileName())
  ? record.getFileName()
  : new File(storePath).getName();
downloadFile(response, storePath, name);
Defensive patterns

Strategy: validation

Validate before calling

// Guarantee a non-empty fileName before downloading
String name = (fileName == null || fileName.isBlank())
  ? new File(storePath).getName()
  : fileName;
FileDownloadUtils.downloadFile(response, storePath, name);

Type guard

public static boolean hasValidFileName(String fileName) {
  return fileName != null && !fileName.trim().isEmpty();
}

Try / catch

try {
  FileDownloadUtils.downloadFile(response, storePath, fileName);
} catch (NullPointerException e) {
  if (e.getMessage().contains("file name")) {
    response.sendError(400, "File name required");
  }
}

Prevention

When it happens

Trigger: A download request where the display fileName is not supplied — e.g. the caller passes only storePath and omits fileName, or the DB record's fileName field is null/blank, or a frontend download link omits the name query param.

Common situations: Download endpoint called with only a path param and no name param; DB record missing the original filename column value; a refactor that drops the fileName argument from the call site.

Related errors


AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14). Data as JSON: /api/errors/29f0f3f3aabed386. Report an issue: GitHub.