当前位置: 首页 > 知识库问答 >
问题:

Jackson可以自动将任何构造函数参数视为JsonProperty吗?

荀博
2023-03-14

如何让Jackson将“name”视为具有@JsonProperty注释?

public class SimpleClass {
    private String name;
    private String doNotSerialize;

    public SimpleClass( @JsonProperty("name") String name ) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    public int getSum() {
        return 1+1;
    }
}

现在,我得到了一个错误,无法识别的字段“sum”,因为它将每个getter都视为可序列化属性。

如果我添加类注释:

@JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE )

序列化时,我得到一个空字符串。我希望Jackson能在构造函数参数上看到@JsonProperty并解决它。

如果我将类注释更改为:

@JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.ANY )

然后我得到了“doNotSerialize”字段。

如果我在构造函数上设置@JsonCreator,并更改自动检测,我仍然会得到一个空白字符串:

@JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY )
public class SimpleClass {
    private String name;
    private String doNotSerialize;

    @JsonCreator
    public SimpleClass( @JsonProperty("name") String name ) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    public int getSum() {
        return 1+1;
    }
}

我希望以某种方式告诉Jackson将所有构造函数参数视为可序列化字段,将所有其他字段/setter视为不可序列化字段。

共有2个答案

谢翰学
2023-03-14

如果希望序列化json中包含“sum”,但在反序列化时要忽略它,可以执行以下操作:

@JsonIgnoreProperties(ignoreUnknown=true)
public class SimpleClass { 
   // properties/getters 

   public int getSum() { return 1+1; }
}

如果您想从json中完全删除“sum”,可以这样做

@JsonIgnoreProperties({"sum"})
public class SimpleClass { 
   // properties/getters 

   public int getSum() { return 1+1;  }
}

public class SimpleClass { 
   // properties/getters 

   @JsonIgnore
   public int getSum() { return 1+1;  }
}
司徒博容
2023-03-14

您可以使用过滤器仅序列化具有匹配字段的getter,例如。

package org.example;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import java.io.IOException;
import java.io.StringWriter;


public class App {
    @JsonFilter("test")
    public static class SimpleClass {
        private String name;
        private String doNotSerialize;

        public SimpleClass(String name ) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public int getSum() {
            return 1+1;
        }
    }
    public static void main( String[] args ) throws IOException {
        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        filterProvider.addFilter("test", new SimpleBeanPropertyFilter() {
            @Override
            protected boolean include(BeanPropertyWriter writer) {
                return super.include(writer);
            }

            @Override
            protected boolean include(PropertyWriter writer) {
                String name = writer.getName();
                Class clazz = writer.getMember().getDeclaringClass();
                try {
                    clazz.getDeclaredField(name);
                    return super.include(writer);
                } catch (NoSuchFieldException e) {
                    // ignore
                    return false;
                }
            }
        });
        ObjectMapper mapper = new ObjectMapper();
        mapper.setFilterProvider(filterProvider);
        StringWriter sw = new StringWriter();
        mapper.createGenerator(sw).writeObject(new SimpleClass("foo"));
        System.out.println(sw.toString());
    }
}

我不知道你的全部要求,但这应该是一个开始。

我并没有试着去做你们实际上问的事情,也就是说,看构造函数参数,但这也应该是可能的。

 类似资料:
  • 我正在尝试使用杰克逊对物体进行去耳廓化 我有一个例外: 我知道这是因为这是我的构造函数: 所以,我的构造函数收到 HttpResponse 参数,我没有传递它,但我不知道该怎么做。我不能用空构造函数过度收费,因为我需要它以这种方式接收 HttpResponse 对象。当我调用 readValue() 方法时,有什么方法可以传递这个构造函数参数吗?或者在这种情况下最好的选择是什么?我感谢您的帮助。问

  • 到目前为止,在gradle中,定义输入或输出的常见方式是使用诸如InputFile之类的注释。 从Kotlin的角度来看,在构造函数中注入所有这些输入/输出值会很好,但我想知道,这可能吗?类似于: ):DefaultTask()

  • 问题内容: 这行得通吗? 我只是想弄清楚构造函数。如果将其称为方法,那么我认为它的工作原理与方法类似。您可以在调用该方法时使用的方法中创建局部变量,因此我不明白为什么在构造函数使用它们之前必须先声明实例变量。 问题答案: 在您的示例中,速度和权重不是实例变量,因为它们的范围仅限于构造函数。您可以在外部声明它们,以使它们在整个类(即整个类的对象)中可见。构造函数的目的是初始化它们。 例如以这种方式:

  • 问题内容: 我所知道的是,编译器在字节码中编写了一个默认的无参数构造函数。但是,如果我们自己编写,则该构造函数会自动调用。这种现象是构造函数压倒一切的吗? 问题答案: 您所描述的不是最重要的。如果您未指定默认构造函数,则编译器将创建一个默认构造函数。如果是子类,它将调用默认的父构造函数(super()),还将所有实例变量初始化为由该类型的默认值确定的默认值(数字类型为0,布尔值为false,对象为

  • 在经历冬眠3时。x文档我知道我们也可以为具有私有可见性的POJO声明一个无arg构造函数,但文档说它有限制: 无参数构造函数是所有持久类的要求;Hibernate必须使用Java反射为您创建对象。构造器可以是私有的,但是在没有字节码插装的情况下,运行时代理生成和有效的数据检索需要包或公共可见性。 我不熟悉Hibernate,我试图了解何时使用运行时代理,何时使用字节码,以及这在Hibernate中

  • 我正在尝试通过:如果流文件; 在我的主()中,到一个名为“FIFO”的类的构造函数:FIFO(文件); 在FIFO(FIFO.h)的头文件中,我有: 在FIFO.cc,我有: 我一直喜欢(还有更多,我只是粘贴其中一个): 在文件包括从/usr/lib/gcc/x86_64-redhat linux/4.4.7/…/…/…/…/包含/c /4.4.7/bits/localefwd.h: 43,从/u