Почему метод возврата изображения-src вместо URL/маршрута для контроллера модуля Play Framework?

Я создал модуль Play Framework «Ean2BarcodePlayModule», который включает этот шаблон «barcode.scala.html», сохраненный в пакете «views.barcodePackage.tags»:

@(ean: Long)
<img class="barcode" alt="@ean" src="@controllers.barcodePackage.BarcodeController.getBarcode(ean)" />

После использования «Activator publish-local» я сослался на это в шаблоне «index.scala.html» тестового проекта:

@(message: String)

@main("Welcome to Play") {

    @barcodePackage.tags.barcode(5010255079763L)

}

Ожидаемый результат

<!-- Redacted for brevity -->
  <img class="barcode" alt="5010255079763" src="/barcodeRoutes/5010255079763">
<!-- Redacted for brevity -->

Но фактический результат таков:

<!-- Redacted for brevity -->
  <img class="barcode" alt="5010255079763" src="Action(parser=BodyParser(anyContent))">
<!-- Redacted for brevity -->

Как будет отмечено, возвращаемый тип метода метода действия контроллера появляется там, где должен быть исходный URL-адрес, но я не понимаю, почему это происходит, и не знаю, как это исправить.

Модуль включает эту строку в «barcodePackage.routes»:

GET     /:ean   controllers.barcodePackage.BarcodeController.getBarcode(ean:Long)

Между тем файл маршрута в тестовом проекте содержит:

->      /barcodeRoutes              barcodePackage.Routes

Это код контроллера модуля:

package controllers.barcodePackage


import models.barcodePackage.Barcode
import play.api.mvc.{Action, Controller}
import play.api.libs.concurrent.Execution.Implicits._
import scala.util.{Failure, Success}

/**
 * Created by Brian_Kessler on 3/11/2015.
 */
object BarcodeController extends Controller
{
  def getBarcode(ean:Long) = Action.async{
      Barcode.renderImage(ean) map {
        case Success(imageData) => Ok(imageData).as(Barcode.mimeType)
        case Failure(error)     => BadRequest("Couldn't generate bar code. Error: " + error.getMessage)
    }
  }

}

Примечания:

  1. Самое главное, я хотел бы, чтобы функциональность модуля работала должным образом.

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


person Brian Kessler    schedule 12.03.2015    source источник


Ответы (2)


Благодаря Сарвешу Кумару Сингху, чей ответ помог мне встать на правильный путь, я понял это.

Итак, как я понял, проблема была не в том, что шаблон не находил контроллер, а в том, что он вызывал метод в контроллере вместо обратного маршрутизатора для контроллера.

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

В моей нынешней версии игры это означало изменение barcode.scala.html на:

@(ean: Long)
<img class="barcode" alt="@ean" src="@controllers.barcodePackage.routes.BarcodeController.getBarcode(ean:Long)" />

Обратите внимание, что источник НЕ начинается с «@routes», а скорее «routes» стоит между именем пакета («barcodePackage») и именем контроллера («BarcodeController»).

person Brian Kessler    schedule 13.03.2015

Это потому, что вы вызываете эту функцию, говоря @controllers.net.nowhereatall.playforscala.barcodes.barcode(ean), когда шаблон отображается в игре.

Теперь, когда вы уже указали маршрут и привязали его к своей функции controllers.net.nowhereatall.playforscala.barcodes.barcode(ean).

Измените имя файла barcode.routes на barcodes.routes

Теперь, предполагая, что вы хотите интегрировать файл barcodes.routes вашего подпроекта в основной проект следующим образом:

->  /barcodes barcodes.routes

Итак... теперь вам нужно будет изменить несколько вещей.

  1. Переместите свои контроллеры в подпроект barcodes в пакете controllers.barcodes.
  2. Вы должны использовать Barcodes, а не barcodes для имени объекта (условия Scala).

