BeanIo 嵌套列表固定长度封送和解封

BeanIo nested list fixedlength marshal and unmarshal

我不明白为什么没有从 BeanIo 清楚地解析嵌套对象。

解析是基于“定长”的,所以是定位的。

提供这些 pojos:

@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; 
}

我做了这个 class 来尝试输入和输出操作来解决问题:

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 参考指南的 Segments 部分。这里复制太多了,但是用一个段来表示一个@Record里面的嵌套对象。要使用这些段,您需要使用 @Segment 注释对 属性 List<Address> 进行注释,并在这种情况下指定集合类型。你的 Employee class 然后变成:

@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);