2017-06-17 7 views
1

Iteratorおよびカスタムヘッダ情報を返すことができるメッセージスプリッタを実装することは可能ですか?私は次のクラスにSpring統合:ヘッダーが豊富なカスタムスプリッター

public class CsvFileToIteratorSplitter extends AbstractMessageSplitter { 

    @Override 
    protected Object splitMessage(Message<?> message) { 
     Object payload = message.getPayload(); 
     Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload"); 

     try { 
      InputStream source = new FileInputStream((File) payload); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(source)); 

      String header = reader.lines().findFirst().orElse(null); 

      return MessageBuilder.withPayload(reader.lines().iterator()) 
        .setHeaderIfAbsent("HEADER", header) 
        .build(); 

     } catch (IOException e) { 
      throw new UncheckedIOException(e); 
     } 
    } 
} 

を持っている場合、例えば

は、それから私は、ヘッダに追加することができますが、ペイロードは、実際にIteratorのインスタンスであり、私はクラスのように変更した場合は分割が

を失敗しました今すぐです

public class CsvFileToIteratorSplitter extends AbstractMessageSplitter { 

    @Override 
    protected Object splitMessage(Message<?> message) { 
     log.debug("{}", message.toString()); 

     Object payload = message.getPayload(); 
     Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload"); 

     try { 
      InputStream source = new FileInputStream((File) payload); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(source)); 

      return reader.lines().iterator(); 

     } catch (IOException e) { 
      throw new UncheckedIOException(e); 
     } 
    } 
} 

分割は機能しますが、ヘッダー情報は失われます。

機能を分割してヘッダに追加する方法はありますか?

答えて

1

あなたは、最初の行がすでにリーダーから消費されているので、あなたのskip(1)が、正しくないことIterator<MessageBuilder<String>> ...

@SpringBootApplication 
public class So44604817Application { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(So44604817Application.class, args); 
     context.getBean("in", MessageChannel.class).send(new GenericMessage<>(new File("/tmp/foo.txt"))); 
     context.close(); 
    } 

    @Bean 
    @Splitter(inputChannel = "in") 
    public MySplitter splitter() { 
     MySplitter splitter = new MySplitter(); 
     splitter.setOutputChannelName("out"); 
     return splitter; 
    } 

    @Bean 
    public MessageChannel out() { 
     return new MessageChannel() { 

      @Override 
      public boolean send(Message<?> message) { 
       return send(message, -1); 
      } 

      @Override 
      public boolean send(Message<?> message, long timeout) { 
       System.out.println(message); 
       return true; 
      } 

     }; 
    } 

    public static class MySplitter extends AbstractMessageSplitter { 

     @SuppressWarnings("resource") 
     @Override 
     protected Object splitMessage(Message<?> message) { 
      Object payload = message.getPayload(); 
      Assert.isInstanceOf(File.class, payload, "Expected java.io.File in the message payload"); 

      try { 
       InputStream source = new FileInputStream((File) payload); 
       final BufferedReader reader = new BufferedReader(new InputStreamReader(source)); 
       final String header = reader.lines().findFirst().orElse(null); 
       final Iterator<String> iterator = reader.lines().iterator(); 
       Iterator<MessageBuilder<String>> builderIterator = new Iterator<MessageBuilder<String>>() { 

        private String next; 

        @Override 
        public boolean hasNext() { 
         if (this.next != null) { // handle multiple hasNext() calls. 
          return true; 
         } 
         if (!iterator.hasNext()) { 
          try { 
           reader.close(); 
          } 
          catch (IOException e) { 
           e.printStackTrace(); 
          } 
          return false; 
         } 
         else { 
          this.next = iterator.next(); 
          // Handle empty last line 
          if (next.length() == 0 && !iterator.hasNext()) { 
           try { 
            reader.close(); 
           } 
           catch (IOException e) { 
            e.printStackTrace(); 
           } 
           return false; 
          } 
          return true; 
         } 
        } 

        @Override 
        public MessageBuilder<String> next() { 
         String line = this.next; 
         this.next = null; 
         return MessageBuilder 
           .withPayload(line).setHeaderIfAbsent("HEADER", header); 
        } 

       }; 
       return builderIterator; 
      } 
      catch (IOException e) { 
       throw new UncheckedIOException(e); 
      } 
     } 

    } 

} 

注意を返す必要があります。

FOO,BAR 
foo,bar 
baz.qux 

結果:

GenericMessage [payload=foo,bar, headers={sequenceNumber=1, HEADER=FOO,BAR, correlationId=42ce2e1f-5337-1f75-d4fe-0d7f366f76f1, id=94e98261-fd49-b4d0-f6a0-3181b27f145b, sequenceSize=0, timestamp=1497713691192}] 
GenericMessage [payload=baz.qux, headers={sequenceNumber=2, HEADER=FOO,BAR, correlationId=42ce2e1f-5337-1f75-d4fe-0d7f366f76f1, id=c0b1edd6-adb9-3857-cb7c-70f603f376bc, sequenceSize=0, timestamp=1497713691192}] 

JIRA Issue INT-4297 to add this functionality to FileSplitterファイルで

+0

ありがとうございました。うまく動作します – Pram

関連する問題