Play Framework端点如何获取RequestContext?兼容Pekko extractRequestContext
迁移Akka REST到Play 3.0的两个关键问题解决
1. 替代Pekko extractRequestContext获取请求上下文
Play框架中没有直接对应Pekko HTTP的RequestContext类型,但Action参数中的Request对象已经包含了所有请求上下文相关信息:
- 请求头:
request.headers - 客户端地址:
request.remoteAddress - 请求ID:
request.id - 自定义属性:
request.attrs(用于存储请求级别的自定义数据)
如果原代码中extractRequestContext是为了提取用户标识(userKey)这类数据,可通过Play的请求属性、Session或Headers直接获取,无需额外提取上下文对象。例如:
// 假设userKey存储在请求属性中 val userKey = request.attrs(Attrs.UserKey)
2. 将Play文件转换为StrictForm.FileData
要把Play的MultipartFormData.FilePart转换为依赖库要求的StrictForm.FileData,需根据FileData的构造逻辑手动映射字段,以下是通用转换方案:
步骤1:明确StrictForm.FileData的结构
通常StrictForm.FileData包含三个核心字段:
- 文件名(
filename: String) - 内容类型(
contentType: Option[String]) - 数据流(
source: Source[ByteString, _])
步骤2:编写转换逻辑
在Action中处理文件上传时,直接从FilePart提取字段并构造FileData:
import org.apache.pekko.stream.scaladsl.Source import org.apache.pekko.util.ByteString import java.nio.file.Files def createWorkspace = Action(parse.multipartFormData) { implicit request => // 转换Play文件为StrictForm.FileData val maybeIcon = request.body.file("icon").map { picture => StrictForm.FileData( filename = picture.filename, contentType = picture.contentType, // 从临时文件读取字节流构造Source source = Source.single(ByteString(Files.readAllBytes(picture.ref.path))) ) } // 绑定表单其他字段(排除icon,后续合并) workspaceForm.bindFromRequest.fold( errors => { println(errors.toString()) BadRequest("Ooops") }, baseRequest => { // 合并icon字段到请求对象 val fullRequest = baseRequest.copy(icon = maybeIcon) onboardingController.saveData(fullRequest) Ok("") } ) }
步骤3:调整表单定义
如果原workspaceForm包含icon字段,需修改为只绑定非文件字段,后续手动合并:
import play.api.data.Form import play.api.data.Forms._ case class WorkspaceRequest( name: String, description: Option[String], icon: Option[StrictForm.FileData], color: String ) val workspaceForm = Form( mapping( "name" -> nonEmptyText, "description" -> optional(text), "color" -> nonEmptyText )((name, desc, color) => WorkspaceRequest(name, desc, None, color))( wr => Some((wr.name, wr.description, wr.color)) ) )
内容的提问来源于stack exchange,提问作者DanCrts
相关产品推荐
相关产品推荐

