728x90
반응형
Gmail 에서 JAVA 프로그래밍을 통한 이메일을 보내려면 계정설정에서 앱 비밀번호로 로그인 이 가능하도록 2단계 인증을 거쳐 16자리 새로운 암호를 할당받아야 한다.
Email Server 까지 만들기는 귀찮으니 많이들 사용하는 Gmail 계정을 JAVA 와 연결해서 메일을 보내는 법을 알아봅시다.
우선 를 다운 받거나 gradle 이나 maven dependency 에 추가시키자.
### build.gradle.kts
제 build.gradle.kts
파일은 다음과 같음. (Vert.x server 를 쓰기 때문에...)
```[.linenums.lang-kts]
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.tasks.testing.logging.TestLogEvent.*
plugins {
java
application
id("com.github.johnrengelman.shadow") version "8.1.1"
}
group = "net.recoeve"
version = "1.0.0-SNAPSHOT"
repositories {
mavenCentral()
}
val vertxVersion = "4.5.1"
val junitJupiterVersion = "5.9.1"
val mainVerticleName = "recoeve.http.MainVerticle"
val launcherClassName = "io.vertx.core.Launcher"
val watchForChange = "src/**/*"
val doOnChange = "${projectDir}/gradlew classes"
application {
mainClass.set(launcherClassName)
}
dependencies {
implementation("io.netty:netty-all:4.1.104.Final")
// https://mavenlibs.com/maven/dependency/mysql/mysql-connector-java
implementation("mysql:mysql-connector-java:8.0.33")
// https://mavenlibs.com/maven/dependency/com.mysql/mysql-connector-j
implementation("com.mysql:mysql-connector-j:8.1.0")
// https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api
implementation("com.sun.mail:jakarta.mail:2.0.1")
implementation("org.jsoup:jsoup:1.17.1")
// https://mvnrepository.com/artifact/io.vertx/vertx-core
implementation("io.vertx:vertx-core:$vertxVersion")
//Thanks for using https://jar-download.com
implementation("io.micrometer:micrometer-registry-prometheus:1.12.1")
// https://mvnrepository.com/artifact/io.vertx/vertx-micrometer-metrics
implementation("io.vertx:vertx-micrometer-metrics:$vertxVersion")
implementation(platform("io.vertx:vertx-stack-depchain:$vertxVersion"))
implementation("io.vertx:vertx-web-client")
implementation("io.vertx:vertx-web")
implementation("io.vertx:vertx-web-openapi")
implementation("io.vertx:vertx-mysql-client")
implementation("io.vertx:vertx-http-service-factory")
implementation("io.vertx:vertx-json-schema")
implementation("io.vertx:vertx-web-api-contract")
implementation("io.vertx:vertx-rx-java3")
implementation("io.vertx:vertx-auth-oauth2:$vertxVersion")
implementation("io.vertx:vertx-jdbc-client")
implementation("io.vertx:vertx-config")
implementation("io.vertx:vertx-rx-java2")
implementation("io.vertx:vertx-rx-java")
implementation("io.vertx:vertx-mail-client")
implementation("io.vertx:vertx-auth-jdbc")
testImplementation("io.vertx:vertx-junit5")
testImplementation("org.junit.jupiter:junit-jupiter:$junitJupiterVersion")
implementation("org.seleniumhq.selenium:selenium-java:4.17.0") // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
tasks.withType<ShadowJar> {
archiveClassifier.set("fat")
manifest {
attributes(mapOf("Main-Verticle" to mainVerticleName))
}
mergeServiceFiles()
}
tasks.withType<Test> {
useJUnitPlatform()
testLogging {
events = setOf(PASSED, SKIPPED, FAILED)
}
}
tasks.withType<JavaExec> {
args = listOf("run", mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$launcherClassName", "--on-redeploy=$doOnChange")
}
```/
```[.linenums]
gradlew build
gradlew run
// 과 같은 명령어로 java 파일 전체를 compile 하고 dependencies 를 자동으로 다운받고 할 수 있음.
```/
### JAVA code
그리고 아래와 같이 JAVA 코드를 작성하면 잘 돌아감. 해당 코드는 https://mailtrap.io/blog/jakarta-mail-tutorial/#Sending-HTML-email-in-Jakarta-Mail 에서 가져왔고, 제가 class 이름, 변수 등을 약간 수정함.
```[.scrollable.lang-java]
package recoeve.http;
import jakarta.mail.*;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.util.Properties;
public class Gmail {
private static final String username = "recoeve";
private static final String amho = "***amho***"; // 구글계정에서 2단계 인증을 거쳐 받은 16자리 앱 암호입력.
private static final Properties prop = new Properties();
static {
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", "465");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.socketFactory.port", "465");
prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
private static final Session session = Session.getInstance(
prop, new jakarta.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, amho);
}
});
/**
* Send email using Gmail SMTP server.
*
* @param recipientEmail TO recipient
* @param ccEmail CC recipient. Can be empty if there is no CC recipient
* @param title title of the message
* @param message message to be sent
* @throws MessagingException if the connection is dead or not in the connected
* state or if the message is not a MimeMessage
*/
public static void send(String recipientEmail, String ccEmail, String title, String message) {
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("recoeve@gmail.com"));
msg.setRecipients(
Message.RecipientType.TO,
InternetAddress.parse(recipientEmail));
msg.setSubject(title);
msg.setContent(message, "text/html; charset=utf-8");
Transport.send(msg);
} catch (MessagingException e) {
e.printStackTrace();
}
}
public static void main(String... args) throws Exception {
Gmail.send("kipid84@naver.com", "", "title", "<h1>HTML message.</h1>"); // 테스트.
}
}
```/
### "Not provider of jakarta.mail.util.StreamProvider was found" Error handle
최근까지 업데이트 되고 있는 https://mvnrepository.com/artifact/jakarta.mail/jakarta.mail-api/2.1.3 를 dependency 에 넣고 실행시켰더니 "Not provider of jakarta.mail.util.StreamProvider was found" 에러가 발생했었음. 뭔가가 업데이트 되면서 code 를 좀 바꿔줘야 하는것도 같은데... 방법을 찾기가 너무 어려워서 그냥 downgrade 시킨 버전으로 해결 봤음.
최신 버전 사용법을 알고 계신 분은 댓글로 좀 알려주세요.
## Email Server 만들기
아예 Email Server 까지 돌리면서 JAVA 랑 연결해서 자동화 시키는 방법도 있는거 같긴한데... 귀찮;;; 방법은 알아서 찾아보시길. 시간날때 정리하겠음; (아예 안할지도ㅋ)
## 네이버 메일 by 자바 (Naver mail by JavaMail) :: 너무 오래된 문서라 지금은 도움이 안될듯.
우선 에서 javax.mail.jar
file 을 다운받읍시다. 적당한 폴더에 넣어놓고, 이 폴더\javax.mail.jar
를 윈도우 변수(?) CLASSPATH
에 포함시킵시다. 아니면 java compile 하거나 실행시킬때, javac -classpath "folder path\javax.mail.jar;other classes"
, java -classpath "folder path\javax.mail.jar;other classes"
식으로 실행시키면 됨.
그리고 아래와 같이 JAVA 코드를 작성하면 잘 돌아감. 해당 코드는 에서 가져왔고, 제가 class 이름 등 약간 수정함.
아래와 같은 코드로 잘 동작했었는데, 최근에 뭔가 바뀐건지 AWS server 에서는 잘 동작을 안함. Error 잡는 중. 혹시 아시는 분 있으면 도와주세요~!
```[.scrollable.lang-java]
package recoeve.http;
import com.sun.mail.smtp.*;
// import java.security.Security;
// import java.util.Date;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
// For import: download javax.mail.jar file from Java.net - The Source for Java Technology Collaboration - JavaMail API
// and include the filepath in classpath.
// C:\Recoeve\classes\javax.mail.jar
// API: Package com.sun.mail.smtp
// https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html
// https://developers.google.com/appengine/docs/java/mail/usingjavamail
/**
* https://stackoverflow.com/questions/3649014/send-email-using-java
* asked Sep 6 '10 at 4:34 by Mohit Bansal
* @author doraemon
*/
public class NaverMail{
public static void sendChangePwd(String id, String email, String token, String lang)
throws AddressException, MessagingException {
String title="Forgot password on Recoeve.net?";
if (lang.equals("ko")) {
title="Recoeve.net 의 비밀번호를 잊어버리셨나요?";
}
String url="https://"+Recoeve.HOST+"/account/changePwd?id="+id+"&email="+email+"&token="+token;
String msg="<span style='line-height:1.6; font-family:'Malgun Gothic', '맑은 고딕', 나눔고딕, NanumGothic, Tahoma, Sans-serif; font-size:27px'>Within 10 minutes after you receive this email, please visit<br><a href='"+url+"&lang=en"+"'>"+url+"&lang=en"+"</a>.<br><br><br><br>이메일을 받으신 후 10분내로 다음 링크를 방문해주세요.<br><a href='"+url+"&lang=ko"+"'>"+url+"&lang=ko"+"</a></span>";
NaverMail.send(email, "", title, msg);
}
public static void sendVeriKey(String email, String id, String veriKey)
throws AddressException, MessagingException {
String title="Verify your account on Recoeve.net";
String url="https://"+Recoeve.HOST+"/account/verify/"+id+"/"+veriKey;
String msg="<span style='line-height:1.6; font-family:'Malgun Gothic', '맑은 고딕', 나눔고딕, NanumGothic, Tahoma, Sans-serif; font-size:27px'>Thanks for your registration on <a href='https://recoeve.net/'>Recoeve.net</a>.<br><br>Please log in <a href='https://recoeve.net/'>Recoeve.net</a> first, and then click the following link to verify your account:<br><a href='"+url+"'>"+url+"</a><br><br><br><br><a href='https://recoeve.net/'>Recoeve.net</a> 가입을 환영합니다.<br><br>계정 이메일 인증을 위해 로그인 후 다음 링크를 클릭해 주세요.:<br><a href='"+url+"'>"+url+"</a><br></span>";
NaverMail.send(email, "", title, msg);
}
private static final String username="kipid84";
private static final String amho="amho";
private static final Properties prop = new Properties();
static {
prop.put("mail.smtp.host", "smtp.naver.com");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.starttls.enable", "true"); // TLS
}
private static final Session session = Session.getInstance(
prop, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, amho);
}
}
);
/**
* Send email using NaverMail SMTP server.
*
* @param recipientEmail TO recipient
* @param ccEmail CC recipient. Can be empty if there is no CC recipient
* @param title title of the message
* @param message message to be sent
* @throws AddressException if the email address parse failed
* @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage
*/
public static void send(String recipientEmail, String ccEmail, String title, String message)
throws AddressException, MessagingException {
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("kipid84@naver.com"));
msg.setRecipients(
Message.RecipientType.TO,
InternetAddress.parse(recipientEmail)
);
msg.setSubject(title);
msg.setContent(message, "text/html; charset=utf-8");
Transport.send(msg);
} catch (MessagingException e) {
e.printStackTrace();
}
}
public static void main(String... args) throws Exception {
NaverMail.sendVeriKey("kipid84@naver.com", "kipid", "dfij378asd91fa9sdf1kraq9defr134nr913hjred9af");
NaverMail.sendChangePwd("kipid", "kipid84@naver.com", "29riw7fus8dfu8348u48f8uf", "ko");
}
}
```/
### Error in AWS server
Windows firewall 도 다 열어보고 별 짓을 다 해 봤는데도 해결이 안됨 ㅡ,.ㅡ;;; Security 어쩌구에서 뭔가 막고 있나???
```[.scrollable.lang-java]
Compiling NaverMail.java
--- OUTPUT: recoeve.http.NaverMail ---
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1;
nested exception is:
java.net.ConnectException: Connection timed out: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
at javax.mail.Service.connect(Service.java:388)
at javax.mail.Service.connect(Service.java:246)
at javax.mail.Service.connect(Service.java:195)
at javax.mail.Transport.send0(Transport.java:254)
at javax.mail.Transport.send(Transport.java:124)
at recoeve.http.NaverMail.send(NaverMail.java:90)
at recoeve.http.NaverMail.sendVeriKey(NaverMail.java:47)
at recoeve.http.NaverMail.main(NaverMail.java:97)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:580)
at java.base/sun.nio.ch.Net.connect(Net.java:569)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:666)
at java.base/java.net.Socket.connect(Socket.java:600)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
... 9 more
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1;
nested exception is:
java.net.ConnectException: Connection timed out: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
at javax.mail.Service.connect(Service.java:388)
at javax.mail.Service.connect(Service.java:246)
at javax.mail.Service.connect(Service.java:195)
at javax.mail.Transport.send0(Transport.java:254)
at javax.mail.Transport.send(Transport.java:124)
at recoeve.http.NaverMail.send(NaverMail.java:90)
at recoeve.http.NaverMail.sendChangePwd(NaverMail.java:39)
at recoeve.http.NaverMail.main(NaverMail.java:98)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:580)
at java.base/sun.nio.ch.Net.connect(Net.java:569)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:666)
at java.base/java.net.Socket.connect(Socket.java:600)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
... 9 more
[Finished in 48.8s]
```/
### Error in Vert.x server running on AWS now.
```[.scrollable.lang-java]
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.naver.com, 587; timeout -1;
nested exception is:
java.net.ConnectException: Connection timed out: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
at javax.mail.Service.connect(Service.java:388)
at javax.mail.Service.connect(Service.java:246)
at javax.mail.Service.connect(Service.java:195)
at javax.mail.Transport.send0(Transport.java:254)
at javax.mail.Transport.send(Transport.java:124)
at recoeve.http.NaverMail.send(NaverMail.java:90)
at recoeve.http.NaverMail.sendChangePwd(NaverMail.java:39)
at recoeve.db.RecoeveDB.forgotPwd(RecoeveDB.java:784)
at recoeve.http.Recoeve.lambda$start$16(Recoeve.java:594)
at io.vertx.core.impl.future.FutureImpl$1.onSuccess(FutureImpl.java:91)
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
at io.vertx.core.http.impl.HttpEventHandler.handleEnd(HttpEventHandler.java:79)
at io.vertx.core.http.impl.Http2ServerRequest.handleEnd(Http2ServerRequest.java:198)
at io.vertx.core.http.impl.Http2ServerStream.handleEnd(Http2ServerStream.java:198)
at io.vertx.core.http.impl.VertxHttp2Stream.lambda$new$1(VertxHttp2Stream.java:62)
at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:255)
at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:134)
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:158)
at io.vertx.core.http.impl.VertxHttp2Stream.onEnd(VertxHttp2Stream.java:140)
at io.vertx.core.http.impl.Http2ServerStream.onEnd(Http2ServerStream.java:123)
at io.vertx.core.http.impl.VertxHttp2Stream.onEnd(VertxHttp2Stream.java:135)
at io.vertx.core.http.impl.Http2ConnectionBase.onDataRead(Http2ConnectionBase.java:317)
at io.vertx.core.http.impl.Http2ServerConnection.onDataRead(Http2ServerConnection.java:44)
at io.netty.handler.codec.http2.Http2FrameListenerDecorator.onDataRead(Http2FrameListenerDecorator.java:36)
at io.netty.handler.codec.http2.Http2EmptyDataFrameListener.onDataRead(Http2EmptyDataFrameListener.java:49)
at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$FrameReadListener.onDataRead(DefaultHttp2ConnectionDecoder.java:307)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readDataFrame(DefaultHttp2FrameReader.java:415)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.processPayloadState(DefaultHttp2FrameReader.java:250)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readFrame(DefaultHttp2FrameReader.java:159)
at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder.decodeFrame(DefaultHttp2ConnectionDecoder.java:173)
at io.netty.handler.codec.http2.DecoratingHttp2ConnectionDecoder.decodeFrame(DecoratingHttp2ConnectionDecoder.java:63)
at io.netty.handler.codec.http2.Http2ConnectionHandler$FrameDecoder.decode(Http2ConnectionHandler.java:393)
at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:453)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.vertx.core.http.impl.VertxHttp2ConnectionHandler.channelRead(VertxHttp2ConnectionHandler.java:416)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1383)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1246)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1295)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:580)
at java.base/sun.nio.ch.Net.connect(Net.java:569)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:666)
at java.base/java.net.Socket.connect(Socket.java:600)
at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:359)
at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
... 66 more
```/
## RRA
- https://mvnrepository.com/artifact/com.sun.mail/jakarta.mail/2.0.1
- javamail.java.net - API docs - Package com.sun.mail.smtp summary
- developers.google.com - Google App Engine - Java - Using JavaMail to Send Mail
- stackoverflow.com - Send email using java, 2010-09-06, asked by Mohit Bansal.
// I used the answer by Cheok Yan Cheng. The code is written by doraemon (the same person??).
728x90
반응형
'[IT/Programming] > HTML related' 카테고리의 다른 글
Super Easy Edit (SEE | 엄청 쉬운 편집) of docuK (문서K: MarkDown | 마크다운): 사용 설명서. (0) | 2024.04.23 |
---|---|
VtoV Back-end 개발자용 과제 테스트 (1) | 2024.04.23 |
HTML a href tag with onclick return (2) | 2024.04.07 |
v.qq.com 동영상 퍼오기 (1) | 2024.02.18 |
.webp, .webm, .avif, .mp4 를 img tag, video tag 로 로딩 테스트 (Loading test) (4) | 2024.02.18 |
HTML 에서 동영상 연속 재생하기 (playlist, shuffle, replay) (0) | 2024.02.11 |
Getting Data from Google Spreadsheet or Excel (1) | 2024.02.09 |