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

如何在Scala中将MongoDB返回的JSON格式Greeting数据转为XML

Fixing XML Conversion for Scala Greeting Case Class from MongoDB Future

Let's break down what's going wrong in your code and walk through the fixes, tailored specifically for Scala and Akka HTTP (since your route structure looks like Akka HTTP):

First, the core issues in your current code:

  1. You're passing a Future[Seq[Greeting]] directly to Jackson's readValue() — Jackson has no idea how to handle Scala Future (it's an asynchronous wrapper, not the actual data). You need to wait for the future to resolve first.
  2. Jackson's default setup doesn't support Scala case classes — the standard Jackson databind library is built for Java, so you need the Scala module to handle case classes properly.
  3. You don't need to convert through JSON first — your goal is XML output, so we can serialize the Seq[Greeting] directly to XML, skipping the unnecessary JSON step.

Solution 1: Manual XML Construction (Simplest, No Extra Dependencies)

Since your Greeting case class is small, building the XML manually is straightforward and avoids adding more libraries. Akka HTTP has built-in support for Scala's native XML type, so this works out of the box.

Here's the corrected route:

import akka.http.scaladsl.server.Directives._
import scala.concurrent.Future
import scala.xml.Elem

// Your existing case class
case class Greeting(msg: String, name: String)

path("getXML") {
  val greetingSeqFuture: Future[Seq[Greeting]] = MongoDAL.fetchAllGreetings()
  
  // Handle the asynchronous Future with Akka HTTP's onComplete
  onComplete(greetingSeqFuture) {
    case scala.util.Success(greetings) =>
      // Build XML directly from the Seq[Greeting]
      val xmlResponse: Elem = <greetings>
        {greetings.map(greeting => 
          <greeting>
            <msg>{greeting.msg}</msg>
            <name>{greeting.name}</name>
          </greeting>
        )}
      </greetings>
      complete(xmlResponse) // Akka HTTP auto-sets Content-Type to application/xml
    
    case scala.util.Failure(error) =>
      complete(s"Failed to load greetings: ${error.getMessage}")
  }
}

Solution 2: Using Jackson for XML Serialization (For Complex Classes)

If you need to handle more complex case classes later, using Jackson's XML module with Scala support is a scalable option. First, update your built.sbt with compatible dependencies (your 2.4.0 version is very outdated — use a recent stable version):

libraryDependencies ++= Seq(
  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.15.2",
  "com.fasterxml.jackson.dataformat" % "jackson-dataformat-xml" % "2.15.2",
  // Keep your existing Akka HTTP and MongoDB dependencies
)

Then, adjust your route to use Jackson's XmlMapper (configured for Scala):

import akka.http.scaladsl.server.Directives._
import scala.concurrent.Future
import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

// Initialize the mapper once (don't create it inside the route!)
val xmlMapper: XmlMapper = XmlMapper.newBuilder()
  .addModule(DefaultScalaModule) // Enables Scala case class support
  .build()

path("getXML") {
  val greetingSeqFuture: Future[Seq[Greeting]] = MongoDAL.fetchAllGreetings()
  
  onComplete(greetingSeqFuture) {
    case scala.util.Success(greetings) =>
      // Serialize the Seq[Greeting] directly to XML string
      val xmlString = xmlMapper.writeValueAsString(greetings)
      complete(xmlString)
    
    case scala.util.Failure(error) =>
      complete(s"Failed to load greetings: ${error.getMessage}")
  }
}

Key Takeaways

  • Always resolve Futures in Akka HTTP routes — use onComplete, onSuccess, or onFailure to handle asynchronous results; never pass a raw Future to serialization methods.
  • Scala case classes need special Jackson support — the jackson-module-scala adds handling for case classes, immutable fields, and other Scala-specific features.
  • Prefer manual XML for simple types — it's faster, easier to debug, and doesn't require extra dependencies.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:47:53