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
属性。
我正在编写一个 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
属性。