简体   繁体   English

使用DSL从Spring位置读取文件的Spring集成

[英]Spring Integration using DSL for reading file from Unix location

I have a requirement where i need to look for a file continuously at unix location.Once its available then i need to parse it and convert to some json format.This needs to be done using Spring integration - DSL. 我有一个要求,我需要在unix位置连续查找文件。一旦它可用,那么我需要解析它并转换为一些json格式。这需要使用Spring集成 - DSL完成。 Following is the piece of code I got from spring site but it shows following exception: 以下是我从Spring网站获得的一段代码,但它显示以下异常:

o.s.integration.handler.LoggingHandler: org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application.processFileChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 

Below is the code: 以下是代码:

@SpringBootApplication
public class FileReadingJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(FileReadingJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Bean
    public IntegrationFlow fileReadingFlow() {
         return IntegrationFlows
                  .from(s -> s.file(new File("Y://"))
                              .patternFilter("*.txt"),
                          e -> e.poller(Pollers.fixedDelay(1000)))
                  .transform(Transformers.fileToString())
                  .channel("processFileChannel")
                  .get();
        }

}

New Code: 新守则:

@SpringBootApplication public class SpringIntegration { @SpringBootApplication公共类SpringIntegration {

public static void main(String[] args) {
    new SpringApplicationBuilder(SpringIntegration.class)
    .web(false)
    .run(args);
}

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost("ip");
    factory.setPort(port);
    factory.setUser("username");
    factory.setPassword("pwd");
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(factory);
}

@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
    fileSynchronizer.setDeleteRemoteFiles(false);
    fileSynchronizer.setRemoteDirectory("remote dir");
    fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.txt"));

    return fileSynchronizer;
}
@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "1000", maxMessagesPerPoll = "1"))
public MessageSource ftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source =
            new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
    source.setLocalFilter(new AcceptOnceFileListFilter<File>());
    source.setLocalDirectory(new File("Local directory"));

    return source;
}

@Bean
@ServiceActivator(inputChannel = "fileInputChannel")
public MessageHandler handler() {
    return new MessageHandler() {


        @Override
        public void handleMessage(Message<?> message) throws MessagingException {
            System.out.println("File Name : "+message.getPayload());

        }

    };
}

@Bean public static StandardIntegrationFlow processFileFlow() { return IntegrationFlows .from("fileInputChannel").split() .handle("fileProcessor", "process").get(); @Bean public static StandardIntegrationFlow processFileFlow(){return IntegrationFlows .from(“fileInputChannel”)。split()。handle(“fileProcessor”,“process”)。get();

    }

@Bean
@InboundChannelAdapter(value = "fileInputChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
    AcceptOnceFileListFilter<File> filters =new AcceptOnceFileListFilter<>();

    FileReadingMessageSource source = new FileReadingMessageSource();
    source.setAutoCreateDirectory(true);
    source.setDirectory(new File("Local directory"));
    source.setFilter(filters);

    return source;
}
@Bean
public FileProcessor fileProcessor() {
    return new FileProcessor();
}


 @Bean
    @ServiceActivator(inputChannel = "fileInputChannel")
    public AmqpOutboundEndpoint amqpOutbound(AmqpTemplate amqpTemplate) {
        AmqpOutboundEndpoint outbound = new AmqpOutboundEndpoint(amqpTemplate);
        outbound.setExpectReply(true);
        outbound.setRoutingKey("foo"); // default exchange - route to queue 'foo'
        return outbound;
    }



    @MessagingGateway(defaultRequestChannel = "amqpOutboundChannel")
    public interface MyGateway {
        String sendToRabbit(String data);

    }

} }

FileProcessor: FileProcessor:

public class FileProcessor { 公共类FileProcessor {

public void process(Message<String> msg) {
    String content = msg.getPayload();
    JSONObject jsonObject ;
    Map<String, String> dataMap = new HashMap<String, String>();
    for(int i=0;i<=content.length();i++){
    String userId = content.substring(i+5,i+16);


    dataMap = new HashMap<String, String>();

    dataMap.put("username", username.trim());


    i+=290; //each record of size 290 in file
     jsonObject = new JSONObject(dataMap);
    System.out.println(jsonObject);

    }

}

} }

Your code is correct , but an exception tells you that there is need something what will read messages from the direct channel "processFileChannel". 您的代码是正确的,但例外情况告诉您需要从直接通道“processFileChannel”读取消息的内容。

Please, read more about different channel types in the Spring Integration Reference Manual . 请在Spring Integration Reference Manual中阅读有关不同通道类型的更多信息。

EDIT 编辑

One of first class citizen in Spring Integration is MessageChannel abstraction. Spring Integration中的一等公民之一是MessageChannel抽象。 See EIP for more information. 有关更多信息,请参阅EIP

The definition like .channel("processFileChannel") mean declare DirectChannel . .channel("processFileChannel")这样的定义意味着声明DirectChannel This kind of channel means accept message on the send and perform handling directly just in send process. 这种通道意味着在send过程中接受消息并直接执行处理。 In the raw Java words it may sound like: call one service from another. 在原始的Java语言中,它可能听起来像:从另一个服务中调用一个服务。 Throw NPE if the another hasn't been autowired. 如果另一个尚未自动装配,则抛出NPE

So, if you use DirectChannel for the output, you should declare somewhere a subscriber for it. 因此,如果您使用DirectChannel作为输出,您应该在某处声明订阅者 I don't know what is your logic, but that is how it works and no other choice to fix Dispatcher has no subscribers for channel . 我不知道你的逻辑是什么,但这就是它的工作方式,没有别的选择来修复Dispatcher has no subscribers for channel

Although you can use some other MessageChannel type. 虽然您可以使用其他一些MessageChannel类型。 But for this purpose you should read more doc, eg Mark Fisher's Spring Integration in Action . 但为了这个目的,你应该阅读更多的文档,例如Mark Fisher的Spring Integration in Action

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM