자바/스프링

메일 API 이용하기

초보개발자뀨 2021. 7. 13. 13:36

면접을 준비하면서 최대한 국비 프로젝트를 하면서 못 해봤던 다양한걸 경험해보려구 하고있습니다.

그 첫 시작을 Java Mail Api를 이용해서  메일 전송을 구현해보도록하겠습니다!

 

우선 구현 해볼 동작 순서는 

 

메일 발송 버튼 -> 해당 Url Controller로 접근 -> Service로 접근  - > DB로 부터 정보 받는다 . ->  데이터 cvs파일화 -> cvs파일 컨트롤러로 넘겨주기 -> 메일로 전송 

로 진행해보도록 하겠습니다.

 

form.xml 수정 및 메일 정보 수정

우선 메일 전송을 구현하기 전에 라이브러리 추가 및 메일 서버의 정보부터 넣어야합니다.

form.xml에 다음 두가지의 라이브러리를 추가해줍니다. 

버전 같은 경우는 https://mvnrepository.com/artifact/javax.mail/mail

에 접속하셔서 최신버전을 사용하시거나 1.4.7 버전을 사용하셔두 무관합니다.

아래spring-context-support 는 메일 작업을 돕기위한 부가적인 기능들을 분리해놓은 라이브러리라고 보시면됩니다.

		<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
		<dependency>
		    <groupId>javax.mail</groupId>
		    <artifactId>mail</artifactId>
		    <version>1.4.7</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

 

두 라이브러리를 추가하셨다면 이제 메일서버에 대한 내용을 넣어야겠죠?

이번 예제에 네이버 메일을 사용할 예정이기에 네이버 메일로 들어가 하단 환경설정에 들어가셔서

해당 설정에서 사용함으로 바꿔줍니다.

 

그후 Bean설정을 해줍니다.

저는 root-context.xml에 추가해줬습니다.

mailSender이라는 이름의 빈을 설정해주었구요

host와 port같은 경우는

네이버 pop설정 밑에 보시면 이런식으로 나와있습니다.

 

 

	<!--  메일 전송을 위한 빈 설정 -->
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="smtp.naver.com" />
		<property name="port" value="465" />
		<property name="username" value="네이버 아이디" />
		<property name="password" value="네이버 비밀번호" />
		<property name="defaultEncoding" value="utf-8" />
		<property name="javaMailProperties">
			<props>
				<prop key="mail.debug">true</prop>
				<prop key="mail.smtp.starttls.enable">true</prop>
				<prop key="mail.smtps.ssl.checkserveridentity">true</prop>
				<prop key="mail.smtp.auth">true</prop>
				<prop key="mail.smtps.ssl.trust">*</prop>
				<prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
			</props>
		</property>
	</bean>

 

 

 

메일 발송 버튼

우선 메일 발송 버튼은 간단히 버튼으로 만들었구요!

버튼 클릭 이벤트로 /sendMail Url 로 접근하게 만들었습니다.

<button onclick="location.href='/sendMail'">메일 발송하기</button>

Controller 작성

위에 작성한 mailSender bean 정보를 이용할 수 있도록 Autowired로 의존성 주입을 해줍니다.

	@Autowired
	private JavaMailSenderImpl mailSender;

 

	@GetMapping("/sendMail")
	public String sendMail() {

		final MimeMessagePreparator preparator = new MimeMessagePreparator() { 
			@Override public void prepare(MimeMessage mimeMessage) throws Exception { 
					// true -> 멀티파트 메시지를 사용 하겠다는 의미 , 인코딩
					final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); 
					helper.setFrom("park517777@naver.com");
					helper.setTo("park51777@naver.com");
					helper.setSubject("테스트 메일 전송"); 
					// setText true는 html를 사용하겠다는 뜻
					helper.setText("직원목록 보내드립니다.", true); 
					String path="c:\\csv\\";
					String createfile="c:\\csv\\empList.csv";
					empService.makeCvs(path,createfile);	
					FileSystemResource file = new FileSystemResource(new File(createfile));
					helper.addAttachment("empList.csv", file);
					
				}
			};
				
				mailSender.send(preparator);


		return "home";
	}

위 코드부터 천천히 보겠습니다. 

버튼을 눌러 해당 URL로 접근하게되면

MimeMessagePreparator 객체를 생성하게됩니다.

스프링을 이용해서 메일 전송하는 클래스는 MimeMessage와 simpleMailMessage가 있습니다.

두 차이점은 Mime는 멀티파트 데이터 즉 파일도 전송할 수 있고 simpleMailMessage는 텍스트 데이터만 전송이 가능합니다. 저희는 cvs 파일을 넘길 예정이므로 Mime를 사용하겠습니다.

 

