how to use #XmlElement in java - java

I'm trying to learn how to store objects as XML files in java, but I'm having a bit of a problem.
Most tutorials that I have found have said that I should use the #XmlElement annotation with set methods, however is there another way to use them, as my objects would be easier to make using just the constructors I have for them instead of a set for each field.

The #XmlElement can also be used on the property. You will find more information in the javadoc.
The javadoc gives this example:
public class USPrice {
#XmlElement(name="itemprice")
public java.math.BigDecimal price;
}

All public fields and properties (get/set method pairs) will be treated by default as if they were annotated with #XmlElement. You can add #XmlElement on the get or set method. You can also annotate the field (instance variable). If you do you should annotate your class with #XmlAccesorType(XmlAccessType.FIELD).
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
JAXB does not currently support annotating constructors. If you are dealing with immutable objects then the following may help:
http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html

Related

Jackson: Overriding JSON property

Trying to override a JSON propert to return date in long format. But it does not seem to work.
#JsonIgnore
#JsonProperty("dateTime")
public long getDateTimeInLong() {
return getDateTime().getTime(); //belongs to super class. It is an AspectJ implementation.
}
If I remove the #JsonIgnore annotation I get Conflicting getter definitions for property "dateTime": exception.
The error message describes itself. It occurs because you have conflicting getter definitions.
You can fix it by resolving the getter conflict. I suppose you already have getDateTime() method that has the #JsonProperty annotation. You can just remove the annotation or add #JsonIgnore. Both ways should work. If the method is defined in the super class you can override the method and redefine its annotations.
I'd avoid using annotations for data representation purposes, since it probably would pollute your code, design would become 'representation centric'. Unless you're using that object as DTO, but that's another anti pattern. Instead I'd separate representation concerns, there's already an answer how to do that.

Customizing Field Name Serialization in Jackson Object Mapper

Say I have a bean:
public class MyBean {
public String oneMississipi;
public int myBestFriend;
//Getters&Setters&Bears,Oh my.
}
And I am using com.fasterxml.Jackson DataBinding to transform instances of this pojo into json output... How do I customize the serialization of field names and can this be scoped to a global/class/field level?
e.g. I wish to dasherize my field names:
{
"one-mississipi": "two mississippi",
"my-best-friend": 42
}
I have already spent hours in Google and even trawling through the jackson code in order to find out where the field serialization occurs, but can't seem to see anywhere that it may delegate for custom field processing.
Does anyone have any ideas as to where this functionality lies if any? Much appreciated
Implement PropertyNamingStrategy and inside the resolving methods use AnnotatedMethod, AnnotatedField or AnnotatedParameter to get the declaring class. Then you can look for any custom annotation on that class and apply any custom naming depending on it.
The biggest problem with this approach is that it's not possible to get the actual concrete class being serialized or deserialized, it will always return the declaring class. So it won't be possible to override naming behavior in subtypes for the inherited members unless you bring them into the subtype.
Another solution would be using different mappers for classes that have different naming strategies. You can make it more or less transparent by creating a top-level "router" mapper that will decide which mapper instance to use (special care must be taken for configuration methods and other non ser/deser related methods). Assuming that you will have a finite number of the strategies this solution should be workable too.
The drawback of this solution is that you won't be able to mix different naming strategies during a single serialization / deserialization run.

Enumerate Java Fields

I have a Java class with ~90 fields. I want to be able to do things to every field (generate an XML element for instance) without writing the same 5 lines of code with slight substitutions 90 times. In Objective C I think you can get to instance variables in ways similar to accessing Dictionary elements (ObjectForKey). Is there anything similar in Java such that I can get an array of the fields then do something to each of them?
Yes, it's called Reflection API.
In particular, MyClass.class.getDeclaredFields() will return a full list of fields declared by this class (see API for details)
Here's another approach: Use the Introspector API with the JDK to obtain bean-like properties of a class. This is helpful if you have getters and setters for your class and do not want to access the private fields directly.
Obtain a BeanInfo via the Introspector and get all the propertyDescriptors from it. To find getter of that property.
I'll have to admit that using this API is a bit cumbersome and reflection (suggested by Nikita Rybak) is more straight forward.
But there's a utility Apache BeanUtils that does all the hardwork internally so working with beans becomes simple.
Add:
If you are using the reflection API, I'd suggest you annotate your bean fields or your getters with a custom annotation.
public class MyClassWith90Fields {
#XmlSerialize("name")
private String screenName; // shoudl serialize as <name>...</name>
#XmlSerialize
private String email; // shoud serialize as <email>...</email>
#XmlSerializeIgnore
pirvate boolean flag; // shoud not serialize as annotated as ignore
}
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.METHOD})
public #annotation XmlSerialize {
public String value;
}
Once done, your generation code can check (using reflection) annotated fields and serialize them to XML appropriately.

