Nital
Nital

Reputation: 6084

How to send a JSON payload with REST API in Grails?

I am trying to call a REST API with JSON payload using Grails and getting error below.

I have already converted the object to JSON earlier here and passing it in. Not sure what am I missing.

SpotifyService.groovy

@Transactional
class SpotifyService implements EventPublisher {

    String spotifyServiceBaseUrl = 'http://localhost:9999'
    String username = "abcd"
    String password = "defg"

    void createSoldOrder(ItemDetails itemDetails) {
        println("into the createSoldOrder method......")
        String orderId = "100-200-ABC"
        String soldDate = itemDetails.order.orderDate
        String partnerUniqueId = itemDetails.customer.billingAddress.email
        def monthEndDate = new Date() + 30
        String commitEndDate = monthEndDate.toString()
        String product = "premium-month"
        String soldMetadata = "Partner's metadata connected to the sold order"
        String partnerDeals = "hardbundle*3,standalone"
        NewOrder newOrder = new NewOrder(orderId: orderId, soldDate: soldDate, partnerUniqueId: partnerUniqueId,
                commitEndDate: commitEndDate, product: product, soldMetadata: soldMetadata,
                partnerDeals: partnerDeals)
        println("newOrder: " + newOrder)
        String newOrderJsonPayload = new JsonBuilder(newOrder).toPrettyString()
        println("newOrderJsonPayload: " + newOrderJsonPayload)
        placeSpotifyOrder(newOrderJsonPayload)
    }

    void placeSpotifyOrder(String newOrderJsonPayload) {
        println("into the placeSpotifyOrder method........")
        String restUrl = spotifyServiceBaseUrl + "/order-sold"
        println restUrl
        RestBuilder rest = new RestBuilder()
        RestResponse restResponse = rest.post(restUrl) {
            auth username, password
            json {
                newOrderJsonPayload
            }
        }
        if (restResponse.statusCode.value()) {
            println(restResponse.text)
        }
        null
    }

}

Error:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{
    "product": "premium-month",
    "orderId": "100-200-ABC",
    "soldMetadata": "Partner's metadata connected to the sold order",
    "partnerUniqueId": "[email protected]",
    "commitEndDate": "Sat Mar 24 16:51:37 EDT 2018",
    "soldDate": "2017-08-03T20:07:27+0000",
    "partnerDeals": "hardbundle*3,standalone"
}' with class 'java.lang.String' to class 'grails.converters.JSON'
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
    at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.asType(DefaultGroovyMethods.java:15669)
    at org.codehaus.groovy.runtime.StringGroovyMethods.asType(StringGroovyMethods.java:195)
    at org.codehaus.groovy.runtime.dgm$1048.doMethodInvoke(Unknown Source)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:913)
    at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:904)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:168)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:591)
    at grails.web.JSONBuilder.build(JSONBuilder.groovy:42)
    at grails.plugins.rest.client.RequestCustomizer.json(RequestCustomizer.groovy:195)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1433)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at com.synapsegroupinc.spotifyintegrator.SpotifyService$__tt__placeSpotifyOrder_closure4.doCall(SpotifyService.groovy:50)

Upvotes: 1

Views: 1446

Answers (2)

Beno
Beno

Reputation: 987

I think your problem connected with Method json{}. The method is overloaded. If you want to send payload as json string you should change your code in placeSpotifyOrder as following:

RestResponse restResponse = rest.post(restUrl) {
      auth (username, password)
      json (newOrderJsonPayload)            
}

Upvotes: 1

elixir
elixir

Reputation: 1442

Create a new class with all the properties you need in the json object. Create an instance of the class and populate its properties. Then use objInstance as JSON to covert it to json.

Upvotes: 1

Related Questions