objectmapper only serialize specific fields [duplicate] - java

This question already has answers here:
How do I use a custom Serializer with Jackson?
(11 answers)
Closed 1 year ago.
I want to write a function that only serializes a POJO with given implicit field names.
For example,
class Car{
public int id;
public String type;
public Manufacture manufacture;
}
Class Manufacture{
public int id;
public String name;
}
if I want to serialize a Car object with a given list(i.e. [Car.id, Car.Manufacture.name])
Then I want to get
{
Car:{
id: xxx,
Manufacture: {
name: xxx
}
}
}
Another example, given list = [Car.type]
Then I should get
{
Car:{
type: xxx
}
}
I am currently trying to override the serializeAsField method to check if the field is in the given list, but the problem here is that I don't know the depth, then I cannot correctly compare the current field with the list.
How could I achieve it? Are there any other ways?

Mark the unwanted fields with the #JsonIgnore annotation.
On-the-fly filtering
Here is a Baeldung article that discusses using a filter to
determine which fields are serialized:
https://www.baeldung.com/jackson-serialize-field-custom-criteria
I suspect that is the answer you want.

Related

Deserializing nested JSON with Jackson [duplicate]

This question already has an answer here:
Flattening nested attributes in Jackson
(1 answer)
Closed 2 years ago.
I am trying to deserialize nested JSON into a single DTO in a Spring Boot application.
The JSON:
{"productId": "xyz123",
"description": "some_description",
"value": "123",
"boughtOnDate": "2020-05-20 14:22:58.000662",
"details": {
"material": "some_material",
/// another 20 entries
}
}
The DTO:
#JsonIgnoreProperties(ignoreUnknown = true)
#Entity
public class Item {
#Id
private String productId;
private String description;
private Integer value;
private Timestamp boughtOnDate;
private String material;
// another 20 fields that are in the nested part of the json
// getters & setters
The current solution I have is to unpack nested json in the Item class like so:
#JsonProperty("details")
private void unpackNestedJson(Map<String, Object> details) {
this.material = (String) details.get("material");
// and another 20 lines for unpackacking the rest from the nested part
While unpackNestedJson works fine and does its job, it feels cumbersome as there is a lot of data to unpack from the nested part of the JSON (all entries below and above 'details' from JSON should go as fields into Item entity class only). My question would be - is there a more simple/elegant way of unpacking the nested JSON into a single DTO? Any help appreciated.
No, i think that's the right way to do, but if you want to explore another option, you could have an Details object inside Item with a material property. Then you could just have some getters/setters with the parent DTO delegating to the material property to still achieve the same behavior.

Lombok #Value returns json in lower case [duplicate]

This question already has answers here:
Stop Jackson from changing case of variable names
(3 answers)
Closed 2 years ago.
I have a project in spring and lombok. I have the following class:
import lombok.Value;
#Value
public class Movement {
int xAxis;
int yAxis;
}
This is being returned in a spring response. However I'm expecting it to be returned like this:
"movement": {
"xAxis":1,
"yAxis":2
}
but it comes back like this
"movement": {
"xaxis":1,
"yaxis":2
}
with the fields in lower case. Am I missing something?
Try to use JsonProperty
#Value
public class Movement {
#JsonProperty("xAxis")
int xAxis;
#JsonProperty("yAxis")
int yAxis;
}
#JsonProperty Defines name of the logical property, i.e. JSON object field name to use for the property. If value is empty String (which is the default), will try to use name of the field that is annotated.
Use this annotation as per below :
#JsonProperty("xAxis")
int xAxis;

Will Gson set a field to null when JSON doesn't contain it?

I actually have multiple questions regarding Gson.
The first one being if Gson would set the value of a field to null when the provided JSON does not contain any field matching it.
For example, when the provided JSON features the field name but the class I deserialize it to contains name and avatar, would avatar be null?
The next question is in relation to the above one. When I would set a field with an already predefined value, would Gson override it, even if it isn't provided in the JSON (overrides it to null) or would it simply ignore the field and move on?
And finally would I want to know if Gson would still set a value to name when I would use #SerializedName("username") but the JSON contains name.
I want to update my API, including some bad namings of JSON fields, but I want to make the transition of it for the people using it a smooth as possible, so I want to still (temporary) provide the old field name, while also providing support for the new one. Is that possible using the #SerializedName annotation?
I'm still a beginner with Gson and the Gson User Guide wasn't that helpful for me to answer those two specific questions (Or I overlooked it which would also be possible).
I tried implementing this. Here is my code. I hope the output at the end answers your question.
JSON used:
{
"name": "Robert",
"weather": "19 deg"
}
Main class:
public class GSONExample2 {
private static final String jsonStr = "JSON Mentioned above";
public static void main(String[] args) {
GsonDataExample root = new Gson().fromJson(jsonStr, GsonDataExample.class);
System.out.println(root);
}
}
POJO:
class GsonDataExample {
#SerializedName("username")
private String name;
private String avatar;
#SerializedName(value="weather", alternate = "temperature")
private String weather;
private String nameWithDefault = "Default name";
// getters, setters and toString() implemented
}
Output:
GsonDataExample(name=null, avatar=null, weather=19 deg, nameWithDefault=Default name)
To map multiple keys to same attributes, you can use #SerializedName(value="weather", alternate = "temperature") as shown above.

Jackson in JSON Output: Rename Fields in Multiple Use Cases (without a single JsonProperty)

Is it possible to rename JSON output fields in an object an arbitrary number of times when outputting with Jackson?
I can use a one-time JsonProperty as shown here,
How to map JSON field names to different object field names?
But suppose I have a single class which is used in multiple outputs. In each output, I want to have the flexibility of defining which name(s) to change.
public class Study implements Serializable {
// Can vary as "id" / "studyId" depending on call
private int id;
// Can vary as "description" / "studyDescription" / "studyDesc" depending on call
private String description;
}
Or do I need to create new objects for each case?
Do refer: https://www.baeldung.com/json-multiple-fields-single-java-field
It's as simple as using #JsonAlias in combination with #JsonProperty annotation as below:
public class Study implements Serializable {
// Can vary as "id" / "studyId" depending on call
#JsonProperty("id")
#JsonAlias("studyId")
private int id;
// Can vary as "description" / "studyDescription" / "studyDesc" depending on call
private String description;
}
PS: Using #JsonProperty twice didn't work :D

Sort a data structure in Java [duplicate]

This question already has answers here:
sorting objects in java
(6 answers)
Closed 6 years ago.
I have a data structure in Java which looks like:
class Order {
int id;
String name;
int totalCost;
String address;
List<String> items;
public setter() {
....
}
public getter() {
...
}
}
I have a test class which uses this data structure:
class TestClass {
List<Order> o = getAllOrders();
sortOrders();
}
I want to write a sortOrders method to sort this this data structure based on one of its attributes, in this case the name on the order.
I know to sort in Java we can do:
java.util.Collections.sort(anyArrayListOfStrings);
What is the efficient way to sort the whole data structure in Java?
Well, all you would need is to pass a comparator to the Collections.sort() method. You could do something like this since you want to sort the list of Order objects based on the name field..
Collections.sort(o, new Comparator<Order>() {
public int compare(Order o1, Order o2) {
return o1.name.compareTo(o2.name);
}
});

Categories

Resources