Spring批处理,记录跳过的记录/行

时间:2014-07-01 11:31:37

标签: java spring batch-processing spring-batch

为了能够记录所有跳过的记录/行(来自Flat文件),我在FieldSet.getValues()实现中将Item(数据模型)链接到FieldSetMapper<T>

此处record是我的数据模型。

public void loadRecord(FieldSet fieldSet){
    record.setFieldSet(fieldSet.getValues());
}

SB在onSkipInRead中提供FlatFileParseException的记录/行。为onSkipInWriteonSkipInProcess提供相同的内容,我提出了上述解决方案。 此外,record不存储平面文件中的所有字段,因此我只能使用数据模型来识别每一行。

  1. 这是一个很好的方法吗?
  2. 还有其他方法吗?
  3. 记录/行是否与存储在任何上下文中的项目相对应?
  4. 感谢您的帮助!

2 个答案:

答案 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);
  }
}