Я не могу понять, почему вложенный объект не анализируется четко из BeanIo.
Разбор основан на «фиксированной длине», поэтому позиционно.
Дайте эти пожо:
@Record(minOccurs=1)
@Data
public class Address {
@Field(length=2)//,at=1)
private String prov;
@Field(length=6)//at=2)
private String city;
}
и
@Record(minOccurs=1)
@Data
public class Employee {
@Field(length=6)//,at=1)
private String firstName;
private List<Address> addresses;
@Field(length=6)//at=2)
private String lastName;
}
Я сделал этот класс, чтобы попытаться выполнить операции ввода и вывода, чтобы устранить проблему:
public class BeanioTest {
public static void main(String[] args) {
Employee emp = new Employee();
emp.setFirstName("Joe");
emp.setLastName("Black");
List<Address> addresses = new ArrayList<>();
Address address1 = new Address();
address1.setCity("PARIS");
addresses.add(address1);
Address address2 = new Address();
address2.setCity("MILAN");
addresses.add(address2);
emp.setAddresses(addresses);
String marshalled = marshaller( emp);
System.out.println(marshalled);
Employee empUnm = unmarshaller(marshalled);
System.out.println(empUnm.toString());
}
public static Employee unmarshaller(String emp) {
StreamFactory factory = StreamFactory.newInstance();
StreamBuilder builder = new StreamBuilder("s1")
.format("fixedlength")
.addRecord(Employee.class)
.addRecord(Address.class);
factory.define(builder);
Unmarshaller unmarshaller = factory.createUnmarshaller("s1");
Employee unmarshalled = (Employee) unmarshaller.unmarshal(emp);
return unmarshalled;
}
public static String marshaller(Employee emp) {
StreamFactory factory = StreamFactory.newInstance();
StreamBuilder builder = new StreamBuilder("Tm")
.format("fixedlength")
.addRecord(Employee.class)
.addRecord(Address.class);
factory.define(builder);
Marshaller marshaller = factory.createMarshaller("Tm");
String marshalled = marshaller.marshal(emp).toString();
return marshalled;
}
}
Но ввод и вывод не будут заботиться о вложенной коллекции, вывод консоли выглядит так:
Joe Black
Employee(firstName=Joe, addresses=null, lastName=Black)
Я пробовал разные попытки, но не могу понять. Пожалуйста, укажите мне правильное направление.
Также см. раздел Сегменты Справочного руководства по BeanIO. Копировать здесь слишком много, но сегмент используется для обозначения вложенных объектов внутри @Record
. Чтобы использовать сегменты, вам нужно аннотировать свойство List<Address>
аннотацией @Segment
и указать тип коллекции в этом случае. Тогда ваш класс Employee
станет:
@Data
@Record(minOccurs = 1)
@SuppressWarnings("javadoc")
public class Employee {
@Field(length = 6)// ,at=1)
private String firstName;
@Segment(collection = List.class)
private List<Address> addresses;
@Field(length = 6)// at=2)
private String lastName;
}
Существуют различные другие атрибуты, которые вы можете настроить для сегмента. Дополнительные параметры см. в документации.
PS: Не является частью проблемы, но у вас, вероятно, есть опечатка в тестовом коде:
Address address2 = new Address();
address1.setCity("MILAN"); // I assume you want MILAN to be the city for address2, not address1
addresses.add(address2);
Да, была опечатка, исправлю. Кстати, большое спасибо, в документации BeanIo четко не нашел.