0

Как создать прямой канал, адаптер IMAP-канала и передать информацию учетной записи пользователя, чтобы программа начала искать новые письма.Как создать адаптер приемника imap динамически, используя весенний ботинок?

Я уже реализовал почтовый приемник с помощью xml config.

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd 
    http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd" 
    xmlns:int="http://www.springframework.org/schema/integration" 
    xmlns:int-mail="http://www.springframework.org/schema/integration/mail" 
    xmlns:util="http://www.springframework.org/schema/util"> 

<int:channel id="emails"/> 

<util:properties id="javaMailProperties"> 
    <prop key="mail.imap.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop> 
    <prop key="mail.imap.socketFactory.fallback">false</prop> 
    <prop key="mail.store.protocol">imaps</prop> 
    <prop key="mail.debug">true</prop> 
</util:properties> 

<int-mail:imap-idle-channel-adapter id="mailAdapter" 
           store-uri="imaps://login:[email protected]:993/INBOX" 
           java-mail-properties="javaMailProperties" 
           channel="emails" 
           should-delete-messages="false" 
           should-mark-messages-as-read="true"> 
</int-mail:imap-idle-channel-adapter> 

Ниже Java файл, который использует файл XML.

public class EmailIntegrationTesting { 

private static Logger logger = LoggerFactory.getLogger(EmailIntegrationTesting.class); 

public static void main(String[] args) throws Exception { 
    ApplicationContext ac = new ClassPathXmlApplicationContext("gmail-imap.xml"); 

    DirectChannel inputChannel = ac.getBean("receiveChannel", DirectChannel.class); 
    inputChannel.subscribe(new MessageHandler() { 
     @Override 
     public void handleMessage(Message<?> message) throws MessagingException { 


      MailToStringTransformer m2s = new MailToStringTransformer(); 
      m2s.setCharset("utf-8"); 
      System.out.println("Message: " + m2s.transform(message)); 

      System.out.println("Message: " + message.getPayload()); 
      Object payload = message.getPayload(); 

      if (payload instanceof MimeMessage) { 
       try { 

        javax.mail.Message mailMessage = (javax.mail.Message) payload; 
        System.out.println(mailMessage.getSubject()); 
        System.out.println(getTextFromMessage(mailMessage)); 

        Address[] receipts = mailMessage.getAllRecipients(); 
        System.out.println("RECEIPIENTS MAIL ID"); 
        if (receipts != null && receipts.length > 0) { 
         for (int i = 0; i < receipts.length; i++) { 
          System.out.println(((InternetAddress) receipts[i]).getAddress()); 
         } 
        } 

        System.out.println("FROM MAIL ID"); 
        Address[] froms = mailMessage.getFrom(); 
        String email = froms == null ? null 
          : ((InternetAddress) froms[0]).getAddress(); 
        System.out.println(email); 

       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 
     } 
    }); 
} 

private static String getTextFromMessage(javax.mail.Message message) throws Exception { 
    String result = ""; 
    if (message.isMimeType("text/plain")) { 
     result = message.getContent().toString(); 
    } else if (message.isMimeType("multipart/*")) { 
     MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); 
     result = getTextFromMimeMultipart(mimeMultipart); 
    } 
    return result; 
} 

private static String getTextFromMimeMultipart(MimeMultipart mimeMultipart) throws Exception { 
    String result = ""; 
    int count = mimeMultipart.getCount(); 
    for (int i = 0; i < count; i++) { 
     BodyPart bodyPart = mimeMultipart.getBodyPart(i); 
     if (bodyPart.isMimeType("text/plain")) { 
      result = result + "\n" + bodyPart.getContent(); 
      break; // without break same text appears twice in my tests 
     } else if (bodyPart.isMimeType("text/html")) { 
      String html = (String) bodyPart.getContent(); 
      // result = result + "\n" + org.jsoup.Jsoup.parse(html).text(); 
     } else if (bodyPart.getContent() instanceof MimeMultipart) { 
      result = result + getTextFromMimeMultipart((MimeMultipart) bodyPart.getContent()); 
     } 
    } 
    return result; 
} 

} 

Я могу успешно получить почту, используя вышеприведенный код.

Я также могу конвертировать xml в java config. ниже приведен код.

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.integration.mail.ImapIdleChannelAdapter; 
import org.springframework.integration.mail.ImapMailReceiver; 
import java.util.Properties; 

@Configuration 
class ImapConfiguration { 

private Properties javaMailProperties() { 
    Properties javaMailProperties = new Properties(); 

    javaMailProperties.setProperty("mail.imap.socketFactory.class","javax.net.ssl.SSLSocketFactory"); 
    javaMailProperties.setProperty("mail.imap.socketFactory.fallback","false"); 
    javaMailProperties.setProperty("mail.store.protocol","imaps"); 
    javaMailProperties.setProperty("mail.debug","true"); 

    return javaMailProperties; 
} 

@Bean 
ImapIdleChannelAdapter mailAdapter() { 
    ImapMailReceiver mailReceiver = new ImapMailReceiver("imaps://login:[email protected]:993/INBOX"); 

    mailReceiver.setJavaMailProperties(javaMailProperties()); 
    mailReceiver.setShouldDeleteMessages(false); 
    mailReceiver.setShouldMarkMessagesAsRead(true); 

    return new ImapIdleChannelAdapter(mailReceiver); 
} 

@Bean 
public MessageChannel emails() { 
return new DirectChannel(); 
} 

}

теперь моя точка я хочу настроить выше кода динамически.

USECASE Когда пользователь заполняет данные imap-сервера, он должен начать поиск входящих сообщений электронной почты. означает, что я не хочу создавать bean-компоненты в момент запуска сервера.

ответ

1

См. my answer to this question и its follow-up.

Вы также можете использовать DSL Java для регистрации потоков динамически ...

@Autowired 
private IntegrationFlowContext flowContext; 

... 

    IntegrationFlow flow = IntegrationFlows.from(Mail.imapIdleAdapter(...) 
          .handle(...) 
          ... 
          .get(); 
    IntegrationFlowRegistration flowRegistration = 
       this.flowContext.registration(flow) 
         .register(); 

EDIT

Добавлен образец загрузки приложения

@SpringBootApplication 
public class So42297006Application { 

    public static void main(String[] args) throws Exception { 
     ConfigurableApplicationContext context = SpringApplication.run(So42297006Application.class, args); 
     context.getBean(So42297006Application.class).runDemo(); 
     context.close(); 
     System.exit(0); 
    } 

    public void runDemo() throws Exception { 
     Scanner scanner = new Scanner(System.in); 
     System.out.println("Enter username"); 
     String user = scanner.next(); 
     System.out.println("Enter pw"); 
     String pw = scanner.next(); 
     scanner.close(); 
     startMail(user, pw); 
     Thread.sleep(10_000); 
    } 

    @Autowired 
    private IntegrationFlowContext flowContext; 

    public void startMail(String user, String pw) { 
     IntegrationFlow flow = IntegrationFlows 
       .from(Mail.imapIdleAdapter(imapUrl(user, pw)) 
         .javaMailProperties(p -> p.put("mail.debug", "false")) 
         .userFlag("testSIUserFlag") // needed by the SI test server - not needed if server supports /SEEN 
         .headerMapper(new DefaultMailHeaderMapper())) 
       .handle(System.out::println) 
       .get(); 
     this.flowContext.registration(flow).register(); 
    } 

    private String imapUrl(String user, String pw) { 
     return "imap://" 
       + user + ":" + pw 
       + "@localhost:" + imapServer().getPort() + "/INBOX"; 
    } 

    @Bean 
    public TestMailServer.ImapServer imapServer() { 
     return TestMailServer.imap(0); 
    } 

} 

Maven Deps:

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-integration</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-mail</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.integration</groupId> 
     <artifactId>spring-integration-mail</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.integration</groupId> 
     <artifactId>spring-integration-test</artifactId> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework.integration</groupId> 
     <artifactId>spring-integration-java-dsl</artifactId> 
    </dependency> 
+0

Привет, я очень новичок весной, и я мало знаю о applicationContext. Но возможно ли создать канал, который начнет получать почту, когда произойдет какое-то событие. В моем случае пользователю необходимо заполнить конфигурацию imap, и когда он заполнит конфигурацию и нажмите кнопку «Сохранить», мне нужно запустить IMAP-приемник «на лету». Является ли это возможным? Можете ли вы добавить рабочие примеры, пожалуйста? –

+0

Пример в моем ответе будет делать именно это - как только вы зарегистрируете поток, начнется запуск почтового адаптера. –

+0

Я добавил быстрый пример. –