Невозможно прикрепить заголовок ответа в ActionBuilderImpl.invokeBlock () - PullRequest
0 голосов
/ 28 января 2019

В моем приложении Play 2.6 у меня есть собственный класс действий, который выполняет некоторые общие действия, применимые ко всем моим действиям.Опуская несвязанные детали, код выглядит следующим образом:

class VariantAction @Inject()
  (parser: BodyParsers.Default)
  (implicit ec: ExecutionContext) 
extends ActionBuilderImpl(parser) with Results {

   ///
   override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
      if (aok) {
            block(request).andThen {
              case Success(result) =>                
                  result.withHeaders("foo" -> "bar")   // THIS DOES NOT WORK
              case Failure(t) =>
            }
         }
         catch {
              /// Some exception handling
         }
      }
      else {
         Future.successful(ServiceUnavailable)
      }
   }
}

Все работает, как и ожидалось: обратный вызов в andThen () выполняется, но заголовок, который он пытается добавить в ответ, не добавляется.Я предполагаю, что есть условие гонки, и к тому времени, когда обратный вызов вызван, ответ уже передан.Конечно, я могу добавить эту логику ко всем конкретным действиям, но это, кажется, не поддается разуму.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Ответ Андрея содержит объяснение того, почему мой код не работал, но не исчерпывающий ответ, как его исправить: корень проблемы, как указывает Андрей, заключается в моем неправильном понимании метода Result.withHeaders ():это не мутатор, а скорее создает новый объект Result.

Это работает:

class VariantAction @Inject()
  (parser: BodyParsers.Default)
  (implicit ec: ExecutionContext) 
extends ActionBuilderImpl(parser) with Results {

   ///
   override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
      if (aok) {
         block(request).map { _.withHeaders("foo" -> "bar") }
         }
         catch {
              /// Some exception handling
         }
      }
      else {
         Future.successful(ServiceUnavailable)
      }
   }
}
0 голосов
/ 28 января 2019

Конструкция block(request).andThen ... возвращает только result, результат не возвращается с заголовком "foo".он же возвращает результат block(request), а не результат .andThen.Обратный вызов в .andThen будет в конечном итоге работать, хотя результат не будет возвращен.

Попробуйте изменить andThen на map.andThen для "побочного эффекта" и "map" для результата "преобразования".

Здесь разница:

enter image description here

Вы также должны быть уверены, что не переопределяете заголовок "foo" позже в действии.

...