SMTP 방식으로 메일 전송 + 압축 모듈
1. 메일 전송(SMTP 방식)
- 컴퓨터로 이메일을 전송할 때, sendMail, qmail 등의 메일 서버 프로그램을 사용함
- 메일 client와 미리 정해진 규칙들을 사용하여 메일을 발송
- 정해진 규칙 = SMTP 프로토콜
- 텔넷으로 메일서버에 연결하여 SMTP 프로토콜에 맞게 명령을 내리면 메일이 발송됨
1) pom.xml에 메일발송에 필요한 라이브러리 추가
2) Controller 소스 작성
예) Controller 예제1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
/** 자바 메일 발송
* @throws MessagingException
* @throws AddressException **/
@RequestMapping(value = "/mailSender")
public void mailSender(HttpServletRequest request, ModelMap mo) throws AddressException, MessagingException {
// 네이버라면 smtp.naver.com 을 입력
// Google이라면 smtp.gmail.com 을 입력
String host = "smtp.naver.com";
final String username = "XXXXXXXX"; //네이버 아이디를 입력. @ 이후 주소는 입력X
final String password = "YYYYYYYY"; //네이버 이메일 비밀번호를 입력
int port=465; //포트번호
//메일 내용
String recipient = "WWWWWWW@gmail.com"; //받는 사람의 메일주소
String subject = "메일테스트"; //메일 제목
String body = username+"님으로 부터 메일을 받았습니다."; //메일 내용
Properties props = System.getProperties(); // 정보를 담기 위한 객체 생성
// SMTP 서버 정보 설정
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.trust", host);
//Session 생성
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
String un=username;
String pw=password;
protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
return new javax.mail.PasswordAuthentication(un, pw);
}
});
session.setDebug(true); //for debug
Message mimeMessage = new MimeMessage(session); //MimeMessage 생성
mimeMessage.setFrom(new InternetAddress("XXXXXXXX@naver.com")); //발신자 세팅 , 보내는 사람의 이메일주소를 한번 더 입력, @이후 주소까지 입력
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient)); //수신자 세팅 //.TO 외에 .CC(참조) .BCC(숨은참조) 도 있음
mimeMessage.setSubject(subject); //제목 세팅
mimeMessage.setText(body); //내용 세팅
Transport.send(mimeMessage); //javax.mail.Transport.send() 이용
}
| cs |
예) Controller 예제2 (1과 다른 방식)
- but, 전체적인 방식 자체는 비슷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
package Example;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class MailExam {
public static void main(String[] args){
try{
new MailExam();
}catch(Exception e){
System.out.println("Error");
}
}
public MailExam() throws Exception{
Properties props = new Properties(); //프로퍼티 객체 생성
props.setProperty("mail.transport.protocol", "smtp"); //smtp 방식임 선언
props.setProperty("mail.host", "smtp.gmail.com"); //메일 호스트 주소 선언(다른 메일 주소로 변경 가능)
props.put("mail.smtp.auth", "true"); //smtp 권한 획득
props.put("mail.smtp.port", "465"); //포트번호
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); //소켓 사용
props.put("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.quitwait", "false");
//권한 획득 + 발송자 이메일 리턴
Authenticator auth = new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("nowonbun@gmail.com", "");
}
};
//세션 설정
Session session = Session.getDefaultInstance(props,auth);
MimeMessage message = new MimeMessage(session);
message.setSender(new InternetAddress("nowonbun@gmail.com")); //발송자 메일 주소
message.setSubject("test"); //발송 메일 제목
message.setRecipient(Message.RecipientType.TO, new InternetAddress("nowonbun@naver.com")); //수신자 메일 주소
Multipart mp = new MimeMultipart();
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText("Test Contents"); //메일 내용 담기
mp.addBodyPart(mbp1);
//첨부 파일
String filename = "f:\\test.xls";
if(filename != null){
if(fileSizeCheck(filename)){
MimeBodyPart mbp2 = new MimeBodyPart();
FileDataSource fds = new FileDataSource(filename);
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B"));
mp.addBodyPart(mbp2);
}else{
throw new Exception("file size overflow !");
}
}
//MIME 타입 설정
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mc);
message.setContent(mp);
Transport.send(message); //메일 발송
}
//파일 사이즈 체크
protected boolean fileSizeCheck(String filename) {
if (new File(filename).length() > (1024 * 1024 * 2.5)) {
return false;
}
return true;
}
}
| cs |
2. 자바 zip 압축모듈
- 자바 파일 전송은 Java.IO를 이용
- InputStream, OutputStream 이용: 바이트 자원이 아닌 바이너리 자원의 입, 출력
- ZipInpitStream, ZipOutputStream 이용: 압축 파일의 입, 출력
예) 예제 소스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class Zip {
/**
* 압축 메서드
* @param path 경로
* @param outputFileName 출력파일명
*/
public static void compress(String path,String outputFileName) throws Throwable{
//파일 인스턴스 생성
File file = new File(path);
//lastIndexOf는 오른쪽부터 문자열을 셈 => 파일 확장자 찾기에 주로 사용
int pos = outputFileName.lastIndexOf(".");
if(!outputFileName.substring(pos).equalsIgnoreCase(".zip")){
outputFileName += ".zip";
}
// 압축 경로 체크
if(!file.exists()){
throw new Exception("Not File!");
}
// 출력 스트림 초기화
FileOutputStream fos = null;
// 압축 스트림 초기화
ZipOutputStream zos = null;
//압축, 출력 스트림 예외 체크
try{
fos = new FileOutputStream(new File(outputFileName));
zos = new ZipOutputStream(fos);
// 디렉토리 검색
searchDirectory(file,zos);
}catch(Throwable e){
throw e;
}finally{
if(zos != null) zos.close();
if(fos != null) fos.close();
}
}
/**
* 다형성
*/
private static void searchDirectory(File file, ZipOutputStream zos) throws Throwable{
searchDirectory(file,file.getPath(),zos);
}
/**
* 디렉토리 탐색
* @param file 현재 파일
* @param root 루트 경로
* @param zos 압축 스트림
*/
private static void searchDirectory(File file,String root,ZipOutputStream zos) throws Exception{
//지정된 파일이 디렉토리인지 파일인지 검색
if(file.isDirectory()){
//디렉토리일 경우 재탐색(재귀)
File[] files = file.listFiles();
for(File f : files){
searchDirectory(f,root,zos);
}
}else{
//파일일 경우 압축
compressZip(file,root,zos);
}
}
/**
* 압축 메서드
* @param file
* @param root
* @param zos
* @throws Exception
*/
private static void compressZip(File file, String root, ZipOutputStream zos) throws Exception{
FileInputStream fis = null;
try{
String zipName = file.getPath().replace(root+"\\", "");
// 파일을 읽어들임
fis = new FileInputStream(file);
// Zip엔트리 생성(한글 깨짐 버그)
ZipEntry zipentry = new ZipEntry(zipName);
// 스트림에 밀어넣기(자동 오픈)
zos.putNextEntry(zipentry);
int length = (int)file.length();
byte[] buffer = new byte[length];
//스트림 읽어들이기
fis.read(buffer, 0, length);
//스트림 작성
zos.write(buffer, 0, length);
//스트림 닫기
zos.closeEntry();
}catch(Throwable e){
throw e;
}finally{
if(fis != null) fis.close();
}
}
public static void main(String[] args){
try{
Zip.compress("d:\\test", "d:\\test.zip");
}catch(Throwable e){
e.printStackTrace();
}
}
}
| cs |