微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JAVA YAML 读/写数据结构中的变量子集

如何解决JAVA YAML 读/写数据结构中的变量子集

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

以下是我一直在编写的一些测试代码

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)。

这是预期的行为,因为 yaml 不包含内部类中的所有变量。

总而言之,yaml 是否可以处理“反序列化”/丢失的数据,或者是否需要编写包含我的 YAML 公共数据的子类,该子类在我的主数据结构中调用 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 属性。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。