Akka Http创建HttpRequest提交JSON至端点失败求助(原用Spray正常)
Hey there! Let's figure out why your Akka HTTP JSON request isn't working when it ran smoothly with Spray. Even though Akka HTTP grew out of Spray, there are some key differences in how requests are structured and JSON is handled—let's walk through the most common issues and fixes:
Spray had its own built-in JSON support, but Akka HTTP relies on libraries like akka-http-spray-json (the most common choice, since it's familiar from Spray) for converting between case classes and JSON. If this setup is off, it's usually the root cause:
- First, confirm you've added the right dependency to your build (example for SBT):
libraryDependencies += "com.typesafe.akka" %% "akka-http-spray-json" % "your-akka-http-version" - You need to define a JSON format for your request model and bring the marshalling support into scope. Create a trait like this:
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import spray.json.DefaultJsonProtocol // Your request model case class ApiRequest(field1: String, field2: Int) trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol { implicit val apiRequestFormat = jsonFormat2(ApiRequest) } - Make sure your client or server code extends this
JsonSupporttrait—without it, Akka HTTP won't know how to serialize/deserialize your JSON.
Spray's HttpRequest had subtle differences compared to Akka HTTP's implementation. Here's a correct example of sending a POST request with a JSON body in Akka HTTP:
import akka.http.scaladsl.model._ import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import scala.concurrent.ExecutionContextExecutor import spray.json._ // Set up Akka essentials (you probably have these, but double-check) implicit val system = ActorSystem("RequestSystem") implicit val materializer = ActorMaterializer() implicit val ec: ExecutionContextExecutor = system.dispatcher // Create your request data val requestBody = ApiRequest("test-value", 123) // Build the HttpRequest correctly val request = HttpRequest( method = HttpMethods.POST, uri = "http://your-service-endpoint", // *Critical:* Set the Content-Type header to application/json and serialize the body entity = HttpEntity(ContentTypes.`application/json`, requestBody.toJson.compactPrint) ) // Send the request and handle the response Http().singleRequest(request).map { response => response.status match { case StatusCodes.OK => println("Request succeeded!") case other => println(s"Request failed with status: $other") } }
Common mistakes here:
- Forgetting to explicitly set the
application/jsoncontent type—Akka HTTP doesn't infer this automatically like Spray sometimes did. - Using the wrong serialization method: make sure you're using the
toJsonmethod from your Spray JSON format, not a custom serializer that produces invalid JSON.
If the issue is on the server side (your Akka HTTP route isn't accepting the request), check these details:
- In Spray, you might have used
entity(as[ApiRequest])—Akka HTTP uses the same directive, but you need the JSON marshaller in scope. Here's a valid route example:import akka.http.scaladsl.server.Directives._ class ServiceRoutes extends JsonSupport { val routes = post { path("your-endpoint-path") { entity(as[ApiRequest]) { requestData => // Process the request and send a response complete(StatusCodes.OK, s"Received data: ${requestData.field1}, ${requestData.field2}") } } } } - If you're dealing with CORS, note that Akka HTTP doesn't include default CORS handling like some Spray setups might have—you'll need to add explicit CORS directives if your client is making cross-origin requests.
To get a clearer picture of what's going wrong, turn on Akka HTTP debug logging. Add these lines to your application.conf:
akka.loglevel = DEBUG akka.http.server.log-unencrypted-network-bytes = 1024 akka.http.client.log-unencrypted-network-bytes = 1024
This will log the raw request and response details, including headers and body content. You'll be able to see if the JSON is malformed, if headers are missing, or if the server is returning a specific error message you weren't catching before.
Mismatched Akka versions can cause all sorts of weird issues. Make sure your Akka Actor, Akka HTTP, and Akka Stream dependencies are using the same compatible version. For example:
- Akka HTTP 10.2.x works with Akka 2.6.x
- Akka HTTP 10.1.x works with Akka 2.5.x
If you can share a minimal, reproducible snippet of your client and server code, that would help pinpoint the exact problem even faster!
内容的提问来源于stack exchange,提问作者Vishal

