pedjak / grails-marshallers Goto Github PK
View Code? Open in Web Editor NEWCustom XML and JSON marshallers for Grails in an easy way
License: Other
Custom XML and JSON marshallers for Grails in an easy way
License: Other
I've been using grails-marshallers from your master branch as of today (2014-01-15). I noticed that when I render my domain objects in JSON, properties with null values or boolean properties with a false value appear in the resulting JSON just fine. However, the same object rendered as XML does not include either of those. I've temporarily fixed this for myself by removing a conditional you have around the writeElement() call: https://github.com/pedjak/grails-marshallers/blob/master/src/groovy/org/grails/plugins/marshallers/GenericDomainClassXMLMarshaller.groovy#L110
The same null/truth checking is done in several places in this class (e.g., marshalling attributes), so they may all need to be looked at. Was your intent to catch org.springframework.beans.InvalidPropertyException?
Without grails-marshallers, Grails by default renders boolean false and nulls in XML.
I am using Grails 2.3.1 right now.
I'm using this plugin and sometimes I need the Map equivalent for a JSON marshaling. Off course, I dont want it to be JSON, but a real Groovy Map.
Is there any way to make that? I know that internally the plugin does a Map to work on (#21).
Hi all,
I'm wondering if there is a way to set the order for the JSON response because it's not structured acording the order I write key-value using the jsonWriter.
I.E.:
jsonWriter.object().key("a").value("first").key("b").value("second")
{
"b": "second",
"a": "first"
}
I expected a-first pair before b-second pair.
This disorder is worst when I include arrays or nest objects in the JSON response.
Thanks in advance!
Fede
I'm currently using the domain class marshalling configuration style. Are you planning to add a counterpart to "ignore" called something like "only"? This would behave like Grails 2.3 respond()'s "includes".
There are times when I want to say "only allow these properties during serialization". Currently it requires using "ignore" but with many list items.
Also, why not deprecate the use of the term "ignore" and go with Grails terminology like "excludes" and "includes"?
This plugin is great, but I'm not quite sure how to use it with the withFormat
grails block.
In particular, I'm looking at this from the standpoint of versioning a REST api via mime-types, similar to how Github does it.
Here is a rough idea of the sort of use pattern / setup I envision:
Config.groovy
// ... snip ...
grails.mime.types = [html: ['text/html', 'application/xhtml+xml'],
text: 'text/plain',
js: 'text/javascript',
rss: 'application/rss+xml',
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
all: '*/*',
form: 'application/x-www-form-urlencoded',
multipartForm: 'multipart/form-data',
jsonv3:['application/vnd.myapp','application/vnd.myapp+json','application/vnd.myapp.v3+json'], // Default, default json, and v3 json
jsonv2:['application/vnd.myapp.v2+json'], // Only v2 json
xmlv3:['application/vnd.myapp+xml','application/vnd.myapp.v3+xml'], // Default xml, and v3 xml
xmlv2:['application/vnd.myapp.v2+xml'] // only v2 xml
]
// Having to declare this once for XML and once for JSON feels clunky
grails.plugins.marshallers.xml = {
v2{
}
}
grails.plugins.marshallers.json= {
v2{
}
}
// ... snip ...
FooController.groovy
// ... snip ...
def show() {
def object = Foo.get(params.id)
withFormat {
html {object}
jsonv3 { render fooInstance as JSON} // v3 is the default
jsonv2 {
JSON.use('v2') {render fooInstance as JSON}
}
xmlv3{ render fooInstance as XML} // v3 is the default
xmlv2{
JSON.use('v2') {render fooInstance as XML}
}
}
}
// ... snip ...
FooV2XmlMarshaller
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller
class FooV2XmlMarshaller implements ObjectMarshaller<XML> {
static configuration = "v2"
boolean supports(Object object) {
Foo.isAssignableFrom(object.class)
}
void marshalObject(obj, xml) {
// Special v2 stuff
}
}
Now, it might be that the plugin already enables this, which would be fantastic, but when I tried it myself, it didn't seem to want to work.
No documentation or examples for marshalling JSON
Domain class:
@EqualsAndHashCode(includes=['name','url'])
class Reference implements Serializable {
Long id
String name
String url
static belongsTo = [threat: Threat, control: Control, test:Test]
static constraints = {
threat(nullable: true)
control(nullable: true)
test(nullable: true)
url(size: 1..Const.FIELD_LENGTH_LONG)
name(size: 1..Const.FIELD_LENGTH_SHORT)
}
public Object getOwningObject() {
if (threat != null) return threat
if (control != null) return control
if (test != null) return test
}
static marshaller = {
shouldOutputIdentifier false
shouldOutputVersion false
shouldOutputClass false
attribute 'ref','name','url'
ignore 'threat','control','test','owningObject'
}
}
But the marshaller ignores those settings and does not add the attributes. And it does output the identifier.
There are a few classes that have the static marshaller code, but are similarly reported as not supported.
20140904.151213.187 15788 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Trying to write field as xml element: refs on threat1 - threat1
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class java.util.HashSet is false
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class java.util.HashSet is false
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class com.threatmanager.Reference is false
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class com.threatmanager.Reference is false
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class com.threatmanager.Reference is false
20140904.151213.188 15789 [main] DEBUG org.grails.plugins.marshallers.GenericDomainClassXMLMarshaller - Support for class com.threatmanager.Reference is false
This plugin looks promising. Hope I can get it working with Grails 2.3.2!
I get a "List collection types only supported on the owning side of a many-to-many relationship." when trying to define closures under serializer or virtual on a domain class which is the owned side of a many-to-many association. Is this an unsupported scenario?
I use Objects that include others with the deep option.
included the configuration in my Domain Objects marshalling = { .. } configuration.
moreover i added the following to my controller setup() (from the unit test case in the project)
grailsApplication.registerArtefactHandler(new JsonMarshallerArtefactHandler())
grailsApplication.registerArtefactHandler(new XmlMarshallerArtefactHandler())
defineBeans {
convertersConfigurationInitializer(ConvertersConfigurationInitializer)
extendedConvertersConfigurationInitializer(ExtendedConvertersConfigurationInitializer)
}
and initialize the test before i call the action in the controller
private def initialize(){
grailsApplication.mainContext.convertersConfigurationInitializer.initialize(grailsApplication)
grailsApplication.mainContext.extendedConvertersConfigurationInitializer.initialize()
}
After adding this the objects get marshalled as json in a correct way.
I use the serializer feature to serialize enums to their names instead of the enum object to have a nice json - when i try to verify the enum in a unit test it is working in the root object but not in the objects included with deep, on those objects the unconverted enum value is returned. When i use the same object in a real controller - the serializer works.
dont know if its a bug or if i left something out in the config - cant find any clues on how to unit test a controller the proper way.
The text included below is all that is mentioned about virtual and serializer. These are incredibly useful features - but their use is kind of a mystery. Could the read me be expanded to show a small example of each?
"virtual is a configuration option which allows us to define closures with custom serialization behavior (json,xml)
serializer unlike virtual which will create completely new property, this configuration options allows us to customize serialization output for existing property"
Why do we make a copy of the collection while we marshal?
Examples:
Btw, is creating an Issue like this the best way to ask questions? :)
I just installed marshallers:0.4, whenever I compiled it the next error was thrown:
| Error Compilation error: startup failed:
/PROJECT_ROUTE/target/work/plugins/marshallers-0.4/src/groovy/org/grails/plugins/marshallers/ConfigurationBuilder.groovy: 28: unable to resolve class org.codehaus.groovy.grails.web.converters.marshaller.ClosureOjectMarshaller
@ line 28, column 1.
import org.codehaus.groovy.grails.web.converters.marshaller.ClosureOjectMarshaller;
ClosureOjectMarshaller is missing a b in Object, so I think this is a typo.
In domain class:
static hasMany = [components: Component, features: Project, settings: Setting, questions: WizardQuestion]
static marshalling = {
deep 'components,features,settings,questions'
}
Results in XML like:
...
But the Component class is not marshalled, it just prints ID not any of the other fields
If I remove multiple properties then it works as expected:
static marshalling = {
deep 'components'
}
Hi,
The latest available version is 0.6 : https://repo.grails.org/grails/plugins/org/grails/plugins/marshallers/
Could you please deploy the 0.7 ?
Thanks
Our project uses single character flags in one class. When we GET an instance, the char property value is [class='system.lang.Character'], I was simply expecting to get a single character string (e.g. 'C' or 'D').
class Product {
char TypeFlag
}
I created the following Marshaller.
JSON.registerObjectMarshaller(Character, { it as String});
(BTW, We really, really appreciate your project. It so easy to used and it has saved us so much time. Kudos you and your fellow project contributors.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.