Reputation: 1071
I have this code that runs on Tomee with Jakarta EE 9.1, it is supposed to generate a JSON string taking the data from inputObj
. Problem is that there are fields with null values that are omitted from the resulting JSON even though withNullValues
is set to true. Any ideas what could be wrong?
JsonbConfig config = new JsonbConfig().withNullValues(true);
String json;
try (Jsonb jsonb = JsonbBuilder.create(config)) {
json = jsonb.toJson(inputObj);
}
Upvotes: 0
Views: 1655
Reputation: 20911
After I had read from your following comment, I solved your issue.
No, the only annotation is at the field name level @JsonbProperty("field_name"), and nothing at the class level.
The annotation's default nillable
value is false
. To accomplish your request you need to make it true
as following.
@JsonbProperty(value = "test", nillable = true)
public String your_field_name;
It yields something like {... your other json fields, "test":null}
To begin, I have never used before this post JSON-B API. For you, I have installed it and its dependencies via its official webpage.
I have started a simple console app and created pom.xml
to leverage its Maven dependencies as written on the webpage.
I think your problem is as to the versions either that of its dependencies or directly its own version.
Don't forget to reload project after changing any settings related to Maven.
What my pom.xml
includes is
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>RefUrself</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- ** The rest is for JSON-B API ** -->
<repositories>
<!-- Needed for JSON-B API -->
<repository>
<id>java.net-Public</id>
<name>Maven Java Net Snapshots and Releases</name>
<url>https://maven.java.net/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
</project>
And, when I run its official example which is Dog
class in which I changed name of the dog to null
, it works like a charm.
Dog
class
public class Dog {
public String name;
public int age;
public boolean bitable;
}
The Test
class in which the program begins to run
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
public class Test {
// Create a dog instance
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = null; // --> null as you see
dog.age = 4;
dog.bitable = false;
JsonbConfig config = new JsonbConfig().withNullValues(true);
// Create Jsonb and serialize
try (Jsonb jsonb = JsonbBuilder.create(config)) {
String result = jsonb.toJson(dog);
System.out.println(result);
//{"age":4,"bitable":false,"name":null}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Upvotes: 4
Reputation: 884
I don't know your full code, so this is my guess. If you don't declare getter
method for properties in class, Json-B
skips to serialize fields. Here is my example.
package action.in.blog;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.Test;
public class JsonbTest {
@Test
void test() throws Exception {
JsonbConfig config = new JsonbConfig().withNullValues(true);
Input inputObj = new Input();
try (Jsonb jsonb = JsonbBuilder.create(config)) {
System.out.println(jsonb.toJson(inputObj));
}
}
public static class Input {
private String value;
}
}
{}
package action.in.blog;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.Test;
public class JsonbTest {
@Test
void test() throws Exception {
JsonbConfig config = new JsonbConfig().withNullValues(true);
Input inputObj = new Input();
try (Jsonb jsonb = JsonbBuilder.create(config)) {
System.out.println(jsonb.toJson(inputObj));
}
}
public static class Input {
private String value;
public String getValue() {
return value;
}
}
}
{"value":null}
If you don't use getter method for fields, fields should be public.
package action.in.blog;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.Test;
public class JsonbTest {
@Test
void test() throws Exception {
JsonbConfig config = new JsonbConfig().withNullValues(true);
Input inputObj = new Input();
try (Jsonb jsonb = JsonbBuilder.create(config)) {
System.out.println(jsonb.toJson(inputObj));
}
}
public static class Input {
public String value;
}
}
{"value":null}
I hope this is helpful for you.
Upvotes: 1
Reputation: 1765
Is it possible there are annotations on the fields of inputObj
you are serializing that are overriding the .withNullValues(true)
setting?
Ref: https://jakarta.ee/specifications/jsonb/3.0/jakarta-jsonb-spec-3.0.html#customizing-null-handling
I also found this: https://github.com/jakartaee/jsonb-api/issues/169#issuecomment-525387593
You didn't share the class for inputObj
but it seems to me like the only way this won't work is if there are annotations on the fields in the class overriding the global setting in config
.
Upvotes: 1