Springboot реализует загрузку файла, и файл повреждается после загрузки

Spring Boot

описание сцены

Используя Springboot для реализации функции загрузки файла, код выглядит следующим образом

String fileName = "template.xls";
res.setHeader("Content-disposition", "attachment;fileName=" + fileName);
res.setContentType("application/vnd.ms-excel;charset=UTF-8");
res.setCharacterEncoding("UTF-8");
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "excelTemplate/template.xls");
FileInputStream input = new FileInputStream(file);
OutputStream out = res.getOutputStream();
byte[] b = new byte[2048];
int len;
while ((len = input.read(b)) != -1) {
    out.write(b, 0, len);
}
input.close();

Загрузите файл, который находится под ресурсами, и используйте IDEA, чтобы начать отладку при локальном тестировании, можно успешно загрузить файл на локальный и открыть обычный файл.

сообщение об ошибке

После завершения локальной отладки проект упаковывается в пакет jar, а затем развертывается на сервере для запуска.В это время снова перейдите по ссылке для скачивания и получите поврежденный файл размером 0 КБ, проверьте журнал приложений сервера и получите следующее сообщение об ошибке; Template.xls не может быть преобразован в абсолютный путь к файлу, поскольку он не находится в файловой системе.

причина

После запроса данных я обнаружил, что проблема возникла в методе ResourceUtils.getFile(), я пришел к исходному коду этого метода и нашел место, где было напечатано вышеуказанное сообщение об ошибке.

if (!"file".equals(resourceUrl.getProtocol())) {
    throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not reside in the file system: " + resourceUrl);
}

Видно, что если протокол текущего файла не файлового типа, то возникнет эта ошибка. В среде отладки файл существует в виде файла, поэтому к нему можно получить доступ с помощью ResourceUtils.getFile(), но в виде jar-пакета после упаковки форма файла больше не существует, а может только читаться в потоке.

Решение

ClassPathResource classPathResource = new ClassPathResource("excelTemplate/template.xls");
InputStream input = classPathResource.getInputStream();

Просто прочитайте метод ResourceUtils.getFile() и измените его для чтения из ClassPathResource. Обратите внимание, что URL-адрес здесь не должен иметь префикс classpath:.

Если есть ошибка, укажите на нее