Here is my POJO:
public class Target {
#JsonProperty(value="sizes",required=true)
private Set<Size> Sizes;
#JsonProperty(value="domains",required=true)
private Set<String> Domains;
// getters and setters
}
I initialize this POJO like this:
Target target = new Target(new HashSet<>(), new HashSet<>());
How to get Json from this object with empty fields? I mean smth. like that:
{"sizes":[], "domains":[]}
I tried use ObjectMapper with different parameters, but it was no useful..
Related
I am trying to parse the following nested JSON object using RestTemplate's getForObject method:
"rates":{
"USD":1.075489,
"AUD":1.818178,
"CAD":1.530576,
"PLN":4.536389,
"MXN":25.720674
}
The number of currency rates varies depending on user input (it can be one or more).
How can I map such list of objects or a HashMap to a Java POJO class?
I tried with composition in the rates object:
public class Rates implements Serializable {
private List<ExternalApiQuoteCurrencyRate> list;
// getter and no-args constructor
}
public class ExternalApiQuoteCurrencyRate implements Serializable {
private String currency;
private BigDecimal rate;
// getters and no-args constructor
}
But the rates object gets deserialized as null.
Could somebody please help? Thanks a lot in advance!
Thanks to #Simon and #bhspencer I solved the issue by exporting the JSON object to a HashMap using JsonNode.
Here is the solution:
ResponseEntity<JsonNode> e = restTemplate.getForEntity(API_URL, JsonNode.class);
JsonNode map = e.getBody(); // this is a key-value list of all properties for this object
// but I wish to convert only the "rates" property into a HashMap, which I do below:
ObjectMapper mapper = new ObjectMapper();
Map<String, BigDecimal> exchangeRates = mapper.convertValue(map.get("rates"), new TypeReference<Map<String, BigDecimal>>() {});
I have a class object that contains an interface variable used for callbacks that I don't want serialized into the JSON. I have attempted to use the #JsonIgnoreProperties() annotation to make it ignore the interface variable, but so far no luck. The pre-processor is choking with a IllegalArgumentException Couldn't make a guess for CallbackRun...
The interface looks generally like:
public interface callbackRun {
void runOnFinish();
}
With the broad strokes shape of my class defined as:
#JSONMapper
#JsonIgnoreProperties(ignoreUnknown=true)
public class itemInventory {
public static itemInventory_MapperImpl MAPPER = new itemInventory_MapperImpl();
private static final List<item> itemList = new ArrayList<>();
private callbackRun responseHandler = null;
/ * other variables, getters setters here */
}
What is the best method of getting GWT-jackson-APT to ignore this interface? Or do I have to completely redefine all my objects to remove my callback function references?
You can use #JsonIgnore by annotating the field
#JSONMapper
public class itemInventory {
public static itemInventory_MapperImpl MAPPER = new itemInventory_MapperImpl();
private static final List<item> itemList = new ArrayList<>();
#JsonIgnore
private callbackRun responseHandler = null;
/ * other variables, getters setters here */
}
The field will not be serialized when writing object to JSON and it will be ignored when reading object from JSON. You can always check the generated mappers and you will see a method initIgnoredProperties in the generated deserializer, also the ignored field will not be included in the generated serializer.
I would like to know after the deserialization with Jackson what fields where set by the Json input (even null), so I can than distinguish the null fields than where set on null from the one that where not specified in Json.
This question comes after my previous one about BeanDeserializerModifier.
public class Dto {
public Collection<String> deserializedFields;
// or even better a collection of reflection fields of the object.
}
public MyFooDto extends Dto {
public Integer myField1;
#PossiblySomeJacksonAnnotation (include, exclude, map on other name, special deserializer, etc...)
public SomeDatatype myField2;
}
Example: by deserializing {"myField1": null} I would like to have deserializedFields = ["myField1"], and by deserializing {} I would like to have deserializedFields = [].
I already tried within a custom deserializer and a BeanDeserializerModifier, but still I cant intercept the list of fields inside the Json object (or if I do so it already consumates the JsonParser and it can't be deserialized then).
In the best case I would also get the reflection list of the MyFooDto Fields that have been set...
Do you see how I could proceed?
Thank you Community!
The most straightforward way is to add code in each setter to add the currently set variable name to a List. E.g. :
public class Dto {
public List<String> deserializedFields = new ArrayList<>();
}
and inside MyFooDto setters like:
public void setMyField1(Integer myField1) {
deserializedFields.add("myField1");
this.myField1 = myField1;
}
That's a lot of work if there are hundreds of such setters. An alternative for such a case is to parse JSON into a tree first, traverse it to get JSON property names to add in a collection and then convert the tree to MyFooDto. E.g. (assuming you have a ObjectMapper mapper and json below is a String with your example JSON):
ObjectNode tree = (ObjectNode) mapper.readTree(json);
ArrayNode deserializedFields = mapper.createArrayNode();
tree.fields().forEachRemaining(e -> deserializedFields.add(e.getKey()));
tree.put("deserializedFields", deserializedFields);
MyFooDto dto = mapper.treeToValue(tree, MyFooDto.class);
I have a complex object and for some of the nested objects I need to serialize them into JSON fields instead of JSON objects.
Eg.
public class Outer {
private String someField;
private AnotherClass anotherField;
}
public class AnotherClass {
#XmlElement(name = "useThisName")
private String someField;
private String anotherField;
}
How can I make a custom serializer that will be for the nested object and obey the annotations so the fields are named properly?
My use case for this is to use the ObjectMapper.convertValue() method to create a Map so that I can loop through it and create NameValuePairs for a rest url.
In the end I am hoping to end up with a
Map<String, String>
That I can loop over and create apache BasicNameValuePairs from.
Below is some code I want to use for the end result if I can get everything to serialize properly.
Map<String, String> parameters
= DefaultJacksonMapper.getDefaultJacksonMapper().convertValue(obj, LinkedHashMap.class);
return parameters
.entrySet()
.stream()
.map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
If I convert this to a map now my output is like:
"someField" -> "data"
"anotherField" -> "size = 2"
I am trying to get the Map to have the following output which I feel like I need a custom serializer.
"someField" -> "data"
"useThisName" -> "data"
"anotherField" -> "data"
Ok I figured this out.
I ended up creating a new Module that inherited off of SimpleModule. Then I created a new Abstract class like
public abstract class OuterMixin {
#JsonUnwrapped
private AnotherClass anotherField;
}
I also had to annotate the AnotherClass with JsonProperty Like:
public class AnotherClass {
#XmlElement(name = "useThisName")
#JsonProperty("useThisName")
private String someField;
private String anotherField;
}
The when I got my Object Mapper I just registered my module with it and did the conversion and it all worked out.
As a side note I have another property that I had to write a custom serializer for and the #JsonUnwrapped did not work with that.
I'm calling a rest service that returns a json object. I'm trying to deserialize the responses to my Java Beans using Jackson and data-binding.
The example Json is something like this:
{
detail1: { property1:value1, property2:value2},
detail2: { property1:value1, property2:value2},
otherObject: {prop3:value1, prop4:[val1, val2, val3]}
}
Essentially, detail1 and detail2 are of the same structure, and thus can be represented by a single class type, whereas OtherObject is of another type.
Currently, I've set up my classes as follows (this is the structure I would prefer):
class ServiceResponse {
private Map<String, Detail> detailMap;
private OtherObject otherObject;
// getters and setters
}
class Detail {
private String property1;
private String property2;
// getters and setters
}
class OtherObject {
private String prop3;
private List<String> prop4;
// getters and setters
}
Then, just do:
String response = <call service and get json response>
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(response, ServiceResponse.class)
The problem is I'm getting lost reading through the documentation about how to configure the mappings and annotations correctly to get the structure that I want. I'd like detail1, detail2 to create Detail classes, and otherObject to create an OtherObject class.
However, I also want the detail classes to be stored in a map, so that they can be easily distinguished and retrieved, and also the fact that the service in in the future will return detail3, detail4, etc. (i.e., the Map in ServiceResponse would look like
"{detail1:Detail object, detail2:Detail object, ...}).
How should these classes be annotated? Or, perhaps there's a better way to structure my classes to fit this JSON model? Appreciate any help.
Simply use #JsonAnySetter on a 2-args method in ServiceResponse, like so:
#JsonAnySetter
public void anySet(String key, Detail value) {
detailMap.put(key, value);
}
Mind you that you can only have one "property" with #JsonAnySetter as it's a fallback for unknown properties. Note that the javadocs of JsonAnySetter is incorrect, as it states that it should be applied to 1-arg methods; you can always open a minor bug in Jackson ;)