【问题标题】:Unable to JSON Marshal B defined as List[A] using AKKA-Http and Spray-Json无法使用 AKKA-Http 和 Spray-Json 将 JSON Marshal B 定义为 List[A]
【发布时间】:2023-03-03 03:30:02
【问题描述】:

如标题所述,我无法将 List[A] 编组为正确的 Json(对象数组)。

我正在使用AKKA-HttpSpray-Json

我定义了两个案例类:

final case class Item(id: String, pid: String, title: String)
final case class Items(items: List[Item])

在那次电话中GET http://localhost:8080/item 收到了:

class ItemEndpoint extends Directives with ItemJsonSupport {

  val route: Route = {
    path("item") {
      get {
        parameters("page".?, "size".?) {
          (page, size) => (page, size) match {
            case (_, _) => 
              onSuccess(Server.requestHandler ? GetItemsRequest){
                case response: Items =>
                  complete(response)
                case _ =>
                  complete(StatusCodes.InternalServerError)
              }
          }
        }
      }
    }
  }       

}

GetItemsRequest 被调用。后者定义为

case class GetItemsRequest 

RequestHandler 一样

class RequestHandler extends Actor with ActorLogging {

  var items : Items = _

  def receive: Receive = {
    case GetItemsRequest =>
      items = itemFactory.getItems
      sender() !  items
  }

}

getItems 通过SparkCassandra 执行查询

def getItems() : Items = {
    val query = sc.sql("SELECT * FROM mydb")
    Items(query.map(row => Item(row.getAs[String]("item"), 
                           row.getAs[String]("pid"), row.getAs[String]("title")
    )).collect().toList)
}

返回包含List[Item]Items。所有对象都正确打印(其中一些具有空字段)。

使用ItemJsonFormatter

trait ItemJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
  implicit val itemFormat: RootJsonFormat[Item] = jsonFormat3(Item)
  implicit val itemsFormat: RootJsonFormat[Items] = jsonFormat1(Items)
}

导致以下错误:

[simple-rest-system-akka.actor.default-dispatcher-9] [akka.actor.ActorSystemImpl(simple-rest-system)] 处理请求时出错:“要求失败”。完成 500 内部服务器错误响应。要更改默认异常处理行为,请提供自定义 ExceptionHandler。 java.lang.IllegalArgumentException:要求失败

我尝试捕获异常并处理它,但我没有获得更多关于该问题的信息。

我关注AKKA DOCS 进行编组。

当做同样的事情,但只得到一项时,它工作得很好,我获得了一个包含所有Item的参数格式良好的json。

{
    "id": "78289232389",
    "pid": "B007ILCQ8I",
    "title": ""
}

即使查看其他相关的 Q/A 我也找不到答案,所以 这是什么原因造成的?我该如何解决?

【问题讨论】:

    标签: scala akka marshalling akka-http spray


    【解决方案1】:

    所有对象都正确打印(其中一些具有空字段)。

    可能会引发异常,因为getItems 正在返回具有一个或多个空字段值的Item 对象。

    处理这个问题的一种方法是用空字符串替换空值:

    def rowToItem(row: Row): Item = {
      Item(Option(row.getAs[String]("item")).getOrElse(""),
           Option(row.getAs[String]("pid")).getOrElse(""),
           Option(row.getAs[String]("title")).getOrElse(""))
    }
    
    def getItems(): Items = {
      val query = sc.sql("SELECT * FROM mydb")
      Items(query.map(row => rowToItem(row)).collect().toList)
    }
    

    【讨论】:

    • 我无法测试它,因为我遇到了一些与依赖项有关的版本问题。如果有效,将很快接受。无论如何,我无法理解为什么单个项目不会出现此问题。即使我有一些空白字段,但在使用单个字段时我没有收到任何错误。有什么想法吗?
    • 在您使用单个 Item 的示例中,"title" 字段的值似乎是一个空字符串,而不是 null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 2018-05-25
    • 2019-10-23
    • 2019-02-25
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多