I'm using the Simple XML library. Most of my models should be parsed using the #Root(strict = false) and most elements/attributes should be parsed with #Element(required = false). Unfortunately the default value for both annotations is true, but I'd like to avoid manually setting it to false on almost every object and field. Is there a setting somewhere I could use, perhaps as an argument passed to the Persister object? I haven't been able to find a solution so far while reading the documentation.
The SimpleXML library provides a #Default annotation which controls default behavior for all elements and attributes, including whether or not they are required. This allows you to set one annotation on the class and not have to override on a property-by-property basis.
#Default(required=false)
public class YourModelObject {
// your elements and attributes
}
Related
In Java we can use custom annotation to validate the fields but apart from this is there any way we can set the value of variable based upon logic using custom annotation in java or spring boot.
See example below
#CustomAnnotation
private String name;
if setter method set the value to name is "$123See" our custom annotation automatically modify the value to name "see" by remove some characters or based upon our own logic.
This is not possible directly and without a background process. Basically, attribute annotations are performed and populated by class analysis.
#1 way: You create a setter method for private attributes and define annotate on it. So, you have to define (example) #Around AOP to your annotation.
https://www.baeldung.com/spring-aop-annotation
#2 way: You add your annotation to your attribute and you have to analyse it with Java reflection, direct after setting the attribute or before setting it with another logic. https://www.baeldung.com/java-custom-annotation
(You can write private attr. in reflection temporary: Set private field value with reflection)
I use a library that provides an annotation #LibraryAnnotation with a Boolean parameter parameter. The default is set to true by the authors of the library.
Unfortunately, in almost all my use cases, I prefer the annotation with parameter = false. To achieve the desired behavior, I use #LibraryAnnotation(parameter=false) instead of #LibraryAnnotation every time. This is error prone since one easily forgets to set the parameter.
I am wondering if there is a way to simplify things by changing the default value for the parameter of #LibraryAnnotation or by defining a custom annotation that behaves like #LibraryAnnotation(parameter=false), but does not require setting a parameter.
(In this particular case, the library is lombok, but the question could be relevant for parametrized annotations provided by any library. Update: Lombok offers default parameter configuration via a lombok.config file, but I am still interested in a general solution.)
You can define your own annotation and use that instead. Something like:
#LibraryAnnotation(parameter = false)
public #interface MyLibraryAnnotationFalse {
}
I have a RESTapi written using Jersey Framework. Along with it there is a POJO class. Now, my need is how do I make a particular field optional in my POJO so that the api will work regardless of that optional field? I want the API should work in both the cases, i.e
if I give that optional parameter then also,
if I don't give then also it should work.
Java 8's Optional was mainly intended for return values from methods, and not for data properties of Java classes(POJO), as described in Optional in Java SE 8:
Of course, people will do what they want. But we did have a clear
intention when adding this feature, and it was not to be a general
purpose Maybe or Some type, as much as many people would have liked us
to do so. Our intention was to provide a limited mechanism for library
method return types where there needed to be a clear way to represent
"no result", and using null for such was overwhelmingly likely to
cause errors.
The key here is the focus on use as a return type. The class is
definitively not intended for use as a property of a Java Bean.
Witness to this is that Optional does not implement Serializable,
which is generally necessary for widespread use as a property of an
object.
[credits] : https://blog.joda.org/2014/11/optional-in-java-se-8.html
I'm guessing you are referring to the serialisation of fields in your POJO. Since you have not stated which version of jackson you are using, you'll have to use one of these annotations to allow nulls:
Can be used on either class or getter:
#JsonInclude(Include.NON_NULL)
If you are using Jackson <2.x, use this:
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
I've got a set of JAXB generated classes and some of the classes have setter methods which accepts
"Object" as the parameter. For example:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name="Car", propOrder = {
"defaultCar"
}
public class Car {
#XmlElement(name = "DefaultCar")
protected Object defaultcar;
public void setDefaultCar(Object value) {
this.defaultCar = value;
}
After I've created instances of these classes in my code, I call the setter methods passing in the required value. Although the method's parameter is Object, the values are most likely to be strings (I've got no control over how it is defined). However, to keep things consistent, I cast the string to Object so that it matches the method's parameter type. The code looks something like this:
Object value = "Old Banger";
Method method = aCar.getClass().getMethod("setDefaultCar", Object.class);
method.invoke(aCar, value);
When I marshall the Java objects, I get the following within the resulting XML, just in front of the value of the string:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string"
I've read somewhere about mismatching data types between the method's parameter type and what has been passed to it. In my case the method parameter being "Object" but I'm passing in a string to it (although I've cast it to Object). I've also seen this post and it looks similar to my problem:
"xsi:type" and "xmlns:xsi" in generated xml by JAXB
However, it doesn't help me overcome my problem. Is there a way to remove these references to xmlns:xsi and xsi:type?
Thx
JAXB exports xsi:type if your data specifies other type than your model. In your case, you set a string, but the field is Object. So your data has a different type than your model. The behaviour is correct.
How you can fix that. You have align the type of the property with the type of the data. There's quite a number of ways to achieve that:
Make it String, why is it an Object in the first place?
Update: You can use jaxb:javaType binding for that.
Ùse #XmlElementRef/#XmlMixed combo instead.
However, to keep things consistent, I cast the string to Object so
that it matches the method's parameter type.
What do you think happens to the string when you cast it to object? :)
You can always override the property type using the type parameter on the #XmlElement annotation.
#XmlElement(name = "DefaultCar", type=String.class)
protected Object defaultcar;
I had similar problem. I was sending XML with these attributes to some WS that was not able to handle it. I remember that I was using Apache CXF for sending this XML so I ended up with CXF interceptor that handled removal of these attributes.
Sadly, I didn't find a way how to "disable" generation of these attributes directly in JAXB. What you can do (and probably will be the only way to solve it) is that you take your generated XML and process it once again with another (DOM/SAX) API and remove attributes manually. It is definitely not a nice solution but I'm not sure if you find better :-/
I would be happy if anyone gives you a better answer...
1- Is there a way to add a deserializer to a module or an ObjectMapper that gets picked up for deserializing all fields with a specific name or regex pattern? (e.g. all fields that match the .*url.* pattern?
2- Also is it possible to register a deserializer that gets picked up for deserializing all fields that have a value that matches a specific regex pattern? (e.g. http://.+).
3- Alternatively is there an annotation I can use on a class, rather than registering it with an ObjectMapper, that can be used instead of 1 and 2?
For (1) and (2), no.
For 3, you can override specified Serializer or Deserializer to use for a property, with:
public class POJO {
#JsonSerialize(using=MySerializer.class)
public String text;
}
What you can do for (1) is just to register a custom serializer for String.class, and defined it as ContextualSerializer. When its createContextual() method gets called, you can check which property it is used for; if name matches your regex, you can construct alternative String serializer; if not, simple one that just calls JsonGenerator.writeString().
For (2), you would just defined custom String serializer and compare value during serialization, taking appropriate action.
You can register a bean serialization customizer that inspects the properties of beans, applies your regular expression, and installs your custom serializer as appropriate.
To quote Tatu:
The extension point would be to add a BeanSerializerModifier, which
you can do via Module implementation. SimpleModule does not add
convenience method for this, so you need to implement
Module#setupModule(), call 'addBeanSerializerModifier'.
There is a parallel structure for the deserialization side.