在Play Framework中创建一个新的Controller并调用它的方法,可以分为几个步骤。这里我将以Scala语言为例来展示如何操作。
步骤 1: 创建一个新的Play Framework项目
如果你还没有创建一个Play项目,你可以使用sbt(Scala构建工具)来创建一个。打开终端,运行以下命令:
sbt new playframework/play-scala-seed.g8
这将会创建一个新的Play项目。跟随提示输入你的项目信息。
步骤 2: 创建一个Controller
在app/controllers目录下创建一个新的Controller。例如,你可以创建一个名为HelloController.scala的文件:
package controllers
import javax.inject._
import play.api.mvc._
@Singleton
class HelloController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
def index() = Action {
Ok("Hello, World!")
}
}
步骤 3: 配置路由
在conf/routes文件中,你需要添加一个路由来映射到你的新Controller的方法。例如:
GET /hello controllers.HelloController.index()
这行代码的意思是,当有HTTP GET请求到/hello路径时,它会调用HelloController的index方法。
步骤 4: 运行你的应用
在项目根目录下,运行以下命令来启动你的Play应用:
sbt run
打开浏览器访问 http://localhost:9000/hello,你应该能看到返回的页面显示"Hello, World!"。
步骤 5: 调用Controller方法(如果你需要在其他地方调用)
如果你想在其他地方(例如另一个Controller或一个Service)调用HelloController的index方法,你可以直接注入HelloController的实例,然后调用它的方法。例如,你可以在另一个Controller中这样做:
package controllers
import javax.inject._
import play.api.mvc._
import play.api.libs.json._
import services.MyService // 假设你有一个MyService服务类,稍后我们会看到如何创建它
@Singleton
class AnotherController @Inject()(cc: ControllerComponents, helloController: HelloController, myService: MyService) extends AbstractController(cc) {
def anotherAction() = Action { implicit request =>
val result = helloController.index() // 调用HelloController的方法
Ok(Json.toJson(result)) // 将结果转换为JSON并返回
}
}
步骤 6: 修改路由以包含另一个Controller的方法(如果需要)
如果你需要从外部访问AnotherController的anotherAction方法,你需要在conf/routes文件中添加相应的路由:
GET /another controllers.AnotherController.anotherAction()
这样,当你访问http://localhost:9000/another时,就会调用AnotherController的anotherAction方法。
小结:
通过以上步骤,你可以在Play Framework中创建并调用一个Controller。你可以根据需要创建更多的Controllers和Services,并通过依赖注入在它们之间进行通信。
def index() = Action 是 Play Framework 中定义 HTTP 处理器的基础写法,其核心在于 Action 后必须跟随花括号代码块 返回 Result,常见变体包括带请求参数、指定解析器、异步处理及占位实现 。
核心写法变体
- 无参简单 Action :
def index = Action { Ok("Hello") }(括号可省略,直接返回 Result) - 带隐式请求对象 :
def index = Action { implicit request => Ok(request.uri) }(需访问 request 信息) - 指定 BodyParser :
def index = Action(parse.json) { implicit request => Ok("Got JSON") }(限制请求体类型) - 异步 Action :
def index = Action.async { Future.successful(Ok("Async")) }(返回Future[Result]) - 未实现占位 :
def index = TODO(返回 501 Not Implemented)
关键补充说明
- 语法差异 :
def index()与def index在 Scala 中均可用,但 Play 惯例常省略空括号;Action后必须 有{ ... }代码块或返回Result的表达式,单独写Action会编译报错 。 - Result 类型 :花括号内需返回
play.api.mvc.Result实例,如Ok、BadRequest、Redirect、InternalServerError等辅助方法 。 - 现代写法 :Play 2.4+ 推荐继承
BaseController并使用@Singleton类结构,而非旧版object extends Controller。
完整示例对比
// 基础同步
def index = Action { Ok("Hello") }
// 带请求日志
def logIndex = Action { implicit request =>
println(s"Request: ${request.uri}")
Ok("Done")
}
// 仅接受 JSON
def jsonIndex = Action(parse.json) { implicit request =>
Ok(s"Received ${request.body}")
}
// 异步处理
def asyncIndex = Action.async { someAsyncJob.map(result =>
Ok(result))
}
:::
需要我帮你对比不同 Action 变体的性能差异吗?可以帮你快速选到最适合当前业务场景的写法。