如何解决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 举报,一经查实,本站将立刻删除。