Java到JSON:指定每个转换的哪些字段被排除在外

发布于 2025-01-24 12:22:50 字数 828 浏览 2 评论 0原文

如前所述在这里(与杰克逊一起)

ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(objectToBeConverted);

我知道我可以使用@jsonignore注释将字段排除在JSON字符串中,但是如果我想多次将同一类转换为JSON,但是每次选择不同的领域要忽略?

例如,如果我有一堂课,

class Foo {
    int a;
    int b;
    ...
}

我可以做类似的事情

Foo foo = new Foo();
String json1 = ow.writeValueAsString(foo).excludeField('b');
String json2 = ow.writeValueAsString(foo).excludeField('a');

,以便所产生的字符串看起来像

// json1
{
    a: 1234
}
// json2
{
    b: 5678
}

杰克逊做不到,也许Gson可以吗?还是另一个图书馆?

As mentioned here, I know that I can convert Java objects to JSON (with Jackson)

ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(objectToBeConverted);

I know that I can exclude fields from being included in the JSON string using the @JsonIgnore annotation, but what if I want to convert the same class to JSON multiple times, but each time choosing different fields to ignore?

For example, if I have a class

class Foo {
    int a;
    int b;
    ...
}

can I do something like

Foo foo = new Foo();
String json1 = ow.writeValueAsString(foo).excludeField('b');
String json2 = ow.writeValueAsString(foo).excludeField('a');

so that the resulting strings look like

// json1
{
    a: 1234
}
// json2
{
    b: 5678
}

If Jackson can't do it, maybe Gson can? Or another library?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

知足的幸福 2025-01-31 12:22:50

您可以尝试使用不同的混合接口。我找到了两种方法。

  1. 使用方法来读取属性。然后,您可以创建一个仅定义要排除属性的混合类别:

     公共接口exludea {
        @jsonignore
        int geta();
    }
     
  2. 使用@jsonincludeproperties不知道哪些属性to expude ,而是< em>包括:

      @jsonincludeproperties({“ b”,“ c”})
    公共接口exludea {
    }
     

在这两种情况下,将该混合添加到对象中,映射器:

objectMapper.addMixIn(Foo.class, ExcludeA.class);

虽然有一件非常非常重要的事情 - 您必须为每个混合使用新的ObjectMapper。如果您使用ObjectMapper实例来序列化foo实例而无需混合插入,则添加混合物无济于事。这可能是因为ObjectMapper实例缓存一些东西。

You can try using different mix-in interfaces. I found two ways to do this.

  1. Use methods for reading properties. You can then create a mix-in class that only defines the properties to exclude:

    public interface ExludeA {
        @JsonIgnore
        int getA();
    }
    
  2. Use @JsonIncludeProperties to not tell which properties to exclude, but which properties to include:

    @JsonIncludeProperties({ "b", "c" })
    public interface ExludeA {
    }
    

In both cases, add that mix-in to the object mapper:

objectMapper.addMixIn(Foo.class, ExcludeA.class);

There is one very, very important thing though - you must use a new ObjectMapper for each mix-in. If you use an ObjectMapper instance to serialize a Foo instance without mix-ins, then adding the mix-in won't help. That's probably because ObjectMapper instances cache some stuff.

肥爪爪 2025-01-31 12:22:50

如果您可以将所有原始类型装箱foo,这是一种简单的方法。

例如:int-&gt; Integerboolean-&gt;然后

@JsonInclude(Include.NON_NULL)
class Foo {
    Integer a;
    Integer b;
    ...
}

,只需制作foo的副本,然后将要忽略的属性设置为null

Foo foo = new Foo();
foo.setA(1234);
foo.setB(5678);

Foo foo1 = objectMapper.readValue(objectMapper.writeValueAsString(foo), Foo.class);  // make a copy of Foo
foo1.setB(null);  // force to ignore B
String json1 = ow.writeValueAsString(foo1); // it will be {a:1234}

Here is a simple approach if you could box up all primitive type in Foo.

For example: int -> Integer, boolean -> Boolean

@JsonInclude(Include.NON_NULL)
class Foo {
    Integer a;
    Integer b;
    ...
}

Then, just make a copy of Foo and set the property which you want to ignore to null.

Foo foo = new Foo();
foo.setA(1234);
foo.setB(5678);

Foo foo1 = objectMapper.readValue(objectMapper.writeValueAsString(foo), Foo.class);  // make a copy of Foo
foo1.setB(null);  // force to ignore B
String json1 = ow.writeValueAsString(foo1); // it will be {a:1234}
千柳 2025-01-31 12:22:50

根据您的需要,有多个解决方案:

首先:
您可以为自己的目的定义两个不同的 dto ,每次需要使用它。


第二:
您可以使用@jsoninclude(jsoninclude.include.non_null)属性注释:

class Foo {

    @JsonInclude(JsonInclude.Include.NON_NULL)
    int a;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    int b;
}

ps:您可以在类级上使用此注释,例如:

@JsonInclude(JsonInclude.Include.NON_NULL) 
class Foo {
    int a;
    int b;
}

第三:
使用可以根据不同条件定义过滤器来忽略属性。

为您的过滤器定义一个简单的类:

public class YourConditionalFilter {

    @Override
    public boolean equals(int a) {
        return a == 1234;
    }
}

然后将此过滤器添加为属性顶部的注释:

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = YourConditionalFilter.class)
int a;

There is multiple solution based on your need:

First:
You can just define two different DTO for your purpose and every time you need to each one just use it.


Second:
You can use @JsonInclude(JsonInclude.Include.NON_NULL) annotation for the properties:

class Foo {

    @JsonInclude(JsonInclude.Include.NON_NULL)
    int a;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    int b;
}

P.S: You can use this annotation on class level as:

@JsonInclude(JsonInclude.Include.NON_NULL) 
class Foo {
    int a;
    int b;
}

Third:
Use can define a filter to ignore properties based on different conditions.

Define a simple class for your filter:

public class YourConditionalFilter {

    @Override
    public boolean equals(int a) {
        return a == 1234;
    }
}

And then add this filter as annotation on top of the property:

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = YourConditionalFilter.class)
int a;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文