JAVA YAML read/write 数据结构中的变量子集

JAVA YAML read/write subset of variables in data structure

我正在编写一个 JAVA 程序,将数据结构中的数据备份到 YAML 文件中。但是,此数据结构省略了用户 read/write 访问的受保护数据。有没有办法设置自定义数据类型或将 Jackson yaml 库标记为仅 read/write 数据结构中的某些变量?

下面是我一直在做的一些测试代码。

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
package swt;

public class swm{   
   
    static class dataStructInner{
        int  accessible;
        int forbidden;   //ignore reads/writes to this variable in YAML i/o
        public dataStructInner(int accessible, int forbidden) {
            this.accessible = accessible;
            this.forbidden = forbidden;
        }
        public dataStructInner(int accessible) {
            this.accessible = accessible;
            this.forbidden = this.forbidden;
        }
        public dataStructInner() {
            this.accessible = 0;
            this.forbidden = this.forbidden;
        }
        @Override
        public String toString() {
            return "dataStructInner{" + "accessible=" + accessible + ", forbidden=" + forbidden + '}';
        }
        
    }
    static class dataArray{          //
        int  accessible;
        private int  forbidden;     //ignore reads/writes to this variable in YAML i/o
        dataStructInner nested;

        public dataArray(int accessible, int forbidden, dataStructInner E) {
            this.accessible = accessible;
            this.forbidden = forbidden;
            this.nested = E;
        }
        public dataArray(int accessible, dataStructInner E) {
            this.accessible = accessible;
            this.forbidden = this.forbidden;
            this.nested = E;
        }
        @Override
        public String toString() {
            return "dataArray{" + "accessible=" + accessible + ", forbidden=" + forbidden + ", nested=" + nested.toString() + '}';
        }
        public dataArray() {
            this.accessible = 0;
            this.forbidden = this.forbidden;
        }
        
    }
    static class JSONExample{
        String header;
        dataArray[] data;
        String footer;
        public JSONExample(String header, dataArray[] data, String closing) {
            this.header = header;
            this.data = data;
            this.footer = closing;
        }
        public JSONExample() {
            this.header = "default header";
            this.data = null;
            this.footer = "default footer";
        }
        @Override
        public String toString() {
            String getArraydata = data[0].toString() + data[1].toString();
            return "JSONExample{" + "header=" + header + "\n, data=" + getArraydata + "\nfooter=" + footer + '}';
        }
    }

    public static void main(String[] args) throws FileNotFoundException, IOException, Exception{
        ObjectMapper om;
        om = new ObjectMapper(new YAMLFactory());
        om.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
        
        File txYamlWrite = new File(System.getProperty("user.dir") + File.separator + "YAMLWriteTest");
        File txYamlRead = new File(System.getProperty("user.dir") + File.separator + "YAMLReadTest");
        File txYamlWriteFinal = new File(System.getProperty("user.dir") + File.separator + "YAMLWriteTestFinal");

        dataStructInner inner0, inner1;
        inner0 = new dataStructInner(0x00, 0xCD);
        inner1 = new dataStructInner(0x01, 0xFF);
        dataArray [] data;
        data = new dataArray[2];
        data[0] = new dataArray(0x00, 0xAB, inner0);
        data[1] = new dataArray(0x01, 0xEF, inner1);
        JSONExample exampleObj;
        exampleObj = new JSONExample("header", data, "footer");
        
//write populated data to YAML formatted file
        String yamlString = null;
        try {
            yamlString = om.writeValueAsString(exampleObj);
        } catch (JsonProcessingException e){
            e.printStackTrace();
        }
        System.out.println(yamlString);
        FileWriter writer = new FileWriter(txYamlWrite);
        writer.write(yamlString);
        writer.close();
        
//read in new data from a YAML file which omits the unwanted data members
//This naturally generates an InvalidDefinitionException as some data was omitted.
        try {
            exampleObj = om.readValue(txYamlRead, JSONExample.class);
            yamlString = om.writeValueAsString(exampleObj);
        } catch (IOException e){
            e.printStackTrace();
        }
//write changes out to verify
        writer = new FileWriter(txYamlWriteFinal);
        writer.write(yamlString);
        writer.close();
//echo result
        System.out.println(exampleObj.toString());
      
    }

这是YAMLWriteTest的内容

header: "header"
data:
- accessible: 0
  forbidden: 171
  nested:
    accessible: 0
    forbidden: 205
- accessible: 1
  forbidden: 239
  nested:
    accessible: 1
    forbidden: 255
footer: "footer"

这是 YAMLReadTest 的输入

header: "new header"
data:
- accessible: 10
  nested:
    accessible: 20
- accessible: 30
  nested:
    accessible: 40
footer: "new footer"

运行 此代码生成异常:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造 swt.swm$JSONExample 的实例(不存在 Creator,如默认构造函数):无法从对象值反序列化(无委托- 或 属性-based Creator).

这是预期的行为,因为 yaml 不包含内部 类.

中的所有变量

总结一下,yaml 是否可以处理“反序列化”/丢失的数据,或者是否有必要编写一个包含我的 YAML public 数据的子类,它在我的主程序中调用 setter 和 getter数据结构?

为了在反序列化时使用构造函数,需要在参数上注解@JsonProperty,以便为反序列化器命名参数。

public dataStructInner(@JsonProperty("accessible") int accessible,
                       @JsonProperty("forbidden") int forbidden) {
public dataArray(@JsonProperty("accessible") int accessible,
                 @JsonProperty("forbidden") int forbidden,
                 @JsonProperty("nested") dataStructInner E) {
public JSONExample(@JsonProperty("header") String header,
                   @JsonProperty("data") dataArray[] data,
                   @JsonProperty("footer") String closing) {

如果不希望序列化写出forbidden属性,可以用@JsonIgnore.

注释字段
@JsonIgnore
int  forbidden;   //ignore reads/writes to this variable in YAML i/o

缺失值使用默认值反序列化,即 0 用于 int 属性。