How do I prevent JAXB from binding superclass methods of the #XmlRootElement when marshalling?

I have a class that is annotated as the #XmlRootElement with #XmlAccessorType(XmlAccessType.NONE). The problem that I am having is that the superclass's methods are being bound, when I do not want them to be bound, and cannot update the class. I am hoping there is an annotation that I can put on the root element class to prevent this from happening.
Example:
#XmlRootElement
#XmlAccessorType(XmlAccessType.NONE)
public class Person extends NamedObject {
#XmlElement
public String getId() { ... }
}
I would expect that only the methods annotated #XmlElement on Person would be bound and marshalled, but the superclass's methods are all being bound, as well. The resulting XML then has too much information.
How do I prevent the superclass's methods from being bound without having to annotate the superclass, itself?
According to this StackOverflow post:
How can I ignore a superclass?
It is not possible with JAX-B to ignore the superclass without modifying the superclass.
Quoting the relevant portion of that post:
Update2: I found a thread on java.net
for a similar problem. That thread
resulted in an enhancement request,
which was marked as a duplicate of
another issue, which resulted in the
#XmlTransient annotation. The comments
on these bug reports lead me to
believe this is impossible in the
current spec.
Just add
#XmlAccessorType(XmlAccessType.NONE)
in front of EACH superclass declaration (and the class itself).
In your case:
#XmlAccessorType(XmlAccessType.NONE)
class NamedObject{
[ ... ]
}
Remember that this has to be done really for each superclass, it is often
forgotten when dealing with huge class dependency trees.
Interfaces, of course, don't need any JAXB annotations.
I know this question is quite old, but there is a kind of solution which works if your superclass is in the same package as its child.
Create a package-info.java in your package and insert
#XmlAccessorType(XmlAccessType.NONE)
package my.package.with.classes;
Obviously, it sets XmlAccessType.NONE upon all classes in the package. Myself, I use it in every package in our domain model. Therefore, I'm pretty safe. However, if your class is 'out of reach', f.e. it's in the JDK, use the solution from the accepted answer in [JAX-B] How can I ignore a superclass?.
I hope it's helpful for anynone who stumbles upon this question as I did.
I'm facing the exact same problem.
My superclass does not handle any JAXB annotations (it doesn't have to) and I would like my subclass not to include superclass properties while marshalling.
Adding the XmlAccesorType on superclass cannot be the solution as I have no way to modify the superclass.
Is there any other solution?
Replace your JAX-B implementation with MOXy and you can do anything you want. It has a ton of extensions that go above and beyond normal JAX-B, one of which will allow you to ignore inherited properties, etc. It also supports moving JAX-B annotations to an XML mapping file so you can keep multiple sets of mappings.
A solution I have found, but which might not work for you depending on what you want to do, is to override the getters you want to ignore and let them return null. The JAXB specs, and by extension the implementations, ignore fields that contain a null value. Note that if you still need to be able to access the superclass value itself using the subclass, you may need to add a secondary accessor method that is not a getter and adjust your code accordingly.

can BeanUtils.setProperty() set value without setter?

I'm currently taking an example from here to map my ResultSet to custom Object. I've tested BeanUtils.setProperty() and it seems like the object would need setters to work. Is there any way to map values like what Gson does? I don't want to have public setters.
No it can't.
As the name implies the BeanUtils deal with Java Beans
They are serializable, have a zero-argument constructor, and allow access to properties using getter and setter methods.
(Emphasis mine.)
Though the Javadoc of the BeanUtils methods is quite vague clues can also be found in the source code of BeanUtilsBean.setProperty() and PropertyUtilsBean.setSimpleProperty().
See the documentation too:
The Java language provides classes like java.beans.Introspector, which can examine a Java class at runtime and identify for you the names of the property getter and setter methods, [...]. The APIs in the BeanUtils package are intended to simplify getting and setting bean properties dynamically, [...].
(Emphasis mine.)
You can use #Data annoation from Lombok library in the Entities.

Categories