2017-09-07 67 views
0

我使用BeanIO來解析固定寬度的文本文件。例如,文件進入我的項目看起來像下面的固定寬度文本:BeanIO InvalidRecordGroupException給出錯誤的行號

CD DummyValue3 
EF DummyValue4 DummyValue5 DummyValue6 
AB DummyValue1 DummyValue2 
... 

在我的映射文件,我已經公佈各的recordId一個record(即AB,CD,EF)

<record name="dummyRecord" template="AB" 
class="com.company.project.DummyRecordClass" minOccurs="0" 
maxOccurs="1" /> 

我然後讓每個記錄的template

<template name="AB"> 
    <field name="recordID" length="3" rid="true" literal="AB" 
      lenientPadding="true" minOccurs="0" /> 
    <field name="value1" length="12" lenientPadding="true" 
      minOccurs="1" required="true"/> 
    <field name="value2" length="12" lenientPadding="true" 
      minOccurs="1" required="true"/> 
</template> 

因爲value1value2minOccurs = 1作爲以及required="true"(是的,我知道這是多餘的,但它已經在代碼中,我們有成千上萬的這些字段),如果我有一個AB段,它們必須存在。

所以,如果我下面的文件傳遞到我的程序:

CD DummyValue3 
EF DummyValue4 DummyValue5 DummyValue6 
AB DummyValue1 

我收到以下InvalidRecordGroupException:

org.beanio.InvalidRecordGroupException: Invalid 'ediMessage' record group at line 1

然而,由於缺少字段實際上是在第3行,當你有500-600行數據進入應用程序時,這可能是一個完全痛苦的調試。

有沒有什麼辦法讓beanIO輸出正確的行號,或即使必填字段缺少templatefield價值?

回答

1

我通過擴展org.beanio.BeanReaderErrorHandlerSupport創建LoggingErrorHandler使用org.beanio.BeanReaderErrorHandler定製的實行。

import org.beanio.BeanReaderErrorHandlerSupport; 
import org.beanio.BeanReaderException; 
import org.beanio.InvalidRecordException; 
import org.beanio.MalformedRecordException; 
import org.beanio.RecordContext; 
import org.beanio.UnexpectedRecordException; 
import org.beanio.UnidentifiedRecordException; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

/** 
* A BeanIO {@code BeanReaderErrorHandler} that logs the error messages. 
* 
* @author Nico Schlebusch 
*/ 
public class LoggingBeanReaderErrorHandler extends BeanReaderErrorHandlerSupport { 

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingBeanReaderErrorHandler.class); 

    /** 
    * Creates a new instance of {@code LoggingBeanReaderErrorHandler}. 
    */ 
    public LoggingBeanReaderErrorHandler() { 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see org.beanio.BeanReaderErrorHandlerSupport#invalidRecord(org.beanio.InvalidRecordException) 
    */ 
    @Override 
    public void invalidRecord(final InvalidRecordException ex) throws BeanReaderException { 

    LOGGER.error("{}", createErrorMessage(ex)); 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see org.beanio.BeanReaderErrorHandlerSupport#unexpectedRecord(org.beanio.UnexpectedRecordException) 
    */ 
    @Override 
    public void unexpectedRecord(final UnexpectedRecordException ex) throws BeanReaderException { 

    LOGGER.error("{}", createErrorMessage(ex)); 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see org.beanio.BeanReaderErrorHandlerSupport#unidentifiedRecord(org.beanio.UnidentifiedRecordException) 
    */ 
    @Override 
    public void unidentifiedRecord(final UnidentifiedRecordException ex) throws BeanReaderException { 

    LOGGER.error("{}", createErrorMessage(ex)); 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see org.beanio.BeanReaderErrorHandlerSupport#malformedRecord(org.beanio.MalformedRecordException) 
    */ 
    @Override 
    public void malformedRecord(final MalformedRecordException ex) throws BeanReaderException { 

    LOGGER.error("{}", createErrorMessage(ex)); 
    } 

    /** 
    * {@inheritDoc} 
    * 
    * @see org.beanio.BeanReaderErrorHandlerSupport#fatalError(org.beanio.BeanReaderException) 
    */ 
    @Override 
    public void fatalError(final BeanReaderException ex) throws BeanReaderException { 

    LOGGER.error("{}", createErrorMessage(ex)); 
    } 

    /** 
    * Creates an error message using the exception to get the RecordContext from which a meaningful error 
    * message can be constructed. 
    * 
    * @param ex the exception containing the error information. 
    * 
    * @return a string describing the error(s). 
    */ 
    protected String createErrorMessage(final BeanReaderException ex) { 

    final String message = ex.getMessage(); 
    final StringBuilder errorMessage = new StringBuilder(message.length() * 5); 

    // if a bean object is mapped to a record group, 
    // the exception may contain more than one record 
    for (int i = 0, j = ex.getRecordCount(); i < j; i++) { 
     final RecordContext recordContext = ex.getRecordContext(i); 
     final String recordName = recordContext.getRecordName(); 
     final String text = recordContext.getRecordText(); 
     errorMessage.append(String.format("%s: %s%n", message, text)); 

     if (recordContext.hasRecordErrors()) { 
     for (final String error : recordContext.getRecordErrors()) { 
      errorMessage.append(String.format("Record '%s' - %s%n", recordName, error)); 
     } 
     } 
     if (recordContext.hasFieldErrors()) { 
     for (final String field : recordContext.getFieldErrors().keySet()) { 
      for (final String error : recordContext.getFieldErrors(field)) { 
      errorMessage.append(String.format("Field '%s' - %s%n", field, error)); 
      } 
     } 
     } 
    } 

    return errorMessage.toString(); 
    } 

} 

您可以修改createErrorMessage()方法只保留你正在尋找的信息。

當然你可以用這些信息做很多其他的事情,比如寫入文件,發郵件等等。請參閱文檔的BeanReaderErrorHandler部分查找替代方法。

然後,你必須與你的BeanReader實例來註冊錯誤處理程序:

BeanReader beanReader = .... 
beanReader.setErrorHandler(errorHandler); 

哪裏錯誤位於這應該然後輸出的更多信息。