如何使用 play framework 2.5 代理 HTTP 方法?

Posted

技术标签:

【中文标题】如何使用 play framework 2.5 代理 HTTP 方法?【英文标题】:How to proxy an HTTP method with play framework 2.5? 【发布时间】:2016-11-03 09:48:43 【问题描述】:

我有 2 个简单的 API:

GET      /users/me/photos        controllers.api.UserController.getMyPhotos
GET      /users/:userId/photos   controllers.api.UserController.getPhotos(userId: Int)

这里是getPhotos

def getPhotos(userId: Int) = SecuredAction.async 
  logger.info(s"Searching for user $userId's photos")

  userPhotosRepo.findByUserId(userId).map 
    photos => Ok(Json.toJson(photos))
  

这里是getMyPhotos

def getMyPhotos = SecuredAction.async  request =>

  request.identity.id.map  currentUserId =>
    logger.info(s"Searching for current user's photos")

    getPhotos(currentUserId) // doesn't work
  .getOrElse(Future.successful(InternalServerError))

如何让getMyPhotos 代理到getPhotos,而不创建他们都调用的辅助方法?

【问题讨论】:

返回的错误是什么?我认为您的代码应该可以工作(SecuredAction 中的代码将被调用两次,一次用于getMyPhotos,一次用于getPhotos 【参考方案1】:

这里可以使用 Play Framework 提供的反向路由

 [full package].routes.[controller].[method]

你的情况

routes.api.UserController.getPhotos(request.identity.id)

如果你想要第一个动作的结果

val ans: Result = Redirect(routes.api.UserController.getPhotos(request.identity.id))

我希望这就是你想要问的。

编辑:

出于您的考虑,这应该是一种正确的方法

def getPhotos(userId: Long) = SecuredAction.async 
  userPhotosRepo findByUserId(userId) map 
    photos => Ok(Json.toJson(photos))
  


def getMyPhotos = SecuredAction.async  request =>
   request.identity.id map  id =>
       Redirect(routes.HomeController.getPhotos(id))
  
 

【讨论】:

我刚刚尝试过,但出现错误:play.sbt.PlayExceptions$CompilationException: Compilation error[Cannot write an instance of play.api.mvc.Result to HTTP response. Try to define a Writeable[play.api.mvc.Result]] 我的代码只是Future.successful(Ok(Redirect(routes.UserController.getPhotos(currentUserId))))。我不想发出实际的 HTTP 重定向,所以我假设这只是一个透明的内部重定向? 您想在另一个动作中调用哪个动作? - 我假设您想在 getPhotos 中调用 getMyPhotos ? - 你想从一个动作中得到另一个动作的响应吗​​? 没有。 getMyPhotos 是从他们的身份验证信息中获取当前用户 ID 的那个。然后我只想返回从getMyPhotos 调用getPhotos(currentUserId) 的结果。这只是一种方便的方法,因此客户端不需要知道登录用户的 ID 是什么。 如果你想通过我的编辑来实现这样的目标,这可能是一个更好的选择,并且会根据需要添加抽象。

以上是关于如何使用 play framework 2.5 代理 HTTP 方法?的主要内容,如果未能解决你的问题,请参考以下文章

Play Framework 2.5 JavaAsync 抛出 CompletionException

Play framework 2.5新建工程执行日志

Play Framework (2.5) - JMX port enable to see in JVisualVM

从 Play Framework 更改 WS API! 2.4 至 2.5

如何在 Play 2.5 框架中使用授权 ActionBuilder 保护静态文件

如何在 play framework 1.2.5 中验证 REST