X File Storage версия: v2.2.1
Spring Boot версия: bk.2.7.2
Solon версия:
JVM версия:
openjdk версия "1.8.0_412"
OpenJDK Runtime Environment (Zulu 8.78.0.19-CA-macos-aarch64) (build 1.8.0_412-b08)
OpenJDK 64-Bit Server VM (Zulu 8.78.0.19-CA-macos-aarch64) (build 25.412-b08, mixed mode)
Другие зависимости с названием и версией:
# Введите конфигурационные файлы здесь
server:
port: 8030
spring:
profiles:
active: xu-dev
datasource:
url: jdbc:mysql://127.0.0.1:3306/x-file-storage-test?characterEncoding=UTF-8&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: mysql@G2ZH
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
multipart:
resolve-lazily: true # ленивая загрузка многопоточных запросов
``````yaml
x-file-storage: # Настройка хранения файлов, если не используется, можно пропустить
default-platform: local-plus-1 # По умолчанию используемый платформенный идентификатор
thumbnail-suffix: ".min.jpg" # Расширение миниатюр, например ["min.jpg", "png"]
# local: # Локальное хранилище (не рекомендуется использовать)
# - platform: local-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# enable-access: true # Активировать доступ (в продакшн лучше использовать конфигурацию Nginx, более эффективно)
# domain: "" # Домен для доступа, например: "http://127.0.0.1:8030/test/file/", обратите внимание, что он должен совпадать с path-patterns, заканчивается слешом "/", локальному хранилищу рекомендуется использовать относительные пути, чтобы было удобнее менять домены в будущем
# base-path: /Users/gaogzhen/logs/x-file-storage/ # Базовый путь для хранения
# path-patterns: /test/file/** # Путь для доступа, если активирован enable-access, то через этот путь можно получить доступ к загруженным файлам
local-plus: # Улучшенное локальное хранилище
- platform: local-plus-1 # Идентификатор платформенного хранилища
enable-storage: true # Активировать хранение
enable-access: true # Активировать доступ (в продакшн лучше использовать конфигурацию Nginx, более эффективно)
domain: http://127.0.0.1:8030/file/ # Домен для доступа, пример: "http://127.0.0.1:8030/file/", обратите внимание, что он должен совпадать с path-patterns, заканчивается слешом "/", локальному хранилищу рекомендуется использовать относительные пути, чтобы было удобнее менять домены в будущем
base-path: local-plus/ # Базовый путь
path-patterns: /file/** # Путь для доступа
storage-path: /Users/gaogzhen/logs/x-file-storage/ # Путь для хранения
# huawei-obs: # Huawei Cloud OBS, если не используется, можно пропустить
# - platform: huawei-obs-1 # Идентификатор платформенного хранилища
# enable-storage: false # Активировать хранение
# access-key: ??
# secret-key: ??
# end-point: ??
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: http://abc.obs.com/
# base-path: hy/ # Базовый путь
# aliyun-oss: # Alibaba Cloud OSS, если не используется, можно пропустить
# - platform: aliyun-oss-1 # Идентификатор платформенного хранилища
# enable-storage: false # Активировать хранение
# access-key: ??
# secret-key: ??
# end-point: ??
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://abc.oss-cn-shanghai.aliyuncs.com/
# base-path: hy/ # Базовый путь
# qiniu-kodo: # Qiniu Cloud KODO, если не используется, можно пропустить
# - platform: qiniu-kodo-1 # Идентификатор платформенного хранилища
# enable-storage: false # Активировать хранение
# access-key: ??
# secret-key: ??
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: http://abc.hn-bkt.clouddn.com/
# base-path: base/ # Базовый путь
# tencent-cos: # Tencent Cloud COS
# - platform: tencent-cos-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# secret-id: ??
# secret-key: ??
# region: ?? # Регион расположения бакета
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://abc.cos.ap-nanjing.myqcloud.com/
# base-path: hy/ # Базовый путь
# baidu-bos: # Baidu Cloud BOS
# - platform: baidu-bos-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# access-key: ??
# secret-key: ??
# end-point: ?? # Пример abc.fsh.bcebos.com
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://abc.fsh.bcebos.com/abc/
# base-path: hy/ # Базовый путь
# upyun-uss: # UpYun Cloud USS
# - platform: upyun-uss-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# username: ??
# password: ??
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: http://abc.test.upcdn.net/
# base-path: hy/ # Базовый путь
# minio: # MinIO, поскольку MinIO SDK поддерживает Amazon S3, все другие хранилища, совместимые с протоколом Amazon S3, также могут быть настроены здесь
# - platform: minio-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# access-key: ??
# secret-key: ??
# end-point: ??
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: http://minio.abc.com/abc/
# base-path: hy/ # Базовый путь
# amazon-s3: # Amazon S3, все другие хранилища, совместимые с протоколом Amazon S3, также могут быть настроены здесь
# - platform: amazon-s3-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# access-key: ??
# secret-key: ??
# region: ?? # Следует заполнить хотя бы один из этих параметров
# end-point: ?? # Следует заполнить хотя бы один из этих параметров
# bucket-name: ??
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://abc.hn-bkt.clouddn.com/
# base-path: s3/ # Базовый путь
# ftp: # FTP
# - platform: ftp-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# host: ?? # Хост, пример: 192.168.1.105
# port: 21 # Порт, по умолчанию 21
# user: anonymous # Имя пользователя, по умолчанию anonymous (анонимный)
# password: "" # Пароль, по умолчанию пустой
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: ftp://192.168.1.105/
# base-path: ftp/ # Базовый путь
# storage-path: / # Путь для хранения, все загружаемые файлы будут сохранены в этом пути, по умолчанию "/", обратите внимание, что он должен заканчиваться слешом "/"
# sftp: # SFTP
# - platform: sftp-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# host: ?? # Хост, пример: 192.168.1.105
# port: 22 # Порт, по умолчанию 22
# user: root # Имя пользователя
# password: ?? # Пароль или пароль для приватного ключа
# private-key-path: ?? # Путь до приватного ключа, совместимый с Spring ClassPath, файловым путем, HTTP-путем и т.д., пример: classpath:id_rsa_2048
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://file.abc.com/
# base-path: sftp/ # Базовый путь
# storage-path: /www/wwwroot/file.abc.com/ # Путь для хранения, обратите внимание, что он должен заканчиваться слешом "/"
# webdav: # WebDAV
# - platform: webdav-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# server: ?? # Адрес сервера, пример: http://192.168.1.105:8405/
# user: ?? # Имя пользователя
# password: ?? # Пароль
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://file.abc.com/
# base-path: webdav/ # Базовый путь
# storage-path: / # Путь для хранения, все загружаемые файлы будут сохранены в этом пути, по умолчанию "/", обратите внимание, что он должен заканчиваться слешом "/"
# google-cloud-storage: # Google Cloud Storage
# - platform: google-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# project-id: ?? # Проект ID
# bucket-name: ??
# credentials-path: file:/deploy/example-key.json # Путь до файла с учетными данными JSON, совместимый с Spring ClassPath, файловым путем, HTTP-путем и т.д.
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://storage.googleapis.com/test-bucket/
# base-path: hy/ # Базовый путь
# fastdfs:
# - platform: fastdfs-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# run-mod: COVER # Режим выполнения
# tracker-server: # Конфигурация сервера Tracker
# server-addr: ?? # Адрес сервера Tracker (IP:PORT), несколько адресов разделены запятой
# http-port: 80 # По умолчанию: 80
# extra: # Дополнительные настройки
# group-name: group2 # Название группы, может быть пустым
# http-secret-key: FastDFS1234567890 # Секретный ключ безопасности, по умолчанию: FastDFS1234567890
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", пример: https://file.abc.com/
# base-path: hy/ # Базовый путь
# azure-blob:
# - platform: azure-blob-1 # Идентификатор платформенного хранилища
# enable-storage: true # Активировать хранение
# connection-string: ?? # Строка подключения, Azure Blob Console - Безопасность и сеть - Ключ доступа - Строка подключения
# end-point: ?? # Эндпоинт Azure Blob Console - Настройки - Эндпоинты - Основной эндпоинт - Blob службы
# container-name: ?? # Имя контейнера, аналогично s3 bucketName, Azure Blob Console - Данные - Контейнеры
# domain: ?? # Домен для доступа, обратите внимание, что он должен заканчиваться слешом "/", должен совпадать с end-point
# base-path: hy/ # Базовый путь
```### Код воспроизведения ошибки
```java
/**
* Загрузка изображения, успешная загрузка возвращает информацию о файле
* Обработка изображений осуществляется с помощью https://github.com/coobird/thumbnailator
*/
@PostMapping("/upload-image")
public FileInfo uploadImage(@RequestParam("file") MultipartFile file) {
return fileStorageService
.of(file)
.image(img -> img.size(1000, 1000)) // Изменяет размер изображения до 1000x1000
.thumbnail(th -> th.size(200, 200)) // Генерирует миниатюру размером 200x200
.upload();
}
Успешная загрузка и генерация миниатюры
2025-01-15 11:00:10.136 ERROR 68888 --- [nio-8030-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() для сервлета [dispatcherServlet] в контексте с путем [] вызвало исключение [Обработка запроса завершилась ошибкой; вложенные исключения есть org.dromara.x.file.storage.core.exception.FileStorageRuntimeException: Обработка изображения завершилась ошибкой!] с корневой причиной net.coobird.thumbnailator.tasks.UnsupportedFormatException: Для исходных данных не найдено подходящее ImageReader.
at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source) ~[thumbnailator-0.4.20.jar:0.4.20]
at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source) ~[thumbnailator-0.4.20.jar:0.4.20]
at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source) ~[thumbnailator-0.4.20.jar:0.4.20]
at net.coobird.thumbnailator.Thumbnails$Builder.toOutputStream(Unknown Source) ~[thumbnailator-0.4.20.jar:0.4.20]
at org.dromara.x.file.storage.core.UploadPretreatment.image(UploadPretreatment.java:556) ~[classes/:na]
at org.dromara.x.file.storage.core.upload.UploadPretreatment.image(UploadPretreatment.java:688) ~[classes/:na]
at org.dromara.x.file.storage.test.controller.FileDetailController.uploadImage(FileDetailController.java:48) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_362]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_362]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_362]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_362]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1070) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.22.jar:5.3.22]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.22.jar:5.3.22]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.22.jar:5.3.22]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.65.jar:9.0.65]
at java.lang.Thread.run(Thread.java:750) [na:1.8.0_362]
[Здесь можно загрузить изображение]
Вход Перед тем как оставить комментарий