Изменить тело запроса в ActionBuilder of Play Framework - PullRequest
0 голосов
/ 22 февраля 2020

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

object MandoAction extends ActionBuilder[Request, AnyContent] {
  override def parser: BodyParser[AnyContent] = parse.default

  override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = {
    request.body match {
      case AnyContentAsFormUrlEncoded(body) =>
        val newBody: Map[String, Seq[String]] = body + ("hero" -> Seq("mando"))
        block(request.withBody(newBody))
      // case AnyContentAsJson(body) =>
      //   block(request)
      case _ =>
        block(request)
    }
  }
}

Не компилируется из-за того, что Request[Map[String, Seq[String]]] не соответствует ожидаемому универсу c Request[A]. Это правильный способ изменения данных запроса? Как я могу изменить запрос, не зная, каким может быть тело (например, иногда это может быть json, x- www-form-urlencoded, et c)?

1 Ответ

0 голосов
/ 23 февраля 2020

Как я могу изменить запрос, не зная, каким может быть тело (например, иногда это может быть json, x- www-form-urlencoded, et c)?

Я предполагаю, что вам придется использовать комбинацию сопоставления с шаблоном и asInstanceOf (поскольку интерфейс из библиотеки, которую нельзя изменить), например,

class ChangeBodyAction @Inject() (val parser: BodyParsers.Default)(implicit val executionContext: ExecutionContext)
  extends ActionBuilder[Request, AnyContent] 
    with ActionTransformer[Request, Request] {
  def transform[A](request: Request[A]): Future[Request[A]] = Future.successful {
    val transformedBody =
      request.body match {
        case AnyContentAsFormUrlEncoded(data) =>
          val transformedBody = data + ("hero" -> Seq("mando"))
          AnyContentAsFormUrlEncoded(transformedBody)

        case AnyContentAsJson(data) =>
          val transformedBody = data.as[JsObject] + ("hero" -> Json.toJson("mando"))
          AnyContentAsJson(transformedBody)

        case _ => request.body
      }

    request.withBody(transformedBody.asInstanceOf[A])
  }
}

Это правильный способ изменения данных запроса?

ИМХО, нет. Лично я бы оставил исходный запрос без изменений и рассмотрел бы решение проблемы с WrappedRequest или выполнение преобразований после десериализации тела в модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...