본문 바로가기

Java Mail/Email, Web, File appended

Email using Apache Fileupload

JavaMail1.4, Apache upload 1.2 를 이용하여 첨부파일을 가진 메일을 전송하는 예

환경: JDK6, Eclipse 3.5, Apache Fileupload1.2, JavaMail 1.4, Tomcat 6

구성파일: mailForm.jsp, MailServlet, ApacheUploadBean, MailDTO, MailProcBean, sendResult.jsp

mailForm.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!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=EUC-KR">
<title>메일 보내기 폼</title>
<style>
 form{ border:1px solid grey; width: 500px;}
 caption { margin-top:10px; margin-bottom: 10px; font-size: 18pt; }
 th { text-align: right; width:120px;}
 td { text-align: left; }
 .btn { text-align: center; }
 textarea { width:380px; }
 input.text{ width:380px; }
 input.btn { width:70px; }
 table { padding: 10 10 10; margin-right:10px; }
 .file { width:385px; }
</style>
</head>
<body><br/><br/>
<center>
 <form action="MailServlet" method="post" enctype="multipart/form-data">
 <table border="1" cellspacing="0" rules="none" cellpadding="10">
  <caption>메일 쓰기</caption>
  <tr><th>제 목</th><td><input class="text" type="text" name="subject" value="메일보내기 연습"/></td></tr>
  <tr><th>보내는 사람</th><td><input class="text"  type="text" name="from" value="who@micropilot.co.kr"/></td></tr>
  <tr><th>받는 사람</th><td><input class="text"  type="text" name="to" value="who@paran.com"/></td></tr>
  <tr><th>내 용</th><td><textarea name="msg" rows="5" cols="20">잘 들어가야 할텐데....</textarea></tr>
  <tr><th>파일1</th><td><input type="file" name="file" class="file"/></td></tr>
  <tr><th>파일2</th><td><input type="file" name="file" class="file"/></td></tr>
  <tr><th>파일3</th><td><input type="file" name="file" class="file"/></td></tr>
  <tr><td colspan="2"> </td></tr>
  <tr><td colspan="2" style="text-align:center; padding-bottom: 10px;">
   <input type="submit" value="메일전송"/>
   <input type="reset" value="취 소"/> </td></tr>
 </table>
 </form>
</center>
</body>
</html>



MailServlet.java

package mail;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import bean.ApacheUploadBean;
import bean.MailProcBean;
import bean.MailDTO;

public class MailServlet extends HttpServlet{

 @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse resp)
   throws ServletException, IOException {
  
  request.setCharacterEncoding("euc-kr");
  ApacheUploadBean uploadBean = new ApacheUploadBean(request);
  MailDTO mailDTO = uploadBean.getMailDTO();
  MailProcBean mailProc = new MailProcBean();
  boolean ok = mailProc.send(mailDTO);
  request.setAttribute("result", ok);
  request.getRequestDispatcher("/sendResult.jsp").forward(request, resp);

 }
 
}


ApacheUploadBean.java

package bean;

import java.io.*;
import java.util.*;

import javax.servlet.http.*;

import org.apache.commons.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;
import org.apache.commons.io.*;

import bean.MailDTO;
/* Apache Fileupload 라이브러리를 이용하여 폼에서 전달된 데이터에서
 * 텍스트 필드와 파일을 구분하여 파일은 특정 디렉토리에 저장하고
 * 텍스트 필드에 입력된 값과 파일의 경로 등을 MailDTO에 저장한다
 */
public class ApacheUploadBean {
 private HttpServletRequest request;
 private MailDTO mailDTO;
 private String saveDir = "D:/append";
 
 public ApacheUploadBean() {}

 public ApacheUploadBean(HttpServletRequest request) {
  this.request = request;
  upload();
 }

 public void setRequest(HttpServletRequest request) {
  this.request = request;
 }

 public MailDTO getMailDTO() {
  return mailDTO;
 }

 public void setSaveDir(String saveDir) {
  this.saveDir = saveDir;
 }

 public void upload(){
  boolean isMultipart = ServletFileUpload.isMultipartContent(this.request);
  if (!isMultipart) {
  }else {
   FileItemFactory factory = new DiskFileItemFactory();
   ServletFileUpload upload = new ServletFileUpload(factory);
   List items = null;
   try {
    items = upload.parseRequest(this.request);
   } catch (FileUploadException e) {
    e.printStackTrace();
   }
   Iterator itr = items.iterator();
   this.mailDTO = new MailDTO();
   while (itr.hasNext()) {
    FileItem item = (FileItem) itr.next();
    if (item.isFormField()) { // 파일이 아닌 폼필드에 입력한 내용을 가져옴.
     try{
      if(item!=null && item.getFieldName().equals("subject")) {
       String subject = item.getString("KSC5601");//form field 안에 입력한 데이터를 가져옴
       this.mailDTO.setSubject(subject);
      }else if(item!=null && item.getFieldName().equals("from")) {
       String from = item.getString("KSC5601");
       this.mailDTO.setFrom(from);
      }else if(item!=null && item.getFieldName().equals("to")) {
       String to = item.getString("KSC5601");
       this.mailDTO.setTo(to);
      }else if(item!=null && item.getFieldName().equals("msg")) {
       String msg = item.getString("KSC5601");
       this.mailDTO.setMsg(msg);
      }
     }catch(UnsupportedEncodingException use){use.printStackTrace();}
    } else { // 폼 필드가 아니고 파일인 경우
     try {
      String itemName = item.getName();//로컬 시스템 상의 파일경로 및 파일 이름 포함
      if(itemName==null || itemName.equals("")) continue;
      String fileName = FilenameUtils.getName(itemName);// 경로없이 파일이름만 추출함
      // 파일이름 중복검사 및 그에 따른 새이름 설정
      File f = checkExist(fileName);
      item.write(f);// 지정 경로에 파일을 저장함
      if(mailDTO.getFileMap()==null)
         mailDTO.setFileMap(new HashMap<String, File>());
      this.mailDTO.getFileMap().put(fileName, f);// 원래이름, 변경된 이름을 맵에 저장
     } catch (Exception e) { e.printStackTrace(); }
    } // end of else
   }  // end of while
  }   // end of else
 }  // end of upload

 /* 이미 동일이름의 파일이 존재하면 새로 저장되는 파일의 이름 변경 */
 private File checkExist(String fileName){
  File f = new File(saveDir+"/"+fileName);
  if(f.exists()) {
   StringBuffer sb = new StringBuffer(fileName);
   sb.insert(sb.lastIndexOf("."),"-"+new Date().getTime());
   f = new File(saveDir+"/"+sb.toString());
  }
  return f;
 }
}



MailDTO.java

package bean;

import java.io.File;
import java.util.HashMap;

public class MailDTO {
 
 private String subject;
 private String from;
 private String to;
 private String msg;
 private HashMap<String, File> fileMap;

 public MailDTO() {}

 public MailDTO(String subject, String from, String to, String msg) {
  this.subject = subject;
  this.from = from;
  this.to = to;
  this.msg = msg;
 }

 public String getSubject() {
  return subject;
 }

 public String getFrom() {
  return from;
 }

 public String getTo() {
  return to;
 }

 public String getMsg() {
  return msg;
 }

 public void setSubject(String subject) {
  this.subject = subject;
 }

 public void setFrom(String from) {
  this.from = from;
 }

 public void setTo(String to) {
  this.to = to;
 }

 public void setMsg(String msg) {
  this.msg = msg;
 }

 public HashMap<String, File> getFileMap() {
  return fileMap;
 }

 public void setFileMap(HashMap<String, File> fileMap) {
  this.fileMap = fileMap;
 }
}


MailProcBean.java

package bean;

import java.io.*;
import java.util.*;

import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
/* Gmail SMTP 서버를 이용하여 메일을 전송하는 예
 * 서블릿이나 JSP에서 이 클래스를 사용하려면 다음과 같이.....
 * MailProcBean bean = new MailProcBean();
 * boolean ok = bean.send(mailDTO);
 * */
