본문 바로가기
Framework/Spring

[Spring] velocity와 spring으로 템플릿 email 보내기

by 나비와꽃기린 2016. 11. 16.

<<최종 파일구조>>

노란색 표시된 파일들이 필요합니다.






1. 메이븐 디펜던시 추가


(1)javax.mail

<dependency>
	<groupId>javax.mail</groupId>
	<artifactId>mail</artifactId>
	<version>1.4.7</version>
</dependency>

(2) velocity

<dependency>
	<groupId>org.apache.velocity</groupId>
	<artifactId>velocity</artifactId>
	<version>1.7</version>
</dependency>


2. SimpleEmailTemplateExample.java 작성 (main함수를 가진 test 클래스)


사실 여기서 엄청 삽질했네요.........

사실 설정파일을 읽어드리는 소스를 다음과 같이 작성했었는데


ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/spring-beans.xml");

path가 잘못된건지 기본 설정이 잘못된건지 계속 java.io.FileNotFoundException 뜨더군요….


결국 설정파일 위치를 바꾸고 소스를 다음과 같이 FileSystemXmlApplicationContext로 변경하여 성공하였습니다. 예제 만들면서 또 하나 배워가네요.


public static void main(String[] args) {
  Mail mail = new Mail();
  mail.setMailFrom("발신자메일아이디@gmail.com");
  mail.setMailTo("수신자메일입력");
  mail.setMailSubject("Subject - Send Email using Spring Velocity Template");
  mail.setTemplateName("emailtemplate.vm");
  
  
  ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/webapp/WEB-INF/spring/spring-beans.xml");
  
  Mailer mailer = (Mailer) context.getBean("mailer");
  mailer.sendMail(mail);
}

Mail 클래스를 사용하여 발신이메일, 발신이메일, 메일제목, 사용할 template 파일명을 셋팅하고

bean이 정의 되어있는 환경설정파일을 읽어, mailer라는 이름의 bean 객체를 통해 mail을 보내게 되는 예제입니다.

 

FileSystemXmlApplicationContext()는 따로 공부한 후, 포스팅 해봐야겠어요.

(파일위치는 상단의 프로젝트 구조 사진 참고해주세요.)



3. Mail.java 작성

public class Mail {
	private String mailFrom;

	 private String mailTo;

	 private String mailCc;

	 private String mailBcc;

	 private String mailSubject;

	 private String mailContent;

	 private String templateName;

	 private String contentType;

	 public Mail() {
	  contentType = "text/html";
	 }

	 public String getContentType() {
	  return contentType;
	 }

	 public void setContentType(String contentType) {
	  this.contentType = contentType;
	 }

	 public String getMailBcc() {
	  return mailBcc;
	 }

	 public String getTemplateName() {
	  return templateName;
	 }

	 public void setTemplateName(String templateName) {
	  this.templateName = templateName;
	 }

	 public void setMailBcc(String mailBcc) {
	  this.mailBcc = mailBcc;
	 }

	 public String getMailCc() {
	  return mailCc;
	 }

	 public void setMailCc(String mailCc) {
	  this.mailCc = mailCc;
	 }

	 public String getMailFrom() {
	  return mailFrom;
	 }

	 public void setMailFrom(String mailFrom) {
	  this.mailFrom = mailFrom;
	 }

	 public String getMailSubject() {
	  return mailSubject;
	 }

	 public void setMailSubject(String mailSubject) {
	  this.mailSubject = mailSubject;
	 }

	 public String getMailTo() {
	  return mailTo;
	 }

	 public void setMailTo(String mailTo) {
	  this.mailTo = mailTo;
	 }

	 public Date getMailSendDate() {
	  return new Date();
	 }

	 public String getMailContent() {
	  return mailContent;
	 }

	 public void setMailContent(String mailContent) {
	  this.mailContent = mailContent;
	 }

	 @Override
	 public String toString() {
	  StringBuilder lBuilder = new StringBuilder();
	  lBuilder.append("Mail From:- ").append(getMailFrom());
	  lBuilder.append("Mail To:- ").append(getMailTo());
	  lBuilder.append("Mail Cc:- ").append(getMailCc());
	  lBuilder.append("Mail Bcc:- ").append(getMailBcc());
	  lBuilder.append("Mail Subject:- ").append(getMailSubject());
	  lBuilder.append("Mail Send Date:- ").append(getMailSendDate());
	  lBuilder.append("Mail Content:- ").append(getMailContent());
	  return lBuilder.toString();
	 }
}


4. Mailer.java 작성

Velocity 라이브러리를 사용하여 템플릿에 사용할 template파일 경로를 읽어 지정해주고 velocityContext를 통해 템플릿으로 보낼 변수들의 값을 지정해줄 수도 있습니다.

다음 에제는 템플릿으로 firstNamelastName location key값에 string 값을 보내보았습니다.

 

velocity에 관련된 설정을 마친후 springframework.mail.SimpleMailMessage로 셋팅해주고 springframework.mail.MailSender로 메일을 보내게 됩니다.


public class Mailer {
	
