You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala Http4s POST请求返回请求体无效问题排查

问题:Scala Http4s服务器POST请求返回「The request body was invalid」错误

我搭建的Scala Http4s服务器中,GET请求可正常运行,但发送POST请求时返回「The request body was invalid」错误。以下是相关代码和测试请求:

服务器代码

implicit val performanceEncoder: Encoder[Performance] = deriveEncoder[Performance]
implicit val performanceDecoder: EntityDecoder[IO, Performance] = jsonOf[IO, Performance]

private val route: HttpRoutes[IO] = HttpRoutes.of[IO] {
  case GET -> Root / "performances" => Ok(IO.fromFuture(IO(service.getPerformancesWithTickets)))
  case p@POST -> Root / "performances" => p.as[Performance].flatMap {
    perf =>
       Created(IO.fromFuture(IO(service.createPerformanceWithoutTickets(perf))))
   }
}

private val corsRoute = CORS.policy.withAllowOriginAll(route)

private val app: Kleisli[IO, Request[IO], Response[IO]] = Router(
    "/" -> corsRoute
).orNotFound

override def run(args: List[String]): IO[ExitCode] =
  BlazeServerBuilder[IO]
    .bindHttp(8083, "localhost")
    .withHttpApp(app)
    .resource
    .useForever
    .as(ExitCode.Success)

Performance样例类

case class Performance(id: Int, title: String, director: String, stage: String, premierDate: LocalDate,
                   description: String, photoReference: String, tickets: List[Ticket])

测试POST请求

curl -X POST \
 http://localhost:8083/performances \
 -H "Content-Type: application/json" \
 -d '{
   "id": 0,
   "title": "somevalue",
   "director": "somevalue",
   "stage": "somevalue",
   "premierDate": "2023-10-15",
   "description": "somevalue",
   "photoReference": "/images/somevalue.jpg",
   "tickets": []
 }'

问题原因及解决方法

1. LocalDate类型缺少JSON解码支持

Http4s默认使用circe作为JSON处理库,但circe核心库不支持Java 8日期类型(如LocalDate)的自动编码解码。你的Performance类包含premierDate: LocalDate字段,POST请求中的日期字符串无法被正确解析,导致请求体验证失败。

解决步骤:

  • 在项目依赖中添加circe-java8库(以sbt为例):
    libraryDependencies += "io.circe" %% "circe-java8" % "你的circe版本号"
    
  • 在代码中导入circe-java8的日期支持:
    import io.circe.java8.time._
    

2. Ticket类可能缺少对应的编码器/解码器

如果Ticket是自定义样例类,当前代码中未为它定义Encoder和Decoder,即使请求中tickets字段是空数组,circe也无法正确解析该类型。

解决步骤:

  • 为Ticket类生成对应的编码器和解码器:
    import io.circe.generic.semiauto.{deriveEncoder, deriveDecoder}
    
    case class Ticket(/* 你的Ticket字段 */)
    
    implicit val ticketEncoder: Encoder[Ticket] = deriveEncoder[Ticket]
    implicit val ticketDecoder: Decoder[Ticket] = deriveDecoder[Ticket]
    

完成以上操作后重启服务器,POST请求即可正常解析请求体。


内容的提问来源于stack exchange,提问作者Jelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:37:44