다음은 MimeMessage를 생성하는 방법입니다. MimeMessagePreparator와 Helper를 안쓰고 직접 생성하여 메일 전송도 가능하지만 보다 간단한 방법을 위해서 MimeMessagePreparator과 Helper를 사용하겠습니다.

 

final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

 첫 번째 인자는 mimeMessage 객체를 넣고 , 두번 째 인자는 멀티파트를 이용할지에 대한 여부 이며 세번째는 인코딩 방식에 대한 인자입니다.

 

setFrom은 전송 이메일이구요 To는 수신이메일 , Subject는 제목,

setText는 보낼 내용입니다. 두번 째 인자는 해당 내용을 보낼 때 html로 인식를 하게 하냐 안하냐의 여부입니다.

그 뒤에는 이제 cvs파일을 만들기 위해 파일 저장 위치와 파일 이름을 지정해주었구요

Service의 makeCvs로 통하여 파일을 받도록 했습니다. 

FileSystemResoruce는 메일을 통해 보낼 파일 정보를 저장하는 부분입니다.

마지막으로 .addAttachment는 첨부파일의 이름과 해당 file를 인자로 주면 됩니다.

그 후 mailSender를 통해서 해당 내용들을 전송하고

home.jsp 로 이동합니다.

					helper.setFrom("park517777@naver.com");
					helper.setTo("park51777@naver.com");
					helper.setSubject("테스트 메일 전송"); 
					// setText true는 html를 사용하겠다는 뜻
					helper.setText("직원목록 보내드립니다.", true); 
					String path="c:\\csv\\";
					String createfile="c:\\csv\\empList.csv";
					empService.makeCvs(path,createfile);	
					FileSystemResource file = new FileSystemResource(new File(createfile));
					helper.addAttachment("empList.csv", file);
                    				}
			};
				
				mailSender.send(preparator);


		return "home";
	}

 

Cvs 생성 Service
	@Override
	public BufferedWriter makeCvs(String path, String fileName) throws IOException {
		
		File f=new File(path);
		File f1= new File(fileName);
		if(!f.exists()) f.mkdirs();  
		if(f1.exists()) {
			f1.delete();
		}
		List<EmpVO> emp_list = getList();
		BufferedWriter fw;
		try {
			fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName,true), "MS949"));
			fw.append("직원번호");
			fw.append(",");
			fw.append("직급");
			fw.append(",");
			fw.append("이름");
			fw.append(",");
			fw.append("전화번호");
			fw.append(",");
			fw.append("이메일");
			fw.append("\n");
			
			for(EmpVO emp : emp_list) {
				fw.append(emp.getEmp_no());
				fw.append(",");
				fw.append(emp.getEmp_level());
				fw.append(",");
				fw.append(emp.getEmp_name());
				fw.append(",");
				fw.append(emp.getEmp_tel());
				fw.append(",");
				fw.append(emp.getEmp_email());
				fw.append("\n");
			}
			
			fw.flush();
			fw.close();
			return fw;
		} catch (UnsupportedEncodingException | FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

해당 서비스는 파일 저장 위치와 파일의 이름을 인자로 받습니다.

그 후 파일와 폴더가 이미 존재하는지 확인하고 폴더가 없다면 재생성하고 파일이 이미 있다면 삭제 후 재성생 하게 로직을 짯습니다.

 

그 후 Mapper를 통해 정보를 받아옵니다. 저 같은 경우는 회원 리스트의 정보를 받아왔습니다.

 

fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName,true), "MS949"));

이부분은  Cvs 파일은 utf-8 로 하면 깨지기 때문에 MS949 형식으로 지정해주었습니다.

 

그 후 append를 사용해서

~,~,~,~ \n

~,~,~,~ \n

식으로 데이터를 넣으면서 cvs형식을 맞추어주었습니다.

데이터를 다 넣어 준 후 fw.flush() , fw.close()를 이용하여 파일 작업을 마무리 해준 후 

해당 파일을 컨트롤러로 반환해줍니다.

 

버튼 눌러보기

자 이제 코드는 다 짯구 어떻게 동작하는지 확인해보겠습니다.

 

메일 전송 버튼을 누르면!

첨부파일과 함께 메일이 오는걸 확인할 수 있습니다.

 

cvs 파일도 잘 열리구요!

 

 

자 이렇게 메일 전송 구현이 끝났구요!

만약에 받는 사람과 제목, 내용들을 동적으로 받고싶다 하시면

MailVO 를 만드셔서 input을 통해 제목, 받는 사람, 내용들을 작성하여 

해당 Controller에 Post 방식으로 넘겨서 하시면 됩니다!