	@Autowired
	private MailSender mailSender;
	
	@Autowired
	 private VelocityEngine velocityEngine;

	 public void setMailSender(MailSender mailSender) {
	  this.mailSender = mailSender;
	 }

	 public void setVelocityEngine(VelocityEngine velocityEngine) {
	  this.velocityEngine = velocityEngine;
	 }

	 public void sendMail(Mail mail) {
	  SimpleMailMessage message = new SimpleMailMessage();
	  
	  message.setFrom(mail.getMailFrom());
	  message.setTo(mail.getMailTo());
	  message.setSubject(mail.getMailSubject());

	  Template template = velocityEngine.getTemplate("./src/main/webapp/resources/templates/" + mail.getTemplateName());

	  VelocityContext velocityContext = new VelocityContext();
	  velocityContext.put("firstName", "Yashwant");
	  velocityContext.put("lastName", "Chavan");
	  velocityContext.put("location", "Pune");
	  
	  StringWriter stringWriter = new StringWriter();
	  template.merge(velocityContext, stringWriter);
	  
	  message.setText(stringWriter.toString());
	  
	  mailSender.send(message);
	 }
}


5. emailtemplate.vm 작성

해당 템플릿은 Mailer.java에서 셋팅해준 velocityContext의 파라미터 값들을 받아

출력됩니다

Dear ${firstName} ${lastName}
 
Sending Email Using Spring Smtp Email + Velocity Template from ${location} location.

Thanks


6. spring-beans.xml 작성

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="smtp.gmail.com" />
		<property name="port" value="587" />
		<property name="username" value="이메일입력" />
		<property name="password" value="패스워드입력" />
		<property name="javaMailProperties">
			<props>
				<prop key="mail.debug">true</prop>
				<prop key="mail.smtp.auth">true</prop>
				<prop key="mail.smtp.starttls.enable">true</prop>
				<prop key="mail.mime.charset">UTF-8</prop>
				<prop key="mail.transport.protocol">smtp</prop>
			</props>
		</property>
	</bean>

	<bean id="mailer" class="com.common.Mail.Mailer">
		<property name="mailSender" ref="mailSender" /><!--mailSender bean참조-->
		<property name="velocityEngine" ref="velocityEngine" /><!--velocityEngine bean참조-->
	</bean>

	<bean id="velocityEngine"
		class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
		<property name="velocityProperties">
			<props>
				<prop key="resource.loader">file</prop>
				<prop key="class.resource.loader.class">
					org.apache.velocity.runtime.resource.loader.FileResourceLoader
				</prop>
				
			</props>
		</property>
	</bean>
	
</beans>



6. 결과 TEST


위와 같이 테스트코드를 작성하고 예제를 돌려보았더니 다음과 같은 에러가 나더군요.

org.springframework.mail.MailAuthenticationException : Authenticationfailed;


권한이 없다는 에러겠죠?ㅎㅎ 왠지 발신자 셋팅해 놓은 gmail 아이디에서 권한설정을 해줘야 하는 것 같은 느낌이 들어 가보았더니

아니나 다를까 다음과 같은 메일이 와있더군요.

 

 

보안수준이 낮은 앱에서 로그인 접근이 시도됬다는 구글의 경고 메일이 날라옵니다.

똑똑한 구글 같으니라고.............



따라서 보안 수준이 낮은 앱에 엑세스하도록 허용링크를 따라가

아래와 같이 보안수준이 낮은 앱의 엑세스를 허용으로 바꿔주셔야 합니다.




저 같은 경우는 gmail을 통한 예제 테스트라서

테스트 할 때만 엑세스허용으로 바꾸고 다시 사용안함으로 돌려놨답니다

(왠지 해킹의 피해를 볼것 같은 예감에……….;;;;;;;;;;;)

 

어쨌든, 해당 설정을 하고 다시 예제를 돌려보면 다음과 같이 메일본문과 함께

메일이 성공적으로 보내졌음을 확인할 수 있습니다.





메일이 수신메일로 도착했습니다~

변수들도 정상적으로 들어갔죠 :D





뻘짓을 살짝 겪은..... 예제라 아마 나중~~~~~ 나중에~~~~는 보고

여기 틀렸네 하며 고칠수도 있겠다라는 예감이 드네요ㅎㅎㅎㅎ


어쨌든 Velocity와 spring을 통한 메일 보내기 예제였습니다.

그럼 20000.




댓글2

  • 초보자.. 2019.03.19 19:35

    포스팅 된대로 시도해 보았지만..
    Unable to find resource './src/main/webapp/resources/templates/emailtemplates.vm' 이라고 나오면서
    메일러 부분의 vm 파일의 리소스를 찾을수 없다고 합니다..이건 어떻게 해야하나요 ㅠㅠ?
    답글

    • 글작성자입니다.
      보내고자 하는 메일의 템플릿 형식을 작성해두면... 그 파일의 리소스경로를 찾아 메일을 보내는 예제입니다.
      해당 경로에 파일을 생성하고 템플릿을 작성은 하셨었는지부터 확인하시면 될 것 같습니다 ^^!