Загрузка и обслуживание образов Spring Boot

Я создаю новое приложение Spring Boot и хочу иметь возможность хранить и обслуживать изображения, я хочу, чтобы изображения хранились в каталоге приложений:
 введите описание изображения здесь

вот как сейчас выглядит загрузка:

@PostMapping("/")
@ResponseBody
public String upload(@RequestPart String title, @RequestPart MultipartFile img) throws IOException{
    String imgName = img.getOriginalFilename();
    Post p = new Post();
    p.setTitle(title);
    p.setImageName(imgName);
    postService.add(p);
    File upl = new File("images/" + imgName);
    upl.createNewFile();
    FileOutputStream fout = new FileOutputStream(upl);
    fout.write(img.getBytes());
    fout.close();
    return "ok";
}

вот как я хочу получать изображения

<img th:src="@{'images/' + ${post.imageName}}"/>

сейчас я получаю 404, и когда я хочу просмотреть некоторые изображения в каталоге, я получаю

Fatal error reading PNG image file: Not a PNG file

как мне это сделать, чтобы он работал?


person Weras Adve    schedule 12.08.2017    source источник


Ответы (3)


По умолчанию ваше приложение Spring Boot обслуживает static content - в вашем случае изображения - находятся в следующих местах:

  • / static
  • / public
  • /Ресурсы
  • / META-INF / ресурсы

Поэтому обычно static/images/, возможно, будет тем местом, где Thymeleaf должен ожидать статические изображения, которые должны быть доставлены для рендеринга. Но поскольку это место посвящено статическому контенту и, как правило, сохранять загруженный (динамический) контент внутри вашего приложения - плохая идея, я бы рекомендовал НЕ делать этого . Задумывались ли вы о том, что произойдет, если ваше приложение будет повторно развернуто или перенесено на другую машину? Вам придется делать резервную копию / перемещать изображения громоздким способом. Существуют лучшие решения: хранение загружаемого содержимого в отдельном месте за пределами вашего приложения (которое, например, может быть настраиваемым, а также повторно использоваться несколькими экземплярами) или даже использовать базу данных для хранения данных изображения. Это также позволит обрабатывать изображения в транзакционном контексте (например, изоляция и откаты).

Но если вы теперь хотите сохранить его в своем приложении, вы можете расширить местоположения, добавив места для поиска (фактически статический контент). Хотя ответ Ajit и даже документация по-прежнему дают совет по расширению вашего собственного WebMvcConfigurerAdapter, я лично предпочел бы реализовать WebMvcConfigurer вместо этого, потому что первое устарело.

В этом случае это должно выглядеть так:

@Configuration
public class AdditionalResourceWebConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:images/");
    }
}
person Kevin Peters    schedule 12.08.2017

Чтобы получить доступ к изображению с вашего images folder,

введите описание изображения здесь

Вам нужно переопределить addResourceHandlers метод класса WebMvcConfigurerAdapter следующим образом:

@Configuration
public class ResourceConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:images/");
    }
}

После этого вам нужно добавить / перед изображениями в URL-адресе, например:

<img th:src="@{'/images/' + ${post.imageName}}"/>
person Ajit Soman    schedule 12.08.2017
comment
Спасибо за ответ - person Weras Adve; 13.08.2017

Вы можете хранить внешние файлы в папке с именем /static в том же каталоге, что и ваша jar, и Spring по умолчанию их просканирует. Итак, если у вас есть static/images/, вы можете ссылаться на свои изображения с помощью:

<img th:src="@{/images/img.ext}"/>

Итак, вы хотели бы использовать new File("/static/images/" + imgName);

person Scott    schedule 08.05.2018