Reputation: 113
I have a @RestController that returns net.sf.json.JSONObject:
@PostMapping("/list")
public JSONObject listStuff(HttpServletRequest inRequest, HttpServletResponse inResponse) {
JSONObject json = new JSONObject();
...
return json;
}
When JSONObject contains null reference, the following exception is thrown:
Could not write JSON: Object is null; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Object is null (through reference chain: net.sf.json.JSONObject[\"list\"]->net.sf.json.JSONArray[0]->net.sf.json.JSONObject[\"object\"]->net.sf.json.JSONNull[\"empty\"])"
This is the legacy code that we are now cleaning up and at some point we will get rid of explicit JSON manipulations, but this will be a huge change, for now I would like to just get rid of the exception. I tried with following solutions:
Include.NON_NULL
in Spring's Object Mapper - so this piece of code in my WebMvcConfigurationSupportClass
:@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
{
ObjectMapper webObjectMapper = objectMapper.copy();
webObjectMapper.setSerializationInclusion(Include.NON_NULL);
converters.add(new MappingJackson2HttpMessageConverter(webObjectMapper));
}
spring.jackson.default-property-inclusion=non_null
com.fasterxml.jackson
- the only found in the dependency tree is 2.9.7.None of the above helped.
Any suggestions on how to tell Spring to ignore null values in net.sf.json.JSONObjects?
Upvotes: 3
Views: 3807
Reputation: 113
This is not the ideal solution, but rather a workaround. As overriding default mapper/converter behavior didn't work, instead I changed the structure of my JSONObject, so added following line during its generation:
listElt.put("object", "");
which produces:
{
"list" : [ {
"object" : ""
} ]
}
This is fine only if I am not interested in the value of this field - and I am not. I personally prefer @Michał Ziober's solution - it is elegant and generic. Unfortunately doesn't work for me.
Upvotes: 0
Reputation: 38700
Include.NON_NULL
does not work because JSONNull
represents null
but it is not null
per se. From documentation:
JSONNull is equivalent to the value that JavaScript calls null, whilst Java's null is equivalent to the value that JavaScript calls undefined.
This object is implemented as a Singleton
which has two methods: isArray
and isEmpty
where isEmpty
is problematic because throws exception. Below snippet shows it's implementation:
public boolean isEmpty() {
throw new JSONException("Object is null");
}
The best way is to define NullSerializer
for JSONNull
type. Below example shows how we can configure that:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.NullSerializer;
import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;
public class JsonApp {
public static void main(String[] args) throws Exception {
SimpleModule netSfJsonModule = new SimpleModule("net.sf.json");
netSfJsonModule.addSerializer(JSONNull.class, NullSerializer.instance);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(netSfJsonModule);
JSONObject object = new JSONObject();
object.accumulate("object", JSONNull.getInstance());
JSONArray jsonArray = new JSONArray();
jsonArray.add(object);
JSONObject json = new JSONObject();
json.accumulate("list", jsonArray);
System.out.println(mapper.writeValueAsString(json));
}
}
Above code prints:
{
"list" : [ {
"object" : null
} ]
}
See also:
Upvotes: 2