public class MailProcBean {

 private Session session;
 
 public MailProcBean() {
  createSession();
 }
 
 private void createSession(){
   Properties p = new Properties();
   p.put("mail.smtp.user", "my_id@gmail.com"); // Google계정@gmail.com으로 설정
   p.put("mail.smtp.host", "smtp.gmail.com");
   p.put("mail.smtp.port", "465");
   p.put("mail.smtp.starttls.enable","true");
   p.put( "mail.smtp.auth", "true");

   p.put("mail.smtp.debug", "true");
   p.put("mail.smtp.socketFactory.port", "465");
   p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
   p.put("mail.smtp.socketFactory.fallback", "false");
   try {
     Authenticator auth = new SMTPAuthenticator();
     this.session = Session.getInstance(p, auth);
     //this.session.setDebug(true);
   }catch (Exception e) {
  e.printStackTrace();
   }
 }
 
 public boolean send(MailDTO dto){
  try{
     MimeMessage mimeMsg = new MimeMessage(this.session);
     mimeMsg .setSubject(dto.getSubject());
     Address fromAddr = new InternetAddress(dto.getFrom()); // 보내는 사람의 메일주소
     mimeMsg .setFrom(fromAddr);
     Address toAddr = new InternetAddress(dto.getTo());  // 받는 사람의 메일주소
     mimeMsg .addRecipient(Message.RecipientType.TO, toAddr);
     if(dto.getFileMap()!=null){
      MimeMultipart multiPart = new MimeMultipart();
      createTextPart(dto.getMsg(),multiPart );
      createFilePart(dto.getFileMap(),multiPart );
      mimeMsg .setContent(multiPart );
     }else {
      mimeMsg.setContent(dto.getMsg(), "text/plain;charset=KSC5601");
     }
     Transport.send(mimeMsg );
      if(dto.getFileMap()!=null) deleteFiles(dto.getFileMap());
     return true;
   }
   catch (Exception mex) {
     mex.printStackTrace();
   }
   return false;
 }
 
 /* 텍스트 파트를 생성하여 Multipart에 추가한다 */
 private void createTextPart(String msg, Multipart multiPart){
  MimeBodyPart textPart = new MimeBodyPart();
  try{
   textPart.setText(msg);
   multiPart.addBodyPart(textPart);
  }catch(MessagingException me){
   me.printStackTrace();
  }

 }
 
 /* 파일 파트를 생성하여 Multipart에 추가한다 */
 private void createFilePart(HashMap<String, File>fileMap, Multipart multiPart){
  Set<String> keys = fileMap.keySet();
  Iterator<String> it = keys.iterator();
  while(it.hasNext()){
   MimeBodyPart filePart = new MimeBodyPart();
   String originName = it.next();
   File file = fileMap.get(originName);
   FileDataSource fds = new FileDataSource(file);
   DataHandler dh = new DataHandler(fds);
   try{
    filePart.setDataHandler(dh);
    String fileName = null;
    fileName = new String(originName.getBytes("KSC5601"), "8859_1");
    filePart.setFileName(fileName);
    multiPart.addBodyPart(filePart);
   }catch(Exception me){
    me.printStackTrace();
   }
  }
 }
 
 private void deleteFiles(HashMap<String,File>fileMap){
  Set<String> keys = fileMap.keySet();
  Iterator<String> it = keys.iterator();
  while(it.hasNext()){
   String originName = it.next();
   File f = fileMap.get(originName);
   f.delete();
  }
 }
} // end of class

class SMTPAuthenticator extends javax.mail.Authenticator {

  public PasswordAuthentication getPasswordAuthentication() {
   return new PasswordAuthentication("my_id", "my_pwd"); // Google id, pwd, 주의) @gmail.com 은 제외하세요
  }
}


sendResult.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
 boolean ok = (Boolean)request.getAttribute("result");
 String msg = null; 
 if(ok) msg = "성공적으로 메일을 전송했습니다";
 else msg = "메일을 보내는 중에 오류가 발생했습니다";
%>
<script>
 alert("<%=msg%>");
</script>