A Jax-RS client that does a post with a request body of a JSON string
I am using JaxRS to create client side code that interacts with a vendor's API. I have been able to write code that performs GET and POST, both of which do not have a request body. I am currently running into a problem trying to do a POST where there is only a request body being sent. I am trying to send a simple JSON string:
{"server":{"name":"HelloKitty","imageId":71,"flavorId":1}}
The following is the definition for the WebClient I am using (written in Scala, but I know that the headers and authorizations are being done correctly):
def postClient: WebClient = {
val authClient = WebClient.create(authServer)
authClient.header("X-Auth-User", apiUsername)
authClient.header("X-Auth-Key", apiKey)
val response = authClient.get
val metadata = response getMetadata () map { case (k, v) => k -> v(0).toString }
val client = WebClient.create(metadata.get("X-Server-Management-Url").getOrElse("Error in authentication response"))
client.header("X-Auth-User", apiUsername)
client.header("X-Auth-Key", apiKey)
client.header("X-Auth-Token", metadata.get("X-Auth-Token").getOrElse("Error in authentication response"))
client.header("Content-Type","application/json")
}
Here is my resource interface:
@Produces(Array("text/json"))
trait RackspaceServerApi {
@Path("/servers.json")
@GET
def listServers(): String
@Path("/servers/detail.json")
@GET
def listServersDetailed(): String
@POST
@Path("/servers")
@Consumes(Array("application/json"))
def createServerData(server: String)
}
Here is my method that creates a proxy and tries to send the request
def createServer(name: String, imageId: Long, flavorId: Int) = {
// this creates a simple pojo for the server
val serverObject = new RackspaceCreateServerObject(name, imageId, flavorId, None, None)
// i am using lift-web to handle the json
// here I am unmarshalling the serverObject into a json string
val jsonServerData = write(serverObject)
val postProxy = JAXRSClientFactory.fromClient(RackspaceConnection.postClient, classOf[RackspaceServerApi], true)
postProxy.createServerData(jsonServerData)
}
And here is the specific WebApplicationException I get:
Status code: [500]
Entity: [No message body writer found for response class : JAXBElement.]However, if I try to send the request using a webclient instead of a proxy like so:
def createServer(name: String, imageId: Long, flavorId: Int) = {
// this creates a simple pojo for the server
val serverObject = new RackspaceCreateServerObject(name, imageId, flavorId, None, None)
// i am using lift-web to handle the json
// here I am unmarshalling the serverObject into a json string
val jsonServerData = write(serverObject)
val webClient = RackspaceConnection.postClient
webClient.path("/servers")
webClient.post(jsonServerData)
}
It works. Am I doing something wrong in the interface (missing some magical combinatio开发者_C百科n of annotations?)? Or did I not set something up? I am using Jax-RS 2.3.2.
What JAX-RS implementation are you using?
The error message indicates that you need to register a plugin/module to handle the marshalling of JAXB beans to JSON. Some JAX-RS implementations will do this automatically, some require some initialisation.
精彩评论