Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot @Group注释中的minOccurs属性导致意外的recordException_Spring Boot_Bean Io - Fatal编程技术网

Spring boot @Group注释中的minOccurs属性导致意外的recordException

Spring boot @Group注释中的minOccurs属性导致意外的recordException,spring-boot,bean-io,Spring Boot,Bean Io,我是BeanIO的新手,我试图在文件中有特定记录类型可用时为组的出现配置验证逻辑。例如,如果平面文件中有三条记录,如下所示 560866 670972 57086659 我正在尝试设置以下逻辑 56行和67行一起构成多行记录 56和67条记录可以独立于57条记录而来,但57条记录不能没有56和67 我成功地使用@record annotation中的minOccurs属性创建了第一个验证,但无法使用组对56和67执行相同的验证 请在下面找到示例代码设置 HeaderRecord类保存56和67记

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

560866
670972
57086659

我正在尝试设置以下逻辑

  • 56行和67行一起构成多行记录
  • 56和67条记录可以独立于57条记录而来,但57条记录不能没有56和67
  • 我成功地使用@record annotation中的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;
    }
    
    公共类记录对象{
    @组(集合=List.class,minOccurs=1)
    列出标题记录;
    @记录(集合=List.class)
    列出tx57s;
    }
    @记录(maxLength=10,name=“TX56”)
    公共级TX56{
    @字段(序号=0,at=0,长度=2,rid=true,literal=“56”,trim=true)
    受保护的int-id;
    @字段(序号=1,at=2,长度=4,修剪=true)
    受保护整数;
    }
    @记录(maxLength=31,name=“TX67”)
    公共级TX67{
    @字段(序号=0,at=0,长度=2,rid=true,literal=“67”,trim=true)
    受保护的int-id;
    @字段(序号=1,at=2,长度=4,修剪=true)
    受保护整数;
    }
    @记录(maxLength=71,name=“TX57”)
    公共级TX57{
    @字段(序号=0,at=0,长度=2,rid=true,literal=“57”,trim=true)
    受保护的int-id;
    @字段(序号=1,at=2,长度=4,修剪=true)
    受保护整数;
    }
    
    使用上面的配置,当我试图用下面给出的记录解析文件时,它会抛出意外的RecordException。
    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[dispatcherServlet] 异常[请求处理失败;嵌套异常为 org.beanio.UnexpectedRecordException:已到达流的结尾,应为 记录“tx56”]及其根本原因org.beanio.UnexpectedRecordException:End 已达到的流的个数,在处应为记录“tx56” org.beanio.internal.parser.UnmarshallingContext.newunsatifiedRecordException(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.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.beanreader.internalRead(beanreader.java:106)~[beanio-2.1.0.jar:2.1.0] 在 org.beanio.internal.parser.beanreadrepl.read(beanreadrepl.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应始终作为单个记录出现。
      这也很好
    其他详情: 样本平面文件

    560866
    670972
    560866
    670972
    560866
    670972
    57086659
    57086659
    57086659
    57086659
    52022
    560866
    670972
    57086659

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


    我在下面给出正在工作的maven项目Github URL

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

    我已经将类中的所有字段
    设置为private
    ,并假设您已经准备好了getter+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;
    }
    
    在各个TX记录上,我在记录标识符字段的
    @字段上添加了
    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:使用
    toString()
    方法)

    希望这有帮助


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

    我无法重现您的问题,我遇到了其他错误,我正在努力解决这些错误。我不太了解如何在BeanIO上使用注释。您是否可以向我们展示如何配置
    StreamFactory
    ,然后如何创建
    BeanReader
    ,以从文件中读取数据。很抱歉响应延迟,我正在更新问题。所有其他相关细节。嗨,非常感谢您的回复。我之所以将headerRecord作为列表,是因为在一个集合中可能有多个记录。我有最新消息
    @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;
    }
    
    @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();
        }
      }
    }
    
    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
    ]