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

Java 使用DSL从Unix位置读取文件的Spring集成,java,spring,spring-boot,spring-integration,Java,Spring,Spring Boot,Spring Integration,我有一个要求,我需要在unix位置连续查找文件。一旦文件可用,我需要解析它并转换为一些json格式。这需要使用Spring integration-DSL来完成。 以下是我从spring站点获得的一段代码,但它显示了以下异常: o.s.integration.handler.LoggingHandler: org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channe

我有一个要求,我需要在unix位置连续查找文件。一旦文件可用,我需要解析它并转换为一些json格式。这需要使用Spring integration-DSL来完成。 以下是我从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 
代码如下:

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

}
新代码:

@SpringBoot应用程序 公共类集成{

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

        }

    };
}
publicstaticvoidmain(字符串[]args){
新的SpringApplicationBuilder(SpringIntegration.class)
.web(错误)
.run(args);
}
@豆子
公共会话工厂sftpSessionFactory(){
DefaultSftpSessionFactory=新的DefaultSftpSessionFactory(true);
工厂设置主机(“ip”);
工厂设置端口(端口);
factory.setUser(“用户名”);
出厂设置密码(“pwd”);
工厂。setAllowUnknownKeys(真);
返回新的CachingSessionFactory(工厂);
}
@豆子
公共SftpInboundFileSynchronizer SftpInboundFileSynchronizer(){
SftpInboundFileSynchronizer fileSynchronizer=新的SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
setRemoteDirectory(“远程目录”);
setFilter(新的SftpSimplePatternFileListFilter(“*.txt”);
返回文件同步器;
}
@豆子
@InboundChannelAdapter(channel=“sftpChannel”,poller=@poller(fixedDelay=“1000”,maxMessagesPerPoll=“1”))
public MessageSource ftpMessageSource(){
SftpInboundFileSynchronizingMessageSource源=
新的SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
setLocalFilter(新的AcceptOnceFileListFilter());
setLocalDirectory(新文件(“本地目录”);
返回源;
}
@豆子
@ServiceActivator(inputChannel=“fileInputChannel”)
public MessageHandler(){
返回新的MessageHandler(){
@凌驾
public void handleMessage(消息消息消息)引发MessaginException{
System.out.println(“文件名:+message.getPayload());
}
};
}
@豆子 公共静态标准IntegrationFlow processFileFlow(){ 返回积分流 .from(“fileInputChannel”).split() .handle(“文件处理器”、“进程”).get()

}
@豆子
@InboundChannelAdapter(value=“fileInputChannel”,poller=@poller(fixedDelay=“1000”))
public MessageSource fileReadingMessageSource(){
AcceptOnceFileListFilter=新的AcceptOnceFileListFilter();
FileReadingMessageSource=新建FileReadingMessageSource();
source.setAutoCreateDirectory(true);
setDirectory(新文件(“本地目录”);
source.setFilter(过滤器);
返回源;
}
@豆子
公共文件处理器文件处理器(){
返回新的FileProcessor();
}
@豆子
@ServiceActivator(inputChannel=“fileInputChannel”)
公共AmqpOutboundEndpoint amqpOutbound(AmqpTemplate AmqpTemplate){
AmqpOutboundEndpoint outbound=新的AmqpOutboundEndpoint(amqpTemplate);
outbound.setExpectReply(true);
outbound.setRoutingKey(“foo”);//默认exchange-路由到队列“foo”
返回出境;
}
@MessagingGateway(defaultRequestChannel=“amqOutboundChannel”)
公共接口MyGateway{
字符串sendToRabbit(字符串数据);
}
}

文件处理器:

公共类文件处理器{

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

    }

}
公共作废流程(消息消息消息){
字符串内容=msg.getPayload();
JSONObject JSONObject;
Map dataMap=newhashmap();

对于(int i=0;i您的代码是正确的,但是异常告诉您需要一些东西来读取来自直接通道“processFileChannel”的消息

请在中阅读有关不同频道类型的更多信息

编辑

Spring集成中的头等公民之一是
MessageChannel
抽象。有关更多信息,请参阅

.channel(“processFileChannel”)
这样的定义意味着declare。这种通道意味着在发送时接受消息,并直接在
send
过程中执行处理。在原始Java单词中,它可能听起来像:从一个服务调用另一个服务。如果另一个服务没有自动连接,则抛出
NPE

因此,如果您对输出使用
DirectChannel
,您应该在某个地方为它声明一个订户。我不知道您的逻辑是什么,但这就是它的工作原理,并且没有其他选择来修复
Dispatcher没有频道的订户


虽然您可以使用一些其他的
消息频道
类型。但是为此,您应该阅读更多的文档,例如Mark Fisher的。

您的代码是正确的,但是一个异常告诉您需要一些可以从直接频道“processFileChannel”读取消息的内容

请在中阅读有关不同频道类型的更多信息

编辑

Spring集成中的头等公民之一是
MessageChannel
抽象。有关更多信息,请参阅

.channel(“processFileChannel”)
这样的定义意味着declare。这种通道意味着在发送时接受消息,并直接在
send
过程中执行处理。在原始Java单词中,它可能听起来像:从一个服务调用另一个服务。如果另一个服务没有自动连接,则抛出
NPE

因此,如果您对输出使用
DirectChannel
,您应该在某个地方为它声明一个订户。我不知道您的逻辑是什么,但这就是它的工作原理,并且没有其他选择来修复
Dispatcher没有频道的订户


虽然您可以使用其他
消息频道
类型。但为此,您应该阅读更多文档,例如Mark Fisher。

事实上,我是Spring Integration的新手。这个概念有点棘手,如果您能告诉我需要根据我的需要进行哪些更改,将非常有用
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);

    }

}