为了能够记录所有跳过的记录/行(来自Flat文件),我在FieldSet.getValues()
实现中将Item(数据模型)链接到FieldSetMapper<T>
。
此处record
是我的数据模型。
public void loadRecord(FieldSet fieldSet){
record.setFieldSet(fieldSet.getValues());
}
SB在onSkipInRead
中提供FlatFileParseException
的记录/行。为onSkipInWrite
和onSkipInProcess
提供相同的内容,我提出了上述解决方案。
此外,record
不存储平面文件中的所有字段,因此我只能使用数据模型来识别每一行。
感谢您的帮助!
答案 0 :(得分:1)
现在我更了解你的问题了:)
使用自定义FieldSet
将整行保存到您的域对象而不是LineMapper
。来自LineMapper
javadoc:
将行(字符串)映射到通常使用的域对象的接口 以每行为基础将从文件读取的行映射到域对象。 此接口的实现执行解析a的实际工作 线,而不必处理如何获得线。
因此,委托代表很容易解决您的问题:
class StoreLineLineMapper implements LineMapper<DomainObject> {
private LineMapper<DomainObject> delegate;
public DomainObject mapLine(java.lang.String line, int lineNumber) throws java.lang.Exception {
DomainObject record = delegate.mapLine(line, lineNumber);
record.setLineInfo(new LineInfo(line, lineNumber));
return record;
}
}
答案 1 :(得分:0)
此用例的完整代码:
public class UserMapper implements FieldSetMapper<User> {
@Override
public User mapFieldSet(FieldSet fieldSet) throws BindException {
User user = new User();
String ped = fieldSet.readString("Position effective date");
user.setId(fieldSet.readInt("User ID"));
user.setFn(fieldSet.readString("First Name"));
user.loadRecord(fieldSet); // store fieldSet for regenerating line in future
return user;
}
}
这将从fieldSet重新生成一行(Delimiter是TAB):
class User{
@Override
public String toString() {
return StringUtils.arrayToDelimitedString(fieldSet,
DelimitedLineTokenizer.DELIMITER_TAB);
}
}
在SkipListener中记录行,如下所示:
class SkipListener {
public static final Logger logger = LoggerFactory.getLogger(SkipListener.class);
@OnSkipInWrite
public void onSkipInWrite(Object item, Throwable t) {
onSkip(item);
}
@OnSkipInRead
public void onSkipInRead(Throwable t) {
if (t instanceof FlatFileParseException) {
FlatFileParseException ffpe = (FlatFileParseException) t;
onSkip(ffpe.getInput());
}
}
@OnSkipInProcess
public void onSkipInProcess(Object item, Throwable t) {
onSkip(item);
}
public void onSkip(Object item) {
logger.info(item);
}
}