Таким образом, ваш контроллер controllers.net.nowhereatall.playforscala.barcodes в идеале должен быть здесь - controllers.barcodes.Barcodes. But you can place it here -controllers.barcodes.net.nowhereatall.playforscala.Barcodesif you want, just add the part.net.nowhereatall.playforscala` везде в следующем коде.

Теперь измените маршрут в своем barcodes.routes,

GET     /:ean                          controllers.barcodes.Barcodes.barcode(ean:Long)

Теперь вам нужно указать этот маршрут в шаблоне закручивания с помощью обратного маршрутизатора.

@(ean: Long)
<img class="barcode" alt="@ean" src="@controllers.barcodes.routes.Barcodes.barcode(ean)" />

Теперь, когда @barcodes.tags.barcode(5010255079763L) воспроизводит шаблон повторно, этот вызов controllers.barcodes.routes.Barcode(ean) будет оцениваться обратным маршрутизатором как /barcodes/5010255079763 (поскольку вы привязали маршрут controllers.barcodes.Barcode(ean) к /).

следовательно, то, что вы получите в браузере,

<img class="barcode" alt="5010255079763" src="/barcodes/5010255079763" />

Вы даже можете заставить его работать, жестко запрограммировав маршрут, как указано ниже,

@(ean: Long)
<img class="barcode" alt="@ean" src="/barcodes/@ean" />
person sarveshseri    schedule 12.03.2015
comment
Спасибо за длинный ответ! К сожалению, мой тестовый проект не скомпилируется из-за проблемы с его файлом маршрутов, возможно, из-за того, что я решил включить его в имя своего пакета. Завтра я еще поиграю с этим, чтобы посмотреть, поможет ли удаление этого работать, как описано выше, хотя я хотел бы иметь возможность включить это ради отдельного пространства имен. - person Brian Kessler; 12.03.2015
comment
Файл маршрутов больше не вызывает проблем, но (1) я вернулся к получению ‹img class=barcode alt=5010255079763 src=Action(parser=BodyParser(anyContent))› и (2) я понял, что ваше решение кажется удалить использование файла маршрутов модуля из уравнения (т. е. если бы я хотел включить несколько элементов управления в модуль штрих-кода, все они должны быть транскрибированы в тестовый проект. - person Brian Kessler; 13.03.2015
comment
Ну... он использует файл маршрута вашего подпроекта, добавляя его в файл маршрута вашего основного проекта -> /barcodes barcodes.routes. Если у вас есть несколько маршрутов /route1, /route2 в вашем файле маршрутов подпроекта. они будут интегрированы как /barcodes/route1, /barcodes/route1`. - person sarveshseri; 13.03.2015
comment
И все ли вы написали в ответе? - person sarveshseri; 13.03.2015
comment
Я считаю, что я следовал все правильно. Я обновил весь соответствующий код выше. - person Brian Kessler; 13.03.2015
comment
Я снова посмотрел на ваш код и понял, что мне не хватает @routes в моем шаблоне модуля. Однако, когда я пытаюсь его добавить, шаблон не компилируется, вероятно, потому, что мы переименовали маршруты в barcodePackage.routes... Не знаю, как это исправить, но я думаю, что проблема в коде на этом этапе, как и прежде, он пропускал маршрутизатор и вместо этого включал значение, возвращаемое контроллером. - person Brian Kessler; 13.03.2015
comment
ты был очень близок и поставил меня на правильный путь, но посмотри на мой ответ. :-) - person Brian Kessler; 13.03.2015
comment
Ну... мой ответ был полным... просто вы выбрали имя пакета как barcodePackage, а я выбрал barcodes, затем я выбрал имя контроллера Barcodes, а вы выбрали BarcodeContoller. И да... Я сделал одну ошибку при вводе ответа, так как reverse-routeer генерируется в самом пакете. Так и должно было быть @controllers.barcodes.routes.Barcodes.barcode(ean) - person sarveshseri; 13.03.2015
comment
На самом деле... Play использует сильно настроенную сборку sbt. И он генерирует reverse-router для каждого пакета, содержащего контроллер, в той же иерархии пакетов, что и сам контроллер. Итак... для любого контроллера me.mypackage.MyController, у которого есть действие myAction, связанное с маршрутом /myaction, обратным маршрутизатором будет me.mypackage.routes, и он будет содержать объект MyContoller, который будет иметь метод myAction. И этот метод me.mypackage.routes.MyController.myAction будет оценивать привязанный маршрут, т.е. /myaction. - person sarveshseri; 13.03.2015
comment
Окончательный ответ, приведенный ниже, должен был соответствовать уточненному коду, указанному выше, иначе да, это было бы так, как вы сейчас предлагаете. - person Brian Kessler; 13.03.2015