@Group注释中的minOccurs属性导致UnexpectedRecordException



我是Bean IO的新手,当文件中有特定的记录类型时,我试图为组的出现配置验证逻辑。例如,如果平面文件中有三条记录,如下所示。

560866
670972
57086659

我正在尝试设置以下逻辑

  1. 56行和67行一起形成多行记录
  2. 56&67个记录可以独立于记录57而来,但57个记录不能没有56&67

我成功地使用@record注释中的minOccurs属性创建了第一个验证,但对于56&67使用一组。

请在下面找到示例代码设置。

HeaderRecord类保存56&67记录详细信息

@Group
public class HeaderRecord {
@Record(minOccurs = 1)
public TX56 tx56;
@Record(minOccurs = 1)
public TX67 tx67;
}

RecordObject用于保存标题和行项目

public class RecordObject {
@Group(collection = List.class, minOccurs = 1)
List<HeaderRecord> headerRecords;
@Record(collection = List.class)
List<TX57> tx57s;
}
@Record(maxLength = 10, name = "TX56")
public class TX56 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "56", trim = true)
protected int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true)
protected int number;
}
@Record(maxLength = 31, name = "TX67")
public class TX67 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "67", trim = true)
protected int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true)
protected int number;
}
@Record(maxLength = 71, name = "TX57")
public class TX57 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "57", trim = true)
protected int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true)
protected int number;
}

使用上面的配置,当我尝试用下面给出的记录解析文件时,它会抛出UnexpectedRecordException
560866
670972
57086659

堆栈跟踪:

