As it mentioned in comments above, you cant remove fields of compiled class at runtime. Assuming you have to exclude some field from generated json, there I see two options:
- Create a class with fields you want to be present in resulting json, copy required values from original object to a new created. This approach is called view model and allows you to decorate some object's data, hiding sensitive data from being exposed.
- Depending on implementation of your serializer there may be annotations to exclude fields.
@JsonIgnoremay be placed on getter method, if you are using Jackson (default in spring boot). Second aproach requires significant less code, but the first one is more flexible.
apex - Remove field from object list in class - Salesforce Stack Exchange
Spring JSON - Ignore if your POJO field has no corresponding field in said JSON
java - Want to hide some fields of an object that are being mapped to JSON by Jackson - Stack Overflow
json - Dynamically add or remove a member variable of a class - Salesforce Stack Exchange
As it mentioned in comments above, you cant remove fields of compiled class at runtime. Assuming you have to exclude some field from generated json, there I see two options:
- Create a class with fields you want to be present in resulting json, copy required values from original object to a new created. This approach is called view model and allows you to decorate some object's data, hiding sensitive data from being exposed.
- Depending on implementation of your serializer there may be annotations to exclude fields.
@JsonIgnoremay be placed on getter method, if you are using Jackson (default in spring boot). Second aproach requires significant less code, but the first one is more flexible.
Try @JsonIgnore to ignore properties from serialization and de-serialization.
Here is the link to the docs
We have a generic server response that is an absolutely massive JSON, that has dynamic fields.
Aka sometimes an extra fields pops into existance.
I would like to map that object to a single java POJO, and if it doesn't find my field, fuck it, I don't care, null. But don't trow an exception.
@JsonIgnoreProperties(ignoreUnknown = true)
public class RepresentationObject {
@IDK( /* if not found" */ default = "null")
@JsonProperty("Components")
private List<Whatever> nullableWhoCares;
}Or some such
You have two options:
Jackson works on setters-getters of fields. So, you can just remove getter of field which you want to omit in JSON. ( If you don't need getter at other place.)
Or, you can use the
@JsonIgnoreannotation of Jackson on getter method of that field and you see there in no such key-value pair in resulted JSON.@JsonIgnore public int getSecurityCode(){ return securityCode; }
Adding this here because somebody else may search this again in future, like me. This Answer is an extension to the Accepted Answer
You have two options:
Jackson works on setters-getters of fields. So, you can just remove getter of field which you want to omit in JSON. (If you don't need getter at other place.)
Or, you can use the
@JsonIgnoreannotation of Jackson on getter method of that field and you see there in no such key-value pair in resulted JSON.
@JsonIgnore
public int getSecurityCode(){
return securityCode;
}
Actually, newer version of Jackson added READ_ONLY and WRITE_ONLY annotation arguments for JsonProperty. So you could also do something like this.
@JsonProperty(access = Access.WRITE_ONLY)
private String securityCode;
instead of
@JsonIgnore
public int getSecurityCode(){
return securityCode;
}
Not sure I understand your question completely, are you serializing an instance of this class, and do not want the Number_Address__c in the JSON?
If so, look at serialize(objectToSerialize, suppressApexObjectNulls)
Create a below Function -->
public String generateRequest(object requestObj, Boolean suppressNull) {
return System.JSON.serializePretty(requestObj, suppressNull);
}
Notice notice = new Notice ();
//
// Prefill Your notice DTO
//
// requestBody json contain eliminated null value, blank value are not eliminated
String requestBody = generateRequest(notice,true);
You can do like below if you know the schema and heirarchy:
JsonObject jsonObj= gson.fromJson(json, JsonObject.class);
jsonObj.getAsJsonObject("moreDetails").remove("secondName");
System.out.println(jsonObj.getAsString());
refer this for more info Remove key from a Json inside a JsonObject
else you need to write a dynamic function which will check each and every element of JSON object and try to find the secondName element in it and remove it.
So consider here as you have multiple nested objects then you need to write a function which will iterate over each element and check its type if its again a jsonObject call the same method recursively or iteratively to check against current element, in each check you need to also verify that the key, if it matches with the key which has to be removed then you can remove it and continue the same.
for a hint on how to check a value type of JSON see this How to check the type of a value from a JSONObject?
Gson deserializes any valid Json to LinkedTreeMap, like:
LinkedTreeMap<?,?> ltm = new Gson().fromJson(YOUR_JSON, LinkedTreeMap.class);
Then it is just about making some recursive methods to do the clean up:
public void alterEntry(Entry<?, ?> e) {
if(e.getValue() instanceof Map) {
alterMap((Map<?, ?>) e.getValue());
} else {
if(e.getKey().equals("secondName")) { // hard coded but you see the point
e.setValue(null); // we could remove the whole entry from the map
// but it makes thing more complicated. Setting null
// achieves the same.
}
}
}
public void alterMap(Map<?,?> map) {
map.entrySet().forEach(this::alterEntry);
}
Usage:
alterMap(ltm);
map won't work, since it's an intermediate operation, so it won't be executed unless it is followed by some terminal operation.
Use forEach:
Set<FilterEvent> filterEvents = preparation.getFilterEvents();
filterEvents.forEach(f->f.setFilterId(null));
However, if setFilterId expects an int, you can't pass null. You'll have to set it to some other value (0?).
int is a primitive type so if you want to set null then change its data type from int to Integer and
filterEvents.stream().forEach(f->f.setFilterId(null));
or if you don't want to change the data type then set its default value i.e 0 or -1.
Whichever method you use will always iterate through the list to remove your element. The only thing you can do is shorten and prettify your code as much as possible.
Here is a Java 8 one liner:
boolean removed = myList.removeIf(pojo -> pojo.getAccountId().equals(provided));
Don't store the data in a List, store in a java.util.Map instead (keyed by id). The remove() will be a hash lookup.
If you want to maintain order, use LinkedHashMap or TreeMap.