I am using Axis to call a SOAP-based web service. I'm then trying to serialize the returned remote object as JSON, using the Google Gson library.
The serialization to JSON fails, with Gson complaining that "there are multiple elements with the name __equalsCalc()).
When I inspect the returned object in my IDE (Eclipse), I can see that this is true -- the returned object has three members called __equalsCalc() and another three called __hashCode.
I know from looking around that these are added by WSDL2Java (I think) in order to avoid recursion. My question is, why are there THREE of each? And how can I get the serializer to ignore these? They're not actually part of the object's definition (it's called a RemoteProject, for reference). Can I do something hackish like cast the RemoteProject to a RemoteProject to get it to drop those members?
This turns out to be not too hard to solve. I have multiple copies of the same instance var because the class being serialized is shadowing fields of the same name from superclasses. Since I don't care about these fields, the best approach in Gson is to write a custom ExckusionStrategy which can selectively ignore fields based on their name:
http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html
I don't know GSon.
With Jackson, you can annotate properties (i.e - fields that have getters/setters according to Java bean convention) with #JsonIgnore.
This way you can prevent issues like recursion/no matching setter or getter and so on...
Try to find out if you have the same at GSon or use Jackson.
Related
Most of the json serializations work using object property accessors like getter and setter methods. I am trying to serialize third party object with no get/set methods(and I don't have control to modify source) to json and send over REST service.
But the final json produced doesn't have all the properties data as like in my object. This is obvious due to no accessor methods.
Is there any other way I can prepare JSON in this scenario?
Otherwise, is there any other way I can send this 3rd party object over my rest service as is without compromising on it's properties values? (I considered like object serialization and send using streams, but that looks like unconventional).
Maybe most. GSON on the other hand uses reflection to directly setup fields. You actually have to force it to not use reflection (see Gson avoid reflection).
So one solution would be to use that library. And just to be precise: gson uses reflection to identify the fields in your bean classes directly, without relying on getters/setters.
The scenario is simple:
UI call RESTful API to get an object tree, then UI change some data and call RESTful API to update it.
But for security or performance reason..., my RESTful API can NOT bring the whole object tree to the UI.
We have two choose for this purpose: creating an individual Java Bean for RESTful API or extend existing business Java Bean plus #JsonIgnore.
The second looks smarter because we re-use business class.
But Now we have a trouble: I need to merge the object from UI with the object from DB, otherwise I will lose some data.
But how do I know which piece of data will come from UI?
I know I can hard code to copy fields one by one.
But this way is dangerous.
I am asking for generic way to avoid hard code to copy fields.
I tried org.apache.commons.beanutils.BeanUtils, but it can't meet the requirement because it always overwrite target fields.
So I am thinking this way:
If the field in UI bean is not Null, then overwrite the value of the same name field in destination bean. but how do I handle if the field is some kind of primitive type like int which have default value 0?
I don't know if the field really carry an UI value 0 or just not comes back from UI.
I tried to convert primitive type to object type, but it still have troubles on boolean type, many java tools don’t support “ Boolean isValid(){…}” like BeanUtils. And this kind converting is dangerous on existing code.
I tried those code:
JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.construct(MyClassDTO.class, ai, null);
String[] ignoredList = ai.findPropertiesToIgnore(ac);
for(String one: ignoredList){
System.out.println(one);
}
but ignoredList is always null. I am using Jackson 1.9.2
You could consider using JsonPatch. We use it and it works quite well. Of course it means you apply patches at the JSON level and not in the bean directly so if you need to support more than just JSON, it might be a problem.
Here's an implementation: https://github.com/fge/json-patch
I found the solution on Jackson:
MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);
it comes from :
readerForUpdating
merging on Jackson
I have an application that saves its context to XML. In this application, there is a hierarchy of classes, that all implement a common interface, and that represent different settings. For instance, a first setting class may be made of 4 public float fields, another one can be made of a sole HashMap.
I am trying to determine what is the best way to handle writing and reading to XML in a generic way. I read on this site a lot about JAXB and XStream for instance, which are able to make a specific class instance from XML.
However my question is related to the fact that the actual class can be anything that implement a given interface. When you read the XML file, how would you guess the actual class to instantiate from the XML data? How do you do that in your applications?
I thought that I could write the .class name in a XML attribute, read it and compare it to all possible class .class names, until I find a match. Is there a more sensible way?
Thanks
xstream should already take care of this and create the object of correct type.
The tutorial seems to confirm that:
To reconstruct an object, purely from the XML:
Person newJoe = (Person)xstream.fromXML(xml);
If you don't know the type, you will have to first assign it to the common interface type:
CommonInterface newObject = (CommonInterface)xstream.fromXML(xml);
// now you can either check its type or call virtual methods
In my case I just have a kind of header that stores the class name that is serialized and when de-serializing it I just use the header value to figure out to which class shall I de-serialize the values.
A best practice would to use an established, well documented XML parser/mapper. All of the serialization/deserialization work has been done, so you can worry about your business logic instead. Castor and Apache Axiom are two APIs that I have used to marshal/unmarshall(serialize/deserialize) Java Classes and XML.
http://www.castor.org
Apache Axiom
Why does GSON use ONLY fields(private,public,protected)?
Is there a way to tell GSON to use only getters and setters?
Generally speaking when you serialize/deserialize an object, you are doing so to end up with an exact copy of the state of the object; As such, you generally want to circumvent the encapsulation normally desired in an OO design. If you do not circumvent the encapsulation, it may not be possible to end up with an object that has the exact same state after deserialization as it had prior to serialization. Additionally, consider the case where you do not want to provide a setter for a particular property. How should serialization/deserialization act if you are working through the getters and setters?
Is there a way to tell GSON to use only getters and setters?
Not yet.
From the design doc:
[T]here are good arguments to support properties as well. We intend to enhance Gson in a latter version to support properties as an alternate mapping for indicating Json fields. For now, Gson is fields-based.
It is possible to to patch Gson to use getters.
The vague outline of how this works in our app is that we have a lot of TypeAdapter implementations - some for specific value-like objects and some for bean-style objects where we know that JavaBeans logic will work. We then jam all of these onto a GsonBuilder before creating the Gson object.
Unfortunately, GSON is really crap at handling types like Object[]. We mostly saw this when we were trying to make a JSON object to represent method parameters. The workaround for that was to make custom TypeAdapter instances which reflect the methods. (This does mean that you end up using one Gson instance per method you intend to call...)
I am writing the service to implement the audit in our application wherein users can view the status of a particular entity before and after any modification and should also be able to roll it back. We have decided to store the XML Serialized object in the databse in XML_TYPE column.
I am new to serialization, I don't know how to achieve the same, any changes needs to be done to the object to be serialized or do we need to have any mapping XML. Can someone please suggest some good libraries, I understand there are lot of those available in the market like JAXB, JIBX, JABX, XStream and etc. Which one would be good and how to use it.
Any help is highly appreciated.
Regards,
Ravi.
Of course, the best for entities is having POJO's (Plain Old Java Objects). No strange properties, references or methods. It simplifies serializing and keeps your model objects neutral from frameworks and strange layers like persistence, UI, remote-access and so on.
XStream: simplicity
I'd suggest using XStream library for serializing. It tries to be the simplest way to serialize and deserialize objects to XML.
You should think searialization this way:
indicate what class is the object
try to serialize each property
So, these are the two problems to resolve in serializing. XStream lets you create a serializer (XStream class), (OPTIONALLY) indicate what tag name use for each class and (OPTIONALLY) indicate the aliases for properties.
So if you have something like:
package pack;
Person
+ mom: Person
+ dad: Person
it will write with no configuration:
<pack.Person>
<mom>
<pack.Person>
...
</pack.Person>
</mom>
<dad>
<pack.Person>
...
</pack.Person>
</dad>
</pack.Person>
But if you tell it to map package.Person to it will use that tag. You can tell it to write property "mom" as "mother" and things like that.
XStream xs = new XStream();
xs.alias("person", Person.class);
xs.aliasAttribute(Person.class, "mom", "mother");
References
XStream also lets you indicate what kind of references you want:
no references: serialize an object
each time it founds it in the object
tree
absolute references: the second time
an object is found it saves a
reference using the absolute path of
the first instance
(/people/person[4]/teacher)
relative references: the same, but
using a relative reference from this
point (../../person[4]/teacher)
JAXB is the standard. In the simplest (and most common case) you just annotate your entities with JAXB annotations, and use a Marshaller to marshal the object to XML.
You can use either Sun's reference implementation, or Apache JaxMe.
XStream is a good alternative as far as I know, although I haven't used it.