2018-07-17 15:22:07778[http-nio-8080-exec-2]错误org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]-Servlet.service((抛出路径为[]的上下文中的servlet[dispatcherServletexception[请求处理失败;嵌套异常为org.beanio.出乎意料的RecordException:到达流的末尾,应为record'tx56'],根本原因为org.beanio。意外RecordException:结束已达到个流,预期记录为"x56"org.beanio.internal.parser.UnmarshallingContext.newUnmarshalingContext.java:367(~[beanio-2.1.0.jar:2.1.0]在org.beanio.internal.parser.Group.unmarshal(Group.java:127(~[beanio-1.0.jar:2.1.0]在org.beanio.internal.parser.DelegatingParser.unmarshal(DelegatingParser.java:39(~[beanio-2.1.0.jar:2.1.0]在org.beanio.internal.parser.RecordCollection.unmarshal(RecordCollection.java:42(~[beanio-2.1.0.jar:2.1.0]在org.beanio.internal.parser.Group.unmarshal(Group.java:118(~[beanio-2.1.0.jar:2.1.0]在org.beanio.internal.parser.BeanReaderImpl.internalRead(BeanReaderImpl.java:106(~[beanio-2.1.0.jar:2.1.0]在org.beanio.internal.parser.BeanReaderImpl.read(BeanReaderImpl.java:67(~[beanio-2.1.0.jar:2.1.0]在dk.cop.integration.fileconversion.service.sampleapplication.createFixedLengthFile(sampleapplication.java:32(~[classes/:?]

注意:有了上述配置,以下场景可以实现

  • 56&67独立提供
    560866
    670972
  • 57不能独立出现
    57086659:此平面文件失败,并出现适当的异常
  • 56&67应该永远是一个单一的记录
    这也很好用

其他详细信息:Flatfile 示例

560866

如上所述,在平面文件中,存在多个头记录和TX57记录可以作为单个实体出现的可能性。也可能有其他类型的记录介于两者之间,在这种情况下,我必须将TX56、67和57的第二次出现视为不同的项目
在上面的例子中,前10条记录将形成一个recordObject,然后这些记录的第二次出现将形成第二个记录对象。很抱歉之前没有共享,但还有另一个包装类包含recordObject的列表。

我在下面给出了正在工作的maven项目Github的URL。https://github.com/Jayadeep2308/FlatFileParser

编辑:在2018年8月5日所有要求之后更新

我已经在类中创建了所有字段private,并假设您已经准备好了getters+setter。

我在@Group@Record注释上尝试了各种设置组合,因此下面的代码可能不是最佳的,但应该可以使用。

首先是保存所有数据的主组(WrapperObject(:

@Group(minOccurs = 1, maxOccurs = 1)
public class WrapperObject {
@Group(minOccurs = 0, maxOccurs = 1, collection = List.class)
private List<RecordObject> recordObjectList;
@Record(minOccurs = 0, maxOccurs = -1, collection = List.class)
private List<TX52> tx52s;
}

编辑:更新了RecordObject以保存HeaderRecord的列表,还更改了@Group的值。

@Group(minOccurs = 0, maxOccurs = -1)
public class RecordObject {
@Group(minOccurs = 0, maxOccurs = -1, collection = List.class)
private List<HeaderRecord> headerRecords;
@Record(minOccurs = 0, maxOccurs = -1, collection = List.class)
private List<TX57> tx57s;
}
@Group(minOccurs = 0, maxOccurs = -1)
public class HeaderRecord {
@Record(minOccurs = 1, maxOccurs = 1)
private TX56 tx56;
@Record(minOccurs = 1, maxOccurs = 1)
private TX67 tx67;
}

在各个TX记录上,我在记录标识符字段的@Field注释上添加了required=true属性。编辑:添加TX52

@Record(maxLength = 74, name = "TX52")
public class TX52 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "52", trim = true, required = true)
private int id;
@Field(ordinal = 1, at = 2, length = 3, trim = true)
private int number;
}
@Record(maxLength = 10, name = "TX56")
public class TX56 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "56", trim = true, required = true)
private int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true, required = true)
private int number;
}
@Record(maxLength = 31, name = "TX67")
public class TX67 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "67", trim = true, required = true)
private int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true)
private int number;
}
@Record(maxLength = 71, name = "TX57")
public class TX57 {
@Field(ordinal = 0, at = 0, length = 2, rid = true, literal = "57", trim = true, required = true)
private int id;
@Field(ordinal = 1, at = 2, length = 4, trim = true)
private int number;
}

最后,我的测试代码:(EDIT:更新的测试数据(

@Test
public void test() {
final StreamFactory factory = StreamFactory.newInstance();
final StreamBuilder builder = new StreamBuilder("Jaydeep23")
.format("fixedlength")
.parser(new FixedLengthParserBuilder())
.addGroup(WrapperObject.class);
factory.define(builder);
final String scenario1 = "560866n670972n560866n670972n560866n670972";
final String scenario2 = "560866n670972n560866n670972n560866n670972n57086659n57086659n57086659n" +
"57086659n560866n670972n57086659n560866n670972";
// invalid
final String scenario3 = "57086659n57086659n57086659n57086659n57086659";
final String scenario4 = "52022n52066n52054n52120";
final String scenario5 = scenario1;
final String scenario6 = "560866n670972n560866n670972n560866n670972n57086659n57086659n57086659n" +
"57086659n52021n52022n52023n560866n670972n57086659n52023";
final String message = scenario1;
BeanReader beanReader = null;
Object object = null;
try (final Reader in = new BufferedReader(new StringReader(message))) {
beanReader = factory.createReader("Jaydeep23", in);
beanReader.setErrorHandler(new LoggingBeanReaderErrorHandler());
while ((object = beanReader.read()) != null) {
System.out.println("Object = " + object);
}
} catch (final Exception e) {
fail(e.getMessage());
} finally {
if (beanReader != null) {
beanReader.close();
}
}
}

生成此输出:(EDIT:使用toString()方法(

Scenario 1 = [[Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
]null]null
Scenario 2 = [[Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
][Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
]]null
Scenario 3 - gives this error (which is correct according as TX57 is not allowed on its own:
Expected record/group 'tx56' at line 6
Scenario 4 = null[Record Type = 52, Store Number = 22
, Record Type = 52, Store Number = 66
, Record Type = 52, Store Number = 54
, Record Type = 52, Store Number = 120
]
Scenario 5 = [[Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
]null]null
Scenario 6 = [[Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
, Record Type = 56, Store Number = 866
Record Type = 67, Store Number = 972
][Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
, Record Type = 57, Store Number = 866
]][Record Type = 52, Store Number = 21
, Record Type = 52, Store Number = 22
, Record Type = 52, Store Number = 23
]

希望这能有所帮助。

让我知道它现在是否对你有效。

相关内容

  • 没有找到相关文章

最新更新