봄 웹 플럭스에서 반응형 전자 메일을 보내는 방법
저는 새로운 스프링 애플리케이션 내에서 완전한 반응성을 유지하고 싶습니다.따라서 저는 MongoDB와 함께 Web-flux/reactive와 Reactive Repository를 사용합니다.
Java 메일을 기술 스택에 대응적으로 통합하는 방법을 알고 계십니까?대안은 없나요?
전자 메일을 보내고 차단하지 않는 경우 다른 스레드에서 전자 메일을 보내는 코드를 실행할 수 있습니다.Spring WebFlux를 사용하는 경우 이메일 전송 코드를 Mono(A 반응기 라이브러리 게시자)의 공장 방식으로 포장하여 쉽게 수행할 수 있습니다.
호출 가능()에서 모노
또는
Mono.fromRun.
단축 코드
Mono.fromCallable(()-> sendEmail())
.subscribe();
여기서 sendEmail()은 전자 메일을 보내는 기능입니다.
이것은 문서에서도 권장되는 내용입니다. 동기식 차단 통화를 랩하는 방법은 무엇입니까?
롱 코드
아래는 제가 신청서에 사용하고 있는 완전한 샘플 코드입니다.
Mono.fromCallable(() -> {
try {
MimeMessageHelper helper = new MimeMessageHelper(sender.createMimeMessage());
helper.setTo(to);
helper.setSubject(subject);
helper.setText(body);
sender.send(helper.getMimeMessage());
log.info("Email send successfully, subject {} , to {}", subject, to);
return true;
} catch (Exception e) {
log.warn("Failed to send email with subject {}, due to {}",subject,e.getMessage(), e});
return false;
}
)
.subscribe(result -> log.info("Mail sent {}", result));
그리고 반응형 스택일 때는 구독하는 것을 잊지 마세요 :D.
저도 반응형 SMTP 클라이언트를 찾고 있었습니다.
그리고 간신히 찾았어요 ;)
여기 있습니다: https://github.com/HubSpot/NioSmtpClient
README에서:
Netty 기반 Java의 고성능 SMTP 클라이언트.이 클라이언트는 HubSpot에서 잘 테스트되고 많이 사용됩니다.
저는 이미 현지 환경에서 검증했고 정말 반응적입니다!그러나 완전한 기능을 사용합니다.Mono 또는 Flux 대신 Future를 사용하므로 수동으로 포장해야 합니다.
일반적으로 이 도서관은 좋아 보이지만 작가가 제공해준다면 더 좋을 것 같습니다.facade
SDK 사용을 단순화할 수 있습니다.(어쨌든 오픈 소스이므로 개선할 수 있습니다.)
다음은 사용 방법의 예입니다(codeStyle에 대해서는 신경쓰지 마십시오. 예를 위한 것입니다).
private static final String MESSAGE_DATA = "From: <sender@gmail.com\r\n" +
"To: <recipient@gmail.com>\r\n" +
"Subject: test mail\r\n\r\n" +
"Hello stackOverFlow!";
public static void main(String[] args) {
final SmtpSessionFactory smtpSessionFactory = createSmtpSessionFactory();
final SmtpSessionConfig smtpSessionConfig = SmtpSessionConfig.builder().remoteAddress(InetSocketAddress.createUnresolved("smtp.gmail.com", 587)).build();
Mono.fromFuture(smtpSessionFactory.connect(smtpSessionConfig))
.flatMap(connection -> doInSession(connection, req(EHLO, "gmail.com")))
.flatMap(connection -> Mono.fromFuture(connection.getSession().startTls()))
.flatMap(connection -> Mono.fromFuture(connection.getSession().authLogin("sender@gmail.com", "SomeStrongPasswordLike123456")))
.flatMap(connection -> doInSession(connection, req(MAIL, "FROM:<" + "sender@gmail.com" + ">")))
.flatMap(connection -> doInSession(connection, req(RCPT, "TO:<" + "recipient@gmail.com" + ">")))
.flatMap(connection -> doInSession(connection, req(DATA)))
.map(connection -> connection.getSession()
.send(MessageContent.of(Unpooled.wrappedBuffer(MESSAGE_DATA.getBytes(StandardCharsets.UTF_8)))))
.flatMap(Mono::fromFuture)
.flatMap(connection -> doInSession(connection, req(QUIT)))
.flatMap(connection -> Mono.fromFuture(connection.getSession().close()))
.block();
}
private static SmtpSessionFactory createSmtpSessionFactory() {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("niosmtpclient-%d").build();
final SmtpSessionFactoryConfig config = SmtpSessionFactoryConfig.builder()
.eventLoopGroup(new NioEventLoopGroup(4, threadFactory))
.executor(Executors.newCachedThreadPool(threadFactory))
.build();
return new SmtpSessionFactory(config);
}
private static Mono<SmtpClientResponse> doInSession(SmtpClientResponse connection, SmtpRequest request) {
return Mono.fromFuture(connection.getSession().send(request));
}
private static SmtpRequest req(SmtpCommand command, CharSequence... arguments) {
return new DefaultSmtpRequest(command, arguments);
}
작동 방식(일반):
- 세션 팩토리를 정의합니다(방법 참조).
createSmtpSessionFactory
) - 서버와 대화(연결)를 엽니다.
- 우리는 TLS를 시작합니다.
- 자격 증명으로 인증을 수행합니다.
- 우리는 서버에 보낸 사람의 이메일 주소를 말합니다.
- 우리는 서버에 수신자의 이메일 주소를 말합니다.
- 데이터 전송 단계를 시작합니다.
- 우리는 데이터를 보냅니다(데이터는 어떤 패턴을 따라야 합니다)보낸 사람: ...받는 사람: ...제목: ....참조
MESSAGE_DATA
가변) - 대화를 끝내고 있음을 서버에 알립니다.
- 폐회.
제가 찾은 유용한 비 멀티캐스트 SMTP 클라이언트는 https://vertx.io/docs/vertx-mail-client/java/ 뿐입니다.
심지어 스프링-웹플럭스와 몽고드-드라이버-리액티브 스트림과 통합하여 동일한 Netty EventLoopGroup을 공유하도록 했습니다.
Mono.create<MailResult> { sink ->
mailClient.sendMail(email) { asyncResult ->
if (asyncResult.succeeded()) {
sink.success(asyncResult.result()
} else {
sink.error(asyncResult.cause()
}
}
}
마이크로소프트 그래프 api를 사용하고 마이크로소프트의 exrange 서버를 사용하여 이메일 https://learn.microsoft.com/en-us/graph/use-the-api 을 보내는 것은 어떻습니까?원래 질문에 대한 답변은 아니지만, 동일한 개념을 적용할 수 있는지 또는 이 API를 사용하여 비슷한 것을 가지고 있는 사람이 있는지 궁금합니다.
해결책을 찾았어요그것은 사용합니다.spring-boot-starter-data-mongodb-reactive
그리고 Mailgun 또는 SendGrid와 같은 외부 서비스의 API. WebClient WebClient를 입니다.
Web Client 인스턴스 빌드(예: Sendgrid API 사용):
String endpoint = “https://api.sendgrid.com/v3/“; String sendUri = endpoint + “mail/send”; WebClient client = WebClient.builder().filter(…).clientConnector(new ReactorClientHttpConnector(HttpClient.create())).baseUrl(endpoint).build()
응답 개체 구현:
@Data class Response implements Serializable { private boolean status; private String id; private String message; } @Data class NotificationStatusResponse implements Serializable { private LocalDateTime timestamp; private int status; private String message; private String traceId; private String responseId; private String providerResponseId; private String providerResponseMessage; }
메시지 보내기:
public Mono<NotificationStatusResponse> send(NotificationMessage<EmailId> email) throws NotificationSendFailedException { Mono<NotificationStatusResponse> response = null; try { MultiValueMap<String, Object> formMap = new LinkedMultiValueMap<>(); // email parameters here: from, to, subject, html etc. response = client.post().uri(sendUri) .header("Authorization", "Basic " + “your credentials here”) .contentType(MediaType.MULTIPART_FORM_DATA).syncBody(formMap).retrieve() .bodyToMono(Response.class).map(this::getNotificationStatusResponse) .doOnSuccess(message -> log.debug("sent email successfully")) .doOnError((error -> log.error("email failed ", error))); } catch (WebClientException webClientException) { throw new NotificationSendFailedException("webClientException received", webClientException); } return response; NotificationStatusResponse getNotificationStatusResponse(Response response) { NotificationStatusResponse notificationStatusResponse = new NotificationStatusResponse(); notificationStatusResponse.setStatus(200); notificationStatusResponse.setTimestamp(LocalDateTime.now()); notificationStatusResponse.setProviderResponseId(response.getId()); notificationStatusResponse.setProviderResponseMessage(response.getMessage()); return notificationStatusResponse; } }
언급URL : https://stackoverflow.com/questions/51091893/how-to-send-email-reactive-in-spring-web-flux
'programing' 카테고리의 다른 글
오라클 테이블에서 삭제된 행 복구 (0) | 2023.07.21 |
---|---|
서로 다른 마이크로 서비스 간의 데이터 검증 (0) | 2023.07.21 |
MyBatis 목록 삽입 값 (0) | 2023.07.21 |
postgresql의 권고 잠금 시간 초과 (0) | 2023.07.21 |
es6 스타일 가져오기를 사용하여 MongoDB를 가져오는 방법은 무엇입니까? (0) | 2023.07.16 |