首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >@Group注释中的minOccurs属性导致UnexpectedRecordException

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

Stack Overflow用户
提问于 2018-07-17 14:05:45
回答 1查看 954关注 0票数 0

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

560866

670972

57086659

我正在尝试设置以下逻辑

  1. 56和67行合在一起形成多行记录。
  2. 56和67记录可以独立于记录57,但是57记录不能没有56和67。

我成功地在@record注释中使用minOccurs属性创建了第一个验证,但无法使用一个组对56&67进行同样的验证。

请查找下面的示例代码设置。

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

代码语言:javascript
运行
复制
@Group
public class HeaderRecord {
    @Record(minOccurs = 1)
    public TX56 tx56;
    @Record(minOccurs = 1)
    public TX67 tx67;
}

RecordObject用于保存标题和行项。

代码语言:javascript
运行
复制
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:07,778 with nio-8080-exec-2 2ERROR org.apache.catalina.core.ContainerBase.Tomcat.localhost./.dispatcherServlet-Servlet.service()for servletdispatcherServletin上下文与path[]抛出的exceptionRequest处理失败;嵌套异常是到达流的org.beanio.UnexpectedRecordException:End,期望记录‘is 56’与到达流的根源org.beanio.UnexpectedRecordException:End,org.beanio.internal.parser.UnmarshallingContext.newUnsatisfiedRecordException(UnmarshallingContext.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的预期记录‘at 56’。parser.RecordCollection.unmarshal(RecordCollection.java:42)~beanio-2.1.0.jar:2.1.0 at org.beanio.internal.parser.Group.unmarshal(Group.java:118)~beanio-2.1.0.jar:2.1.0 at org.beanio.internal.parser.BeanReaderImpl.internalRead(BeanReaderImpl.java:106)~beanio-2.1.0.jar:2.1.0 at org.beanio.internal.parser.BeanReaderImpl.read(BeanReaderImpl.java:67)~beanio-2.1.0.jar:2.1.0在dk.coop.integration.fileconversion.service.sampleapplication.createFixedLengthFile(sampleapplication.java:32)~classes/:?

注意:使用上面的配置,下面的场景可以工作

  • 56和67是独立的 560866 670972
  • 57不能独立来 57086659:此平面文件失败,但有适当的异常。
  • 56&67应该永远是一个单一的记录。 这也很好。

其他详细信息:示例Flatfile

560866

670972

560866

670972

560866

670972

57086659

57086659

57086659

57086659

52022

560866

670972

57086659

如上文所示,在平面文件中,多个头记录和TX57记录可能作为一个单一实体出现。另外,还有其他类型的记录可以介于两者之间,在这种情况下,我必须将TX56、67和57的第二次出现作为一个不同的项目。

在上面的示例中,前10条记录将形成单个recordObject,然后这些记录的第二次出现将形成第二个记录对象。很抱歉之前没有共享,但是还有另一个包装类,它包含一个recordObject列表。

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

EN

回答 1

Stack Overflow用户

发布于 2018-07-17 21:53:47

编辑:2018年8月5日更新了所有需求

我已经在类中创建了所有字段private,并假定getter+setter已经就位。

我在@Group@Record注释上尝试了各种设置组合,所以下面的代码可能不是最优的,但应该可以工作。

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

代码语言:javascript
运行
复制
@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值。

代码语言:javascript
运行
复制
@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记录上,我在记录标识符字段的required=true注释中添加了@Field属性。编辑:添加TX52

代码语言:javascript
运行
复制
@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;
}

最后,我的测试代码:(编辑:更新的测试数据)

代码语言:javascript
运行
复制
@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 = "560866\n670972\n560866\n670972\n560866\n670972";
  final String scenario2 = "560866\n670972\n560866\n670972\n560866\n670972\n57086659\n57086659\n57086659\n" +
  "57086659\n560866\n670972\n57086659\n560866\n670972";
  // invalid
  final String scenario3 = "57086659\n57086659\n57086659\n57086659\n57086659";
  final String scenario4 = "52022\n52066\n52054\n52120";
  final String scenario5 = scenario1;
  final String scenario6 = "560866\n670972\n560866\n670972\n560866\n670972\n57086659\n57086659\n57086659\n" +
  "57086659\n52021\n52022\n52023\n560866\n670972\n57086659\n52023";

  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();
    }
  }
}

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

代码语言:javascript
运行
复制
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
]

希望这能有所帮助。

如果它现在对你有用,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51383474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档