What is the best/preferred way to validate JSON using annotations inside a POJO?
I would like to be able to distinguish between optional and required fields of a POJO.
I would like to be able to provide default values for required fields of a POJO.
Example:
#JsonTypeInfo(use=Id.NAME, include = As.WRAPPER_OBJECT)
#JsonTypeName("Foo")
public class MyClass{
#JsonProperty
private String someOptionalField;
#JsonProperty
private String someRequiredField;
#JsonProperty
private String someRequiredFieldThatIsNotNull;
#JsonProperty
private int someRequiredFieldThatIsGreaterThanZero;
// etc...
}
A possible approach is to deserialize JSON into an object and validate an object with validation API #MattBall linked. The advantage is that this logic is being decoupled from storage logic and you are free to change your storage logic with no need to reimplement validation.
If you want to validate JSON, you might want to have a look at JSON schema.
Related
I have the next task: read XML file from some directory and convert it to JSON string.
The problem: initial XML and JSON have different names for corresponding properties, e.g. x_date in XML and j_date in JSON.
I have created the class with required field for JSON with such annotations:
public class Card {
#JacksonXmlProperty(localName = "x_date")
#JsonProperty("j_date")
private String date;
// other fields
I have tried to serialize/deserialize test XML file, and it's seems work correctly.
But I'm not sure that is ok to annotate fields with #JacksonXmlProperty and #JsonProperty annotations at the same time. Maybe it's better to create one class per XML part and one for the JSON and transfer the data between them some mapper (e.g. Orika)?
Any suggestions?
Finally solved this by splitting logic in two separate classes: Card.class for XML data with help of #JacksonXmlProperty annotation and CardDto.class which uses #JsonProperty. Mapping between these classes is handled by Orika mapper.
This split will ease further customization of both classes and will allow add new functionality (e.g. persist data to the database using new entity class).
I have a spring boot microservices application and within it, I want to do a specific operation (say some string manip) on specific fields of a Java object (or a JSON object).
For example:
class Employee {
private String id;
private String name;
private String someOtherId;
}
If I need to do a specific operation only to id and someOtherId fields, how can go about it? Can there be custom annotations created to handle this?
Something like:
stringAppend(employee) should do this operation to only the specific fields. I don't want to check iteratively inside the function, rather I would do it via configuration.
The object will be a payload from a HTTPRequest and need to do this manipulation specifically to only certain fields.
For manipulating the specific fields of received object in HTTP request payload, you can use Jackson library in Java. Jackson is a very popular and efficient java based library to serialize or map java objects to JSON and vice versa.
In this case from http request body, Employee object will be in serialized formed.
To deserialized it to actual Employee object you can use ObjectMapper from Jackson library as follows :
Assume payloadJson is a string which contains request payload in JSON format.
ObjectMapper objectMapper = new ObjectMapper();
Employee employee = objectMapper.readValue(payloadJson, Employee.class);
After desrialization you can perform manipulation on fields of Employee object using Getters and Setters method.
I have a java class
public class CategoryItem implements Serializable {
private Long id;
private String name;
private Manager manager;
}
In one case,I need to convert all the fields to json.
on the other case,I only need 'id'and 'name'
How can I do?
Give me some tips.Thanks
Annotate your POJO id and name attributes with #JsonProperty and manager with #JsonIgnore
When you want just id and name, use a default ObjectMapper.
When you want all fields, use a custom ObjectMapper per this question/answer.
There are many ways to do this:
set unwanted field to null, and use #JsonInclude(Include.NON_NULL) annotation at class level.
supply SimpleBeanPropertyFilter, while using ObjectMapper and use annotation #JsonFilter(<filter_name>) at class level.
use a custom-serializer.
This may be a simple task, but I couldn't find a way to do it. Basically, I need to disallow some parameters at the time of using #RequestBody annotation in my controller.
Here is my model:
#Data
public class MyModel {
private int id;
private String name;
}
What I want to do is at the time of response, I want both of the properties to be serialized to JSON, but at the time of create or update, I prefer not to receive id as part of #RequestBody deserialization.
Right now, if I pass id in the JSON body, Spring initializes a MyModel object with its id set to the passed value.
Reason? The ID cannot be generated until the model is created, so the app shouldn't allow the ID to be set. On update, the ID needs to be passed in the URL itself e.g. (PUT /mymodels/43). This helps following the REST principles appropriately.
So, is there any way to achieve this functionality?
Update 1:
Right now, I am stuck with using a request wrapper. I created a new class MyModelRequestWrapper with only name as its property, and have used it with the #RequestBody annotation.
How you do this depends on what version of Jackson you are using. It's basically possible by a combination of the annotations #JsonIgnore and #JsonProperty on relevant fields/getters/setters.
Have a look at the answers here: Only using #JsonIgnore during serialization, but not deserialization
I've faced issue to combine JAXB and Jackson annotation together:
public class Document {
String someField;
#JsonIgnore
#XmlElementWrapper(name = "someWrapper")
#XmlElement(name = "someElement")
List<String> someCollection;
}
I need to be able to marshall and unmarshall field 'someCollection' to xml, but to have the opportunity to serialize 'Document' object to json without such field.
But this field appears in final json string
So, if I've understood right - Jackson sees both JsSON and XML annotations. So I can not force to serialize something and do not serialize in the same moment.
It is not possible, I think