메일 서버 원리
-
대부분 회사마다 메일서버는 별도로 존재한다. ex) mail.naver.com
-
임직원의 수가 많아지면 서버 부하를 분산시키기 위해서, 메일 송수신에 따라 서버를 두개를 나눈다. ex) pop.naver.com,smtp.naver.com
- SMTP (Simple Mail Transfer Protocol) : 메일을 보낼때 사용하는 프로토콜이다. 상업용으로 돈을 주고 사야한다.
- POP (Post Office Protocol) : 메일을 받을때 사용
- IMAP(Internet Mail Access Protocol) : POP3와 동일
- POP3는 move 개념, IMAP은 copy 개념
- 자주 사용하는 네이버 메일의 환경설정 조회를 통해 POP3/IMAP 설정을 확인해보자.
메일 서버 설치
- 아파치에서 제공하는 메일 서버 james 다운로드한다. https://james.apache.org/download.cgi
- javamail api 다운로드한다. https://www.oracle.com/technetwork/java/index-138643.html
- Javabean Activation Framework 다운로드한다. https://www.oracle.com/technetwork/java/javase/downloads/index-135046.html
- lib 폴더에 추가한다.
메일 서버(james) 가동여부 확인하기
CMD에 telnet 명령어 처리가 안되는 경우
telnet은 윈도우즈 기능에 해당한다. 이럴 경우 제어판에서 텔넷 클라이언트 기능을 사용하도록 변경해주면 된다.
경로 : 제어판 - 프로그램 제거 또는 변경 - Windows 기능 사용/사용 안함
갑자기 telnet을 확인하려는 것은 서버가 정상적으로 가동되는 지 확인하기 위해서다.
메일 작성 페이지
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>메일보내기</title>
</head>
<body>
<form action="sendMail_ok.jsp" method="post">
<table border="1" align="center" style="font-size: 10pt;" cellpadding="0" cellspacing="0">
<tr>
<td>보내는사람 이름</td>
<td><input type="text" name="senderName" size="50"/></td>
</tr>
<tr>
<td>보내는사람 E-Mail</td>
<td><input type="text" name="senderEmail" size="50"/></td>
</tr>
<tr>
<td>받는사람 E-Mail</td>
<td><input type="text" name="receiverEmail" size="50"/></td>
</tr>
<tr>
<td>제목</td>
<td><input type="text" name="subject" size="50"/></td>
</tr>
<tr>
<td>내용</td>
<td><textarea rows="8" cols="50" name="content"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="메일 보내기">
</td>
</tr>
</table>
</form>
</body>
</html>
메일 작성 페이지
- javax.mail.Session : Java Mail API를 사용하는 출발점이 되는 클래스.
- javax.mail.Message : Message 클래스는 메일을 표현하기 위해 사용되는 추상 클래스로 주제, 수신자의 이메일주소, 발송자의 이메일 주소, 보낸 날짜와 같은 실제 이메일 메시지의 세부 사항을 나타낸다.
- MimeMessage 클래스는 Message 추상 클래스로부터 상속받은 인터넷 메일 클래스로 메일에 여러 개의 파일을 첨부시켜서 사용
- java.util.Properties는 getProperties()메소드를 사용하여 시스템의 환경변수 값을 얻어올 수 있다. 환경변수의 설정은 Key와 Value 쌍으로 저장(자료형 Map)되어 있다.
JavaMail API를 이용하여 메일을 전송하는 과정
- javax.mail.Session 클래스의 인스턴스를 구한다.
- javax.mail.Message 클래스를 사용하여 전송하고자 하는 메일 메시지를 작성한다. (여기서의 메세지는 text, html,file 등이 올 수 있다.)
- javax.mail.Transport 클래스를 사용하여 작성한 메일을 전송한다.
<%@page import="javax.mail.Transport"%>
<%@page import="javax.mail.internet.InternetAddress"%>
<%@page import="javax.mail.Message"%>
<%@page import="javax.mail.internet.MimeMessage"%>
<%@page import="javax.mail.Session"%>
<%@page import="java.util.Properties"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
//sendMail페이지에서 보낸 5개의 데이터 받아야 함
String senderName = request.getParameter("senderName");
String senderEmail = request.getParameter("senderEmail");
String receiverEmail = request.getParameter("receiverEmail");
String subject = request.getParameter("subject");
String content = request.getParameter("content");
String host = "localhost"; //192.168.16.16
//1.javax.mail.Session 클래스의 인스턴스를 구한다.
Properties prop = System.getProperties(); //시스템의 환경설정
Session ssn = Session.getInstance(prop,null);//환경설정 세션 생성 (시스템의 정보를 읽어와서 세션을 생성)
try{
//2.javax.mail.Message 클래스를 사용하여 전송하고자 하는 메일 메시지를 작성
MimeMessage message = new MimeMessage(ssn);//MimeMessage는 실제 메일내용을 담음
//message객체에 메일속성 설정
message.addRecipient(Message.RecipientType.TO, new InternetAddress(receiverEmail)); //수신인 설정
message.setFrom(new InternetAddress(senderEmail,senderName,"UTF-8"));//발신인 설정
message.setSubject(subject, "UTF-8");//제목 설정
message.setContent(content,"text/plain;charset=UTF-8");//내용 설정
//메일 전송
//3.javax.mail.Transport 클래스를 사용하여 작성한 메일을 전송
Transport tp = ssn.getTransport("smtp");//보낼때 사용하는 프로토콜
tp.connect(host, "", "");//ip, id, pw 가상으로 진행하므로 id, pw 생략
tp.sendMessage(message, message.getAllRecipients());
tp.close();
out.print("메일 전송 완료!!");
}catch(Exception e){
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>확인페이지</title>
</head>
<body>
</body>
</html>
첨부파일과 함께 메일 작성하기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="<%=cp%>/mail/data/style.css" type="text/css"/>
<script type="text/javascript" src="<%=cp%>/mail/data/mail.js"></script>
</head>
<body onload="document.myForm.sendName.focus();">
<br/><br/>
<table width="600" border="2" cellpadding="0" cellspacing="0" bordercolor="#d6d4a6" align="center">
<tr height="40">
<td style="padding-left: 20px;">
<b>E_mail전송</b>
</td>
</tr>
</table>
<br/><br/>
<form action="mailSend_ok.jsp" name="myForm" method="post" enctype="multipart/form-data">
<table width="600" border="0" cellpadding="3" cellspacing="0" align="center">
<tr>
<td colspan="2" height="3" bgcolor="#dbdbdb" align="center"></td>
</tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
보내는 사람 이름
</td>
<td width="460" style="padding-left: 10px;">
<input type="text" name="senderName" size="35" maxlength="20" class="boxTF">
</td>
</tr>
<tr>
<td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td>
</tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
보내는 사람 E-Mail
</td>
<td width="460" style="padding-left: 10px;">
<input type="text" name="senderEmail" size="35" maxlength="20" class="boxTF">
</td>
</tr>
<tr>
<td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td>
</tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
받는 사람 E-Mail
</td>
<td width="460" style="padding-left: 10px;">
<input type="text" name="receiverEmail" size="35" maxlength="20" class="boxTF">
</td>
</tr>
<tr>
<td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td>
</tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
제 목
</td>
<td width="460" style="padding-left: 10px;">
<input type="text" name="subject" size="64" maxlength="100" class="boxTF">
</td>
</tr>
<tr>
<td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td>
</tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
내 용
</td>
<td width="460" style="padding-left: 10px;">
<textarea rows="12" cols="62" name="content" class="boxTA"></textarea>
</td>
</tr>
<tr><td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td></tr>
<tr><td colspan="2" height="10" ></td></tr>
<tr><td colspan="2" height="1" bgcolor="#dbdbdb" align="center"></td></tr>
<tr>
<td width="140" height="30" bgcolor="#eeeeee" style="padding-left: 20px;">
첨부파일
</td>
<td width="460" style="padding-left: 10px;">
<input type="file" name="fileName" maxlength="100" size="48" class="boxTF"/>
</td>
</tr>
<tr><td colspan="2" height="3" bgcolor="#dbdbdb" align="center"></td></tr>
</table>
<table width="600" border="0" cellpadding="3" cellspacing="0" align="center">
<tr align="center">
<td height="40">
<input type="button" value="전송하기" class="btn2" onclick="mailSend();"/>
<input type="reset" value="다시입력" class="btn2" onclick="document.myForm.senderName.focus();"/>
</td>
</tr>
</table>
</form>
</body>
</html>
첨부파일과 함께 메일 전송하기
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="com.mail.MailSend"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
String root = getServletContext().getRealPath("/");
String path = root + File.separator + "pds" + File.separator + "mailFile";
//파일 객체 생성
File f = new File(path);
if(!f.exists())
f.mkdirs();//해당경로파일 없을경우 디렉토리 생성
String encType = "UTF-8";
int maxFileSize = 10*1024*1024;
//메일전송 객체 생성
MailSend mail = new MailSend();
//파일업로드
MultipartRequest mr = new MultipartRequest(request,path,maxFileSize,encType,new DefaultFileRenamePolicy());
mail.setSenderName(mr.getParameter("senderName"));
mail.setSenderEmail(mr.getParameter("senderEmail"));
mail.setReceiverEmail(mr.getParameter("receiverEmail"));
mail.setSubject(mr.getParameter("subject"));
mail.setContent(mr.getParameter("content"));
//첨부파일
String fileName = mr.getFilesystemName("fileName"); //mailSend.jsp에서 첨부파일의 fileName
if(fileName!=null&&!fileName.equals("")){
String fileFullPath = path + File.separator + fileName;
mail.setFileFullPath(fileFullPath);
mail.setOriginalFileName(mr.getOriginalFileName("fileName"));
}
mail.sendMail();
out.print("메일 전송 완료!!");
%>
public class MailSend {
private String receiverEmail;
private String senderName;
private String senderEmail;
private String subject;
private String content;
private String fileFullPath;//서버에 메일파일을 업로드한 뒤 첨부하여 전송하는 것으로 파일경로가 필요하다
private String originalFileName;
private String mailHost;//메일서버
private String mailType;//메일타입
//생성자(메일 호스트 지정 없을 경우 localhost)
public MailSend(){
this.mailHost = "localhost";
this.mailType = "text/html;charset=UTF-8";
}
//오버라이드된 생성자(사용자가 메일호스트를 지정할 경우 반영)
public MailSend(String mailHost){
this.mailHost = mailHost;
this.mailType = "text/html;charset=UTF-8";
}
public String getReceiverEmail() {
return receiverEmail;
}
public void setReceiverEmail(String receiverEmail) {
this.receiverEmail = receiverEmail;
}
public String getSenderName() {
return senderName;
}
public void setSenderName(String senderName) {
this.senderName = senderName;
}
public String getSenderEmail() {
return senderEmail;
}
public void setSenderEmail(String senderEmail) {
this.senderEmail = senderEmail;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getFileFullPath() {
return fileFullPath;
}
public void setFileFullPath(String fileFullPath) {
this.fileFullPath = fileFullPath;
}
public String getOriginalFileName() {
return originalFileName;
}
public void setOriginalFileName(String originalFileName) {
this.originalFileName = originalFileName;
}
public String getMailHost() {
return mailHost;
}
public void setMailHost(String mailHost) {
this.mailHost = mailHost;
}
public String getMailType() {
return mailType;
}
public void setMailType(String mailType) {
if(mailType.equalsIgnoreCase("TEXT")){
this.mailType = "text/plain;charset=UTF-8";
}else{
this.mailType = "text/html;charset=UTF-8";
}
}
public boolean sendMail(){
try {
//1.세션 생성
Properties props = System.getProperties();
props.put("main.smtp.host", mailHost);
Session session = Session.getDefaultInstance(props,null);
//2. 메일을 보낼 메세지 클래스 생성
Message msg = new MimeMessage(session);
//2-1. 보내는사람
if(senderName==null||senderName.equals("")){
msg.setFrom(new InternetAddress(senderEmail));//이름이 없을 경우 이메일주소만 전송
}else{
msg.setFrom(new InternetAddress(senderEmail,senderName,"UTF-8"));//이름이 있을 경우 함께 전송
}
//2-2. 받는사람
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(receiverEmail));
//2-3. 제목
msg.setSubject(subject);
//2-4. HTML형식인 경우 엔터를 <br/>로 변환
if(mailType.indexOf("text/html")!=-1){
content = content.replaceAll("\n", "<br/>");
}
//2-5. 메일 내용과 파일을 MimeBodyPart로 나누어 담음
makeMessage(msg);
msg.setHeader("X-Mailer", senderName);
//2-6. 메일보낸날짜
msg.setSentDate(new Date());
//3. 메일전송
Transport.send(msg);
//4. 메일 전송 후 파일 삭제(이게 없으면, 파일 보낸 후 계속 서버에 파일 존재)
if(fileFullPath!=null){
File f = new File(fileFullPath);
if(f.exists())
f.delete();
}
} catch (MessagingException e) {
System.out.println(e.toString());
return false;
} catch (Exception e) {
System.out.println(e.toString());
return false;
}
return true;
}
private void makeMessage(Message msg) throws MessagingException{
if(fileFullPath==null||fileFullPath.equals("")){
//파일을 첨부하지 않았을경우
msg.setText(content);
msg.setHeader("Content-Type", mailType);
}else{
//파일을 첨부한 경우
//1. 메일내용
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(content);
mbp1.setHeader("Content-Type", mailType);
//2. 첨부파일
MimeBodyPart mbp2 = new MimeBodyPart();
FileDataSource fds = new FileDataSource(fileFullPath);//fileFullPath는 파일의 실제 물리적인 주소
mbp2.setDataHandler(new DataHandler(fds));
try {
if(originalFileName==null||originalFileName.equals("")){
mbp2.setFileName(MimeUtility.encodeWord(fds.getName()));
}else{
mbp2.setFileName(MimeUtility.encodeWord(originalFileName));
}
} catch (UnsupportedEncodingException e) {//try문에서 에러 발생시 UnsupportedEncodingException에서 예외처리됨
System.out.println(e.toString());
}
//내용과 파일 합침
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(mbp2);
//메세지 클래스에 content 입력
msg.setContent(mp);
}
}
}
전송이 완료된 후에 별도로 파일을 관리하지 않을 것이다. 120~125 라인을 작성해서 첨부파일과 함께 메일 전송시, 파일 삭제가 진행된다.
메일서버 설치 및 운영
'Dev > JSP & Servlet' 카테고리의 다른 글
Servlet - 이미지 게시판 만들기 (1) | 2019.03.06 |
---|---|
Servlet-api 임포트 오류시 (0) | 2019.03.06 |
Servlet - ServletContextListener 구현 (0) | 2019.03.06 |
필터구현 (로그인 검사, 캐릭터 인코딩, 시간 측정) (0) | 2019.03.06 |
cos.jar를 이용한 파일 업로드(2)-파일 업로드,다운로드.삭제 (0) | 2019.03.04 |