Grails(15)How to Customized Marshaller
SOAPUI eclipse plugin URL
http://www.soapui.org/eclipse/update
Use the POSTMAN in chrome to test the REST API
We can create the Marshaller class especially for one class
package com.sillycat.project.util.marshaller
import grails.converters.JSON
import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller
import org.codehaus.groovy.grails.web.json.JSONWriter
import com.sillycat.project.Store
import com.sillycat.project.util.Util
class StoreJSONMarshaller implements ObjectMarshaller<JSON> {
publicboolean supports(Object object) {
if(object instanceof Store){
return true;
}
return false;
}
publicvoid marshalObject(Object object, JSON converter)
throws ConverterException {
def store = (Store)object
JSONWriter writer = converter.getWriter();
writer.object();
def streetAddress = (store.address2 == null || store.address2.equals("")) ? store.address1 : store.address1 + ' ' + store.address2
writer.key("address")
writer.value([
'state':store.state,
'country': store.country,
'streetAddress': streetAddress,
city: store.city,
postalCode: store.zip
])
writer.key("id")
writer.value(store.getId())
writer.key("name")
writer.value(store.storeName)
writer.key("status")
writer.value(store.enabled?'ENABLED':'DISABLED')
writer.key("retailerStoreId")
writer.value(store.storeCode)
writer.key("geofences")
def latitude = null;
def longitude = null;
if(store.geoFence != null && store.geoFence.center != null){
latitude = store.geoFence.center.latitude;
}
if(store.geoFence != null && store.geoFence.center != null){
longitude = store.geoFence.center.longitude
}
writer.value([
name: store.storeName,
id: store.geoFence.id,
type: "STORE",
latitude: latitude,
longitude: longitude,
radius: store.geoFence.radius,
ssid : store.ssid,
bssid: store.bssid
])
def brandCode = null
//if(Util.getCurrentBrand() != null){
//brandCode = Util.getCurrentBrand().getCode()
//}
//writer.key("brandCode")
//writer.value(brandCode)
writer.key("timezone")
writer.value(store.timeZone == null ? null : store.timeZone.getID())
writer.endObject();
}
}
Here comes the test class:
@Test
publicvoid testGetSuccess() {
List<Store> stores = [
new Store(storeCode:"TS1",storeName:"Test Store 1",enabled:true),
new Store(storeCode:"TS2",storeName:"Test Store 2",enabled:true),
new Store(storeCode:"TS3",storeName:"Test Store 3",enabled:false)]
mockDomain(Store, stores)
JSON.registerObjectMarshaller(new StoreJSONMarshaller(), 1)
registerMetaClass(Util)
def controller = new StoreController()
controller.params.id = 1
controller.apiGet()
assertEquals(controller.response.status, 200)
//System.out.println(controller.response.status)
//System.out.println(controller.response.contentAsString)
def actualStore = JSON.parse(controller.response.contentAsString)
assertNotNull(actualStore)
assertEquals("Test Store 1",actualStore.name)
}
In the configuration file, BootStrap.groovy
bootstrapService.registerCustomJSONMarshallers()
And here is the class BootstrapService.groovy
import grails.converters.JSON
import com.sillycat.project.util.marshaller.StoreJSONMarshaller
class BootstrapService {
static transactional = true
void registerCustomJSONMarshallers() {
JSON.registerObjectMarshaller(new StoreJSONMarshaller(), 1)
}
}
References:
http://jwicz.wordpress.com/2011/07/11/grails-custom-xml-marshaller/
http://manbuildswebsite.com/2010/02/15/rendering-json-in-grails-part-3-customise-your-json-with-object-marshallers/
http://manbuildswebsite.com/2010/02/08/rendering-json-in-grails-part-2-plain-old-groovy-objects-and-domain-objects/
http://www.soapui.org/eclipse/update
SOAPUI eclipse plugin URL
http://www.soapui.org/eclipse/update
Use the POSTMAN in chrome to test the REST API
We can create the Marshaller class especially for one class
package com.sillycat.project.util.marshaller
import grails.converters.JSON
import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller
import org.codehaus.groovy.grails.web.json.JSONWriter
import com.sillycat.project.Store
import com.sillycat.project.util.Util
class StoreJSONMarshaller implements ObjectMarshaller<JSON> {
publicboolean supports(Object object) {
if(object instanceof Store){
return true;
}
return false;
}
publicvoid marshalObject(Object object, JSON converter)
throws ConverterException {
def store = (Store)object
JSONWriter writer = converter.getWriter();
writer.object();
def streetAddress = (store.address2 == null || store.address2.equals("")) ? store.address1 : store.address1 + ' ' + store.address2
writer.key("address")
writer.value([
'state':store.state,
'country': store.country,
'streetAddress': streetAddress,
city: store.city,
postalCode: store.zip
])
writer.key("id")
writer.value(store.getId())
writer.key("name")
writer.value(store.storeName)
writer.key("status")
writer.value(store.enabled?'ENABLED':'DISABLED')
writer.key("retailerStoreId")
writer.value(store.storeCode)
writer.key("geofences")
def latitude = null;
def longitude = null;
if(store.geoFence != null && store.geoFence.center != null){
latitude = store.geoFence.center.latitude;
}
if(store.geoFence != null && store.geoFence.center != null){
longitude = store.geoFence.center.longitude
}
writer.value([
name: store.storeName,
id: store.geoFence.id,
type: "STORE",
latitude: latitude,
longitude: longitude,
radius: store.geoFence.radius,
ssid : store.ssid,
bssid: store.bssid
])
def brandCode = null
//if(Util.getCurrentBrand() != null){
//brandCode = Util.getCurrentBrand().getCode()
//}
//writer.key("brandCode")
//writer.value(brandCode)
writer.key("timezone")
writer.value(store.timeZone == null ? null : store.timeZone.getID())
writer.endObject();
}
}
Here comes the test class:
@Test
publicvoid testGetSuccess() {
List<Store> stores = [
new Store(storeCode:"TS1",storeName:"Test Store 1",enabled:true),
new Store(storeCode:"TS2",storeName:"Test Store 2",enabled:true),
new Store(storeCode:"TS3",storeName:"Test Store 3",enabled:false)]
mockDomain(Store, stores)
JSON.registerObjectMarshaller(new StoreJSONMarshaller(), 1)
registerMetaClass(Util)
def controller = new StoreController()
controller.params.id = 1
controller.apiGet()
assertEquals(controller.response.status, 200)
//System.out.println(controller.response.status)
//System.out.println(controller.response.contentAsString)
def actualStore = JSON.parse(controller.response.contentAsString)
assertNotNull(actualStore)
assertEquals("Test Store 1",actualStore.name)
}
In the configuration file, BootStrap.groovy
bootstrapService.registerCustomJSONMarshallers()
And here is the class BootstrapService.groovy
import grails.converters.JSON
import com.sillycat.project.util.marshaller.StoreJSONMarshaller
class BootstrapService {
static transactional = true
void registerCustomJSONMarshallers() {
JSON.registerObjectMarshaller(new StoreJSONMarshaller(), 1)
}
}
References:
http://jwicz.wordpress.com/2011/07/11/grails-custom-xml-marshaller/
http://manbuildswebsite.com/2010/02/15/rendering-json-in-grails-part-3-customise-your-json-with-object-marshallers/
http://manbuildswebsite.com/2010/02/08/rendering-json-in-grails-part-2-plain-old-groovy-objects-and-domain-objects/
http://www.soapui.org/eclipse/update