Как обслуживать загруженные файлы в Play!2 с помощью Scala?

Я пытаюсь разрешить пользователям загружать фотографии на сервер, а затем просматривать их. Загрузка происходит так, как описано в этом руководстве. Вот код:

def upload = Action(parse.multipartFormData) { request =>
  request.body.file("picture").map { picture =>
    import java.io.File
    val filename = picture.filename 
    val contentType = picture.contentType
    picture.ref.moveTo(new File("/tmp/picture"))
    Ok("File uploaded")
  }.getOrElse {
    Redirect(routes.Application.index).flashing(
      "error" -> "Missing file"
    )
  }
}

Мне непонятно, как вернуть загруженные изображения пользователям, которые хотят их увидеть. Прямо сейчас я размещаю сервер на своей машине, поэтому фрагмент кода из руководства записывает файлы на мой диск D:, который недоступен (и не должен быть) доступен из Интернета. Насколько я вижу есть 2 варианта:

  1. Храните фотографии в папке /public в моем проекте (тот, который посвящен ресурсам). См. здесь: http://www.playframework.org/documentation/2.0/Assets.

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

Для 1 я не уверен, что это цель активов. Для 2 я понятия не имею, как написать такой контроллер.


person Henry Henrinson    schedule 12.07.2012    source источник


Ответы (3)


2.0.3 будет содержать внешний контроллер активов, который может быть (неправильно) используется для этого. Однако написать такой контроллер не волшебство, у вас есть предопределенная папка, в которой сохраняются все ваши загрузки, и оттуда вы их читаете. В базе данных вы сохраняете (уникальное) имя файла.

Другой подход заключается в сохранении загруженных файлов в базе данных. Мы делаем это с помощью GridFS в MongoDB. Пользовательский контроллер возвращает их пользователю. Таким образом, ваши данные хранятся в одном центральном месте, что также упрощает резервное копирование и восстановление.

person Marius Soutier    schedule 12.07.2012
comment
Интересный. Однако я понимаю, что хранение файлов прямо в базе данных может быть плохой практикой, после этого вопроса: stackoverflow.com/questions/11416735/ - person Henry Henrinson; 12.07.2012
comment
Как всегда, это зависит. GridFS специально создана для такого рода задач, как и Amazon S3. Если вы храните свои файлы в локальной файловой системе, у вас возникнут большие проблемы, когда вам однажды понадобится второй сервер. Взгляните на контроллер активов, это не так сложно понять. - person Marius Soutier; 12.07.2012
comment
Вы также можете использовать NAS для совместного использования хранилища между серверами и монтировать его в нужных местах. Вы также можете загрузить свои файлы в CDN и позволить ему обслуживать ваши файлы. Думаю, использование MongoDB только для хранения файлов — не лучший выбор. - person kheraud; 12.07.2012
comment
Да, я не это имел в виду :) Мы используем MongoDB, поэтому GridFS кажется естественным выбором. Пока работает хорошо. - person Marius Soutier; 13.07.2012
comment
Использование контроллера ExternalAssets рекомендуется только в режиме разработки, этот контроллер отключен в режиме Prod, для простоты предпочтительнее ответ @jozic с добавлением параметра inline = true, если вы знаете (и хотите), чтобы файл отображался с помощью браузер. - person Sparko; 08.03.2014
comment
Часть внешних активов устарела. Вы же знаете, что раньше у нас ничего не было... ;) - person Marius Soutier; 05.01.2016

Простой пример

def index = Action {
  Ok.sendFile(new java.io.File("/tmp/fileToServe.pdf"))
}

есть раздел «Обслуживание файлов» по ​​адресу https://www.playframework.com/documentation/2.4.x/ScalaStream#Serving-files, в котором объясняется, как обслуживать файлы

person Eugene Platonov    schedule 10.08.2012
comment
Я бы предпочел это решение, а не контроллер ExternalAssets, поскольку он отключен в режиме разработки. - person Remi Mélisson; 17.09.2014
comment
Вопрос был не в том, как обслуживать файлы, а в том, как обслуживать загруженные файлы и можно ли загружать их в папку ресурсов. - person Marius Soutier; 05.01.2016

Вы можете добавить новый маршрут следующим образом:

GET     /myFiles/*file               controllers.Assets.at(path="/tmp", file)
person Peanut    schedule 29.01.2013
comment
Я не ожидаю, что это сработает: в процессе сборки содержимое общей папки обрабатывается и добавляется в путь к классам приложения. - person stewSquared; 28.11.2014
comment
Содержимое папки PUBLIC... Прочтите остальную часть документации. Он должен работать правильно. -› playframework.com/documentation/2.0/Assets - person Peanut; 28.11.2014