BeanIO reference guide states that for a fixed-length stream:
if required is set to false, spaces are unmarshalled to a null field value regardless of the padding character.
So if I understand this sentence correctly, it means that the test below should pass for this pojo:
@Record
public class Pojo {
@Field(length = 5, required = false)
String field;
// constructor, getters, setters
}
The test:
@Test
public void test(){
StreamFactory factory = StreamFactory.newInstance();
factory.define(new StreamBuilder("pojo")
.format("fixedlength")
.addRecord(Pojo.class));
Unmarshaller unmarshaller = factory.createUnmarshaller("pojo");
Pojo pojo = (Pojo) unmarshaller.unmarshal(" "); // 5 spaces
assertNull(pojo.field);
}
But it fails, the 5 spaces are unmarshalled as an empty string. What am I missing? How can I unmarshal spaces to a null String?
In the end, I managed this problem with the use of a type handler based on StringTypeHandler:
@Test
public void test(){
StringTypeHandler nullableStringTypeHandler = new StringTypeHandler();
nullableStringTypeHandler.setNullIfEmpty(true);
nullableStringTypeHandler.setTrim(true);
StreamFactory factory = StreamFactory.newInstance();
factory.define(new StreamBuilder("pojo")
.format("fixedlength")
.addRecord(Pojo.class)
.addTypeHandler(String.class, nullableStringTypeHandler)
);
Unmarshaller unmarshaller = factory.createUnmarshaller("pojo");
Pojo pojo = (Pojo) unmarshaller.unmarshal(" ");
assertNull(pojo.field);
}
Update:
As a user on the beanio-users group suggested, one could also use trim=true, lazy=true
on the @Field
annotation:
@Field(length = 5, trim = true, lazy = true)
String field;