아직도 완벽히 이해하지 못한 리눅스 서버 메일전송 정리하기
1.java코드로 지정한 queue 폴더에 txt파일로 저장
- MailVO.java
package oz.mail.service;
import egovframework.com.cmm.ComDefaultVO;
@SuppressWarnings("serial")
public class MailVO extends ComDefaultVO {
private String sendername;
private String senderemail;
private String receivermail;
private String subject;
private String noList;
private String ucount;
private String noNm;
private String content;
private String atchFileId = "";
private String receivername;
private int mailIdx;
// 발송대상 선택 0 : 전체 , 1: 일반 , 2: 기업
private String receiver = "";
public int getMailIdx() {
return mailIdx;
}
public void setMailIdx(int mailIdx) {
this.mailIdx = mailIdx;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
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 getNoList() {
return noList;
}
public void setNoList(String noList) {
this.noList = noList;
}
public String getUcount() {
return ucount;
}
public void setUcount(String ucount) {
this.ucount = ucount;
}
public String getNoNm() {
return noNm;
}
public void setNoNm(String noNm) {
this.noNm = noNm;
}
public String getAtchFileId() {
return atchFileId;
}
public void setAtchFileId(String atchFileId) {
this.atchFileId = atchFileId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getReceivermail() {
return receivermail;
}
public void setReceivermail(String receivermail) {
this.receivermail = receivermail;
}
public String getReceivername() {
return receivername;
}
public void setReceivername(String receivername) {
this.receivername = receivername;
}
}
- MailsendService
package oz.mail.service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public interface MailSendService {
// 메일 종류 (회원가입, 신청현황, .....)
public enum MailType {
test1("test1메일 발송합니다."),
test2("test2메일 발송합니다."),
test3("test3메일 발송합니다.");
private String descript;
MailType(String descript) {
this.descript = descript;
}
public String getDescript() {
return descript;
}
}
//protected List<List<String>) fields = Arrays.asList( "idxId" );
//protected List<Map<MailType, Object>> fields = Arrays.asList("");
/**
* 메일수신자 형식에 맞춰서 수신자목록을 만든다
*
* return : 박찬호<test1@naver.com>;
*
*
*/
String getReceiverInfo(String userNm, String email) throws Exception;
/**
* 메일발송을 위한 파일 생성 UTF-8
*
* MailType tp : 발송하려는 메일이 어떤 종류의 메일인지 타입을 전달한다
* List<?> receiverList : 수신자목록 (name, email 항목)
*
* Map<String, Object> fileds : 메일에 담을 내용들
* 각 메일 타입별로 항목이 정해져 있다. --> MailSendServiceImpl 참조
*/
boolean sendMail(MailType tp, List<String> receiverList, Map<String, Object> fileds) throws Exception;
}
- MailsendServiceimpl.java
package oz.mail.service.impl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import egovframework.com.cmm.service.EgovProperties;
import egovframework.com.cop.ems.service.SndngMailVO;
import egovframework.com.cop.ems.service.impl.SndngMailRegistDAO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import oz.mail.service.MailSendService;
@Service("MailSendService")
public class MailSendServiceImpl extends EgovAbstractServiceImpl implements MailSendService {
/** Message ID Generation */
@Resource(name = "egovMailMsgIdGnrService")
private EgovIdGnrService egovMailMsgIdGnrService;
/** SndngMailRegistDAO */
@Resource(name = "sndngMailRegistDAO")
private SndngMailRegistDAO sndngMailRegistDAO;
protected Log log = LogFactory.getLog(this.getClass());
// 임시 비밀번호 발송
protected List<String> fields1 = Arrays.asList("이름", "임시비밀번호");
Map<MailType, Object> fieldsMap = new HashMap<MailType, Object>();
public MailSendServiceImpl() {
fieldsMap.put(MailType.test1, fields1);
}
public Map<String, Object> getMailTemplate(MailType mailType) {
Map<String, Object> templateMap = new HashMap<String, Object>();
templateMap.put("senderName", "보내는이름");
templateMap.put("senderEmail","보내는이메일");
templateMap.put("templateFn", mailType.name()+".html");
return templateMap;
}
/**
* 메일수신자 형식에 맞춰서 수신자목록을 만든다
*
* return : 박찬호<test1@naver.com>;
*
*
*/
@Override
public String getReceiverInfo(String userNm, String email) throws Exception
{
return userNm + "<" + email + ">;";
}
/**
* 메일발송을 위한 파일 생성
*
* MailType tp : 발송하려는 메일이 어떤 종류의 메일인지 타입을 전달한다
* List<?> receiverList : 수신자목록 (name, email 항목)
*
* Map<String, Object> fileds : 메일에 담을 내용들
* 각 메일 타입별로 항목이 정해져 있다. --> MailSendServiceImpl 참조
*
* eventSeCodeDc
*
*/
@Override
public boolean sendMail(MailType tp, List<String> receiverList, Map<String, Object> fileds) throws Exception
{
String mailContent = "";
Map<String, Object> templateMap = getMailTemplate(tp);
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/HH/mm");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));
String templateFn = EgovProperties.getProperty("Globals.mail.templatePath") + templateMap.get("templateFn").toString();
String strDate = sdf.format(d);
String strIdMail = "1";
String strSmtpServer = EgovProperties.getProperty("Globals.mail.smtpserver");
String strSender = templateMap.get("senderName").toString() + "<" + templateMap.get("senderEmail").toString() + ">";
String strReceiver = "";
String strSubject = tp.getDescript();
String strBody = "";
/* 수신자 목록을 만든다
* 홍길동<test1@naver.com>;홍길순<hong2@naver.com>;
* */
for ( int i=0; i<receiverList.size(); i++ ) {
strReceiver += receiverList.get(i);
}
//System.out.println("템플릿 경로 ? "+ templateFn);
/* 메일템플릿을 읽는다 */
try {
FileInputStream fis = new FileInputStream(new File(templateFn));
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
BufferedReader br = new BufferedReader(isr);
while(true){
String str = br.readLine();
if(str==null) break;
strBody += str;
}
} catch (FileNotFoundException ex) {
System.out.print("메일 템플릿 파일 Read Error --> " + ex);
} catch (IOException ex) {
System.out.print("메일 템플릿 파일 Read Error --> " + ex);
}
// fileds 에서 항목을 읽어온후, 메일 템플릿에서 구멍을 뚫어서 내용을 채운다
Iterator<String> keys = fileds.keySet().iterator();
while( keys.hasNext() ){
String key = keys.next();
String find = "\\{" + key.toLowerCase() + "\\}";
strBody = strBody.replaceAll("(?i)" + find, fileds.get(key).toString());
}
// images 경로 추가
strBody = strBody.replaceAll("(?i)\\{urldomain\\}", EgovProperties.getProperty("Gloabls.mail.urlDomain"));
mailContent = (strDate + "\r\n");
mailContent += (strIdMail + "\r\n");
mailContent += (strSmtpServer + "\r\n");
mailContent += (strSender + "\r\n");
mailContent += (strReceiver + "\r\n");
mailContent += (strSubject + "\r\n");
mailContent += ("" + "\r\n");
mailContent += (strBody + "\r\n");
// queue 에 파일을 생성한다
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss_SSS");
sdf2.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));
String queueFn = EgovProperties.getProperty("Globals.mail.queuePath") + sdf2.format(d) + ".txt";
Writer outFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(queueFn), "utf-8"));
outFile.write(mailContent);
outFile.close();
return true;
}
/**
* 메일을 전송 내역을 테이블에 등록
*
*/
public SndngMailVO insertSndngMail(SndngMailVO vo) throws Exception {
// 1-0.메세지ID를 생성한다.
String mssageId = egovMailMsgIdGnrService.getNextStringId();
vo.setMssageId(mssageId);
return sndngMailRegistDAO.insertSndngMail(vo);
}
}
위 3개파일 만들고 사용 할 컨트롤러쪽에 추가
@RequestMapping("mailsend.do")
public String setSave(Model model, VO vo)throws Exception{
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus txStatus = txManager.getTransaction(def);
String msg = null;
int result = 0;
try {
List<String> receiverList = new ArrayList<String>();
///추가
receiverList.add( mailSendService.getReceiverInfo("받는이름", "받는이메일"));
Map<String, Object> fileds = new HashMap<String, Object>();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String today = formatter.format(new java.util.Date());
fileds.put("userNm", vo.getUserName());
fileds.put("cont", "메일전송들어갈 내용");
fileds.put("dt", today);
mailSendService.sendMail(MailType.temp_tit, receiverList, fileds);
txManager.commit(txStatus);
}catch (Exception e) {
model.addAttribute("msg", "에러발생");
model.addAttribute("url", "/error");
txManager.rollback(txStatus);
}
return "alert";
}
위 작업을 통해 리눅스 서버 내 원하는 위치로 .txt파일을 생성한다.
2.queue 폴더에있는 txt파일을 일정 시간마다 smtp 메일서버로 전송한다.
- smtp 서버에 전송하기 위해 smtpHostServer에 전송해주는 SENDMAIL.jar 파일을 만들어준다.
만드는법 생략 ..
- 만든 후 SENDMAIL.jar 를 편한 위치(queue폴더 상위가 보기 편함)로 이동
- 이동 후 위 사진 처럼 권한을 변경해준다
chmod 777 SENDMAIL.jar
- 변경 후 jar파일 실행
nohup java -jar SENDMAIL.jar&
- 실행이 잘되는 지 확인
ps -ef | grep SENDMAIL
- 이제 java쪽에서 queue 폴더에 .txt파일을 만들면 .jar파일이 일정 초 마다 jar파일에 설정 해둔 smtpHostServer로 전송해준다. txt파일형식은 아래 이미지 처럼 생긴다.
- email/logs 에 로그를 확인해 보면 아래사진처럼 성공유무를 나타내 준다.
- 아래 사진은 전송 완료 후 queue 폴더에서 finished 폴더에 txt파일들 이다.
구현 하면서 삽질한것
1. smtp서버쪽 담당자한테 위에 리눅스 서버 ip delay허용 요청하였음.
2. 적용했다는 연락을 받고 smtp서버 ip로 .jar파일을 만들어서 진행
3. 계속해서 delay 거절 에러가 발생. (3일정도 여러가지 방법을 시도해보았음 )
4. 위 리눅스 서버가 로드밸런서가 걸려있어 다시한번더 공인ip가 아닌 로드밸런서 ip delay 허용 요청함.
5. 허용 되었다는 연락을 받았고 다시 시도 하였지만 delay 거절.
6. 업체와 전화통화하여 확인 결과 delay에 ip는 열어 두었지만 재기동 하지않아 위에 ip가 적용 되지 않았던 것이였음.
7. 총 5일 정도 고생했는데 업체쪽에서 허용을 제대로 하지 않아서 발생하였음. 재기동 후 정상 발송 확인
'개발노트' 카테고리의 다른 글
[Spring]CSRFTOKEN 란? (0) | 2022.12.09 |
---|---|
[jQuery] 유튜브 iframe 동적 생성 (0) | 2022.11.25 |
리눅스 CRONTAB 설정 (0) | 2022.10.18 |
Window Tomcat ssl 적용하기 (0) | 2022.10.17 |
로그인 후 이전페이지 이동 Referer (0) | 2022.09.29 |