java Jakarta JSON排除空字段,即使withNullValues设置为true

mv1qrgav  于 2023-04-10  发布在  Java
关注(0)|答案(3)|浏览(121)

bounty还有6天到期。回答此问题可获得+150声望奖励。ps0604希望引起更多关注此问题。

我有这段代码,运行在Tomee与雅加达EE 9.1,它应该生成一个JSON字符串从inputObj的数据。问题是,有空值的字段被省略,从结果JSON,即使withNullValues设置为true。任何想法可能是错误的?

JsonbConfig config = new JsonbConfig().withNullValues(true);
                    
String json;
try (Jsonb jsonb = JsonbBuilder.create(config)) {
    json = jsonb.toJson(inputObj);
}
z18hc3ub

z18hc3ub1#

我不知道你的完整代码,所以这是我的猜测。如果你没有在类中为属性声明getter方法,Json-B会跳过序列化字段。下面是我的例子。

没有Getter
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;
    }
}
没有getter时的结果
{}
使用Getter
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;
        }
    }
}
使用getter时的结果
{"value":null}
带public关键字

如果你不对字段使用getter方法,那么字段应该是公共的。

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;
    }
}
使用public时的结果
{"value":null}

我希望这对你有帮助。

pepwfjgg

pepwfjgg2#

是否有可能在您正在序列化的inputObj的字段上存在注解,这些注解覆盖了.withNullValues(true)设置?
参考:https://jakarta.ee/specifications/jsonb/3.0/jakarta-jsonb-spec-3.0.html#customizing-null-handling
我还发现了这个:https://github.com/jakartaee/jsonb-api/issues/169#issuecomment-525387593
您没有共享inputObj的类,但在我看来,唯一不起作用的方式是类中的字段上有注解,覆盖了config中的全局设置。

z2acfund

z2acfund3#

tl;dr;已解决。

在我读了你下面的评论后,我解决了你的问题。
不,唯一的注解是在字段名称级别@JsonbProperty(“field_name”),而在类级别没有任何注解。
注解的默认值nillablefalse。要完成您的请求,您需要将其设置为true,如下所示。

@JsonbProperty(value = "test", nillable = true)
public String your_field_name;

它产生类似于{... your other json fields, "test":null}的结果
开始,我在这篇文章之前从未使用过JSON-B API。为了你,我已经通过its official webpage安装了它及其依赖项。
我已经启动了一个简单的控制台应用程序,并创建了pom.xml来利用网页上编写的Maven依赖项。

  • 我认为你的问题是关于它的依赖关系的版本,或者直接是它自己的版本。
    在更改与Maven相关的任何设置后,不要忘记 reload project

我的pom.xml包含的是

<?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>

而且,当我运行它的官方示例Dog类时,我将狗的名字改为null,它工作起来很有魅力。
Dog

public class Dog {
    public String name;
    public int age;
    public boolean bitable;
}

程序开始运行的Test

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);
        }
    }
}

相关问题