매일 조금씩

12/14 - Java로 메일 발송 (텍스트, html, 이미지, 첨부파일) 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

12/14 - Java로 메일 발송 (텍스트, html, 이미지, 첨부파일)

mezo 2020. 12. 15. 02:28
728x90
반응형

1. Dialog - JFrame 자식창(종속창)

             * Modal(제어권)   

               JColorChooser

               JFileChooser

2. MenuBar

               Menu / MenuItem

3. LayoutManager

               컨테이너별 기본 LayoutManager

                JFrame, JDialog            - BorderLayout

                JPanel                        - FlowLayout

                * setLayout 

                * AbsoluteLayout

                GridLayout

                CardLayout

4. Event

          1) 각자 (Widget 별로) - 좀더 window builder 친화적

                     XXXListener -> XXXEvent

                     XXXAdapter -> XXXEvent

          2) 통합 (Widget 통합)

                     구현 통해서 

                

 

※ 응용문제 풀이

내가 어제 푼 방법과는 차이가 있다.

내가 한 방법은 JFrame 클래스에서 콤보박스와 리스트의 값을 세팅할 때 JDialog의 값을 가져왔다.

그래서 Dialog에서 가져온 값을 사용하는 것들은 전부 static 처리를 해줘야했다. (main메서드 내부가 아니기 때문)

강사님은 JFrame클래스의 main메서드 내에서 JDialog 값을 가져왔다. 그래서 나처럼 static처리가 필요없었다.

강사님 방법이 훨씬 간단했다ㅎ 오류에 시달려 막 풀다보니 main메서드가 뒷전이였다..

 

강사님의 풀이는 아래와 같다.

 

SearchZipcodeEx05

 

1) UI 

JFrame과 JDialog 각각을 위해 두개의 UI가 필요하다.

 

(1) JFrame UI

ZipcodeSearchUIEx01.java

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import model1.AddressListModel;
import model1.DongComboBoxModel;
import model1.GugunComboBoxModel;
import model1.SidoComboBoxModel;

import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JScrollPane;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SearchDialogUI extends JDialog {

	private final JPanel contentPanel = new JPanel();
	private JComboBox comboBox1;
	private JComboBox comboBox2;
	private JComboBox comboBox3;
	private JList list;

	
	/**
	 * Launch the application.
	 */
//	public static void main(String[] args) {
//		try {
//			SearchDialogUI dialog = new SearchDialogUI();
//			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//			dialog.setVisible(true);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	/**
	 * Create the dialog.
	 */
	public SearchDialogUI() {
		setBounds(100, 100, 450, 600);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);
		
		comboBox1 = new JComboBox();
		comboBox1.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				if(arg0.getStateChange() == ItemEvent.SELECTED) {
					System.out.println((String)comboBox1.getSelectedItem());
					comboBox2.setModel(new GugunComboBoxModel((String)comboBox1.getSelectedItem()));
				}
			}
		});
		comboBox1.setBounds(14, 12, 124, 24);
		contentPanel.add(comboBox1);
		
		comboBox2 = new JComboBox();
		comboBox2.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					
					comboBox3.setModel(new DongComboBoxModel((String)comboBox1.getSelectedItem(),(String)comboBox2.getSelectedItem()));
				}
			}
		});
		comboBox2.setBounds(152, 12, 125, 24);
		contentPanel.add(comboBox2);
		
		comboBox3 = new JComboBox();
		comboBox3.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					list.setModel(new AddressListModel((String)comboBox1.getSelectedItem(),(String)comboBox2.getSelectedItem(),
							(String)comboBox3.getSelectedItem()));
				}
			}
		});
		comboBox3.setBounds(291, 12, 127, 24);
		contentPanel.add(comboBox3);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(14, 48, 404, 456);
		contentPanel.add(scrollPane);
		
		list = new JList();
		scrollPane.setViewportView(list);
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton okButton = new JButton("확인");
				okButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent arg0) {
						
						SearchDialogUI.this.dispose();
					}
				});
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
			{
				JButton cancelButton = new JButton("취소");
				cancelButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent e) {
						SearchDialogUI.this.dispose();
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
		
		// 초기 시.도 데이터 입력
		comboBox1.setModel(new SidoComboBoxModel());
	}
	
	public String getAddress() {
		return (String)list.getSelectedValue();
	}
}

 

(2) JDialog UI

SearchDialogUI.java

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import model1.AddressListModel;
import model1.DongComboBoxModel;
import model1.GugunComboBoxModel;
import model1.SidoComboBoxModel;

import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JScrollPane;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SearchDialogUI extends JDialog {

	private final JPanel contentPanel = new JPanel();
	private JComboBox comboBox1;
	private JComboBox comboBox2;
	private JComboBox comboBox3;
	private JList list;

	
	/**
	 * Launch the application.
	 */
//	public static void main(String[] args) {
//		try {
//			SearchDialogUI dialog = new SearchDialogUI();
//			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//			dialog.setVisible(true);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	/**
	 * Create the dialog.
	 */
	public SearchDialogUI() {
		setBounds(100, 100, 450, 600);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);
		
		comboBox1 = new JComboBox();
		comboBox1.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				if(arg0.getStateChange() == ItemEvent.SELECTED) {
					System.out.println((String)comboBox1.getSelectedItem());
					comboBox2.setModel(new GugunComboBoxModel((String)comboBox1.getSelectedItem()));
				}
			}
		});
		comboBox1.setBounds(14, 12, 124, 24);
		contentPanel.add(comboBox1);
		
		comboBox2 = new JComboBox();
		comboBox2.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					
					comboBox3.setModel(new DongComboBoxModel((String)comboBox1.getSelectedItem(),(String)comboBox2.getSelectedItem()));
				}
			}
		});
		comboBox2.setBounds(152, 12, 125, 24);
		contentPanel.add(comboBox2);
		
		comboBox3 = new JComboBox();
		comboBox3.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED) {
					list.setModel(new AddressListModel((String)comboBox1.getSelectedItem(),(String)comboBox2.getSelectedItem(),
							(String)comboBox3.getSelectedItem()));
				}
			}
		});
		comboBox3.setBounds(291, 12, 127, 24);
		contentPanel.add(comboBox3);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(14, 48, 404, 456);
		contentPanel.add(scrollPane);
		
		list = new JList();
		scrollPane.setViewportView(list);
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton okButton = new JButton("확인");
				okButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent arg0) {
						
						SearchDialogUI.this.dispose();
					}
				});
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
			{
				JButton cancelButton = new JButton("취소");
				cancelButton.addMouseListener(new MouseAdapter() {
					@Override
					public void mouseClicked(MouseEvent e) {
						SearchDialogUI.this.dispose();
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
		
		// 초기 시.도 데이터 입력
		comboBox1.setModel(new SidoComboBoxModel());
	}
	
	public String getAddress() {
		return (String)list.getSelectedValue();
	}
}

 

 

 

2) model

시도, 구군, 동 콤보박스와  주소 리스트출력을 위해 총 4개의 모델이 필요하다.

 

(1) sido comboBox model

SidoComboBoxModel.java

package model1;

import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;

public class SidoComboBoxModel extends DefaultComboBoxModel<String> {
	
	private ArrayList<ZipcodeTO> sidos;
	
	public SidoComboBoxModel() {
		try {
			ZipcodeDAO dao = new ZipcodeDAO();
			sidos = dao.listSido();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public int getSize() {
		return sidos.size();
	}
	
	@Override
	public String getElementAt(int index) {
		ZipcodeTO to = sidos.get(index);
		return to.getSido();
	}

}

(2) gugun  comboBox model

GugunComboBoxModel.java

package model1;

import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;

public class GugunComboBoxModel extends DefaultComboBoxModel<String> {
	private ArrayList<ZipcodeTO> guguns;
	
	public GugunComboBoxModel(String strSido) {
		try {
			ZipcodeDAO dao = new ZipcodeDAO();
			guguns = dao.listGugun(strSido);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public int getSize() {
		return guguns.size();
	}
	
	@Override
	public String getElementAt(int index) {
		ZipcodeTO to = guguns.get(index);
		return to.getGugun();
	}
}

(3) dong  comboBox model

DongComboBoxModel.java

package model1;

import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;

public class DongComboBoxModel extends DefaultComboBoxModel<String> {
private ArrayList<ZipcodeTO> dongs;
	
	public DongComboBoxModel(String strSido, String strGugun) {
		try {
			ZipcodeDAO dao = new ZipcodeDAO();
			dongs = dao.listDong(strSido, strGugun);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public int getSize() {
		return dongs.size();
	}
	
	@Override
	public String getElementAt(int index) {
		ZipcodeTO to = dongs.get(index);
		return to.getDong();
	}
}

(4) address list  model

AddressListModel.java

package model1;

import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.AbstractListModel;

public class AddressListModel extends AbstractListModel<String> {
	private ArrayList<ZipcodeTO> addresses;
	
	private String strSido;
	private String strGugun;
	private String strDong;
	
	
	public AddressListModel(String strSido, String strGugun, String strDong) {
		try {
			ZipcodeDAO dao = new ZipcodeDAO();
			addresses = dao.listAddress(strSido, strGugun, strDong);
			
			this.strSido = strSido;
			this.strGugun = strGugun;
			this.strDong = strDong;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public int getSize() {
		return addresses.size();
	}
	
	@Override
	public String getElementAt(int index) {
		ZipcodeTO to = addresses.get(index);
		String address = String.format("[%s] %s %s %s %s %s", 
				to.getZipcode(), strSido, strGugun, strDong, 
				to.getRi(), to.getBunji());
		return address;
	}
}

 

 

 

 

 

 

메일 보내기(스팸)


  • 메일 쓰기 → 메일서버(내거) 메일서버(상대방) 메일읽기
  • 메일서버 프로토콜 : smtp(Simple Mail Tranfer Protocol)

 

인증 도메인이 있어야서버를 구축할 수 있다.

자바를 통해서 메일을 보내려면 다음과 같은 과정이 필요하다.

 

  • 자바 구글(공개 smtp 제공) 메일

 

oracle에서 아래 두개의 jar 파일을 다운받아서 자바 프로젝트에 라이브러리로 추가 해야한다.

  • activation.jar
  • mail.jar

우린 그냥 ftp로 강사님이 다운 받아놓으신걸 가져왔다.

filzilla에서 Java > Java > APIs

 

 

 

 

 

 

Java로 구글 smtp사용하여 메일 보내기

가장먼저

아래 주소로 접속해서 보안성이 낮은 앱의 접근을 허용해야한다.

www.google.com/settings/security/lesssecureapps

 

로그인 - Google 계정

하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인

accounts.google.com

그 다음 인증 서버를 다음과 같이 만들어야 한다.

import javax.mail.PasswordAuthentication;

import javax.mail.Authenticator;

public class MyAuthenticator extends Authenticator {
	// 인증 서버 만들기
	
	private String fromMail;
	private String fromPassword;
	
	public MyAuthenticator(String fromMail, String fromPassword) {
		this.fromMail = fromMail;
		this.fromPassword = fromPassword;
	}
	
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(fromMail, fromPassword);
	}
}

 위 인증서버를 가지고 보내는 메일 서버를 만들면 된다. 

 

1. 텍스트로 보내기

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailSender {
	private String fromMail;
	private String fromPassword;
	
	public MailSender() {
		this.fromMail = "kimhaeseon1@gmail.com";
		this.fromPassword = "ribecudmzjmlodcd";
	}
	
	public static void main(String[] args) {
		String toMail = "khs51777@naver.com";
		String toName = "테스터";
		String subject = "테스트 제목";
		String content = "테스트 내용";
		
		MailSender mailSender = new MailSender();
		mailSender.sendMail(toMail, toName, subject, content);
	}
	
	public void sendMail(String toMail, String toName, String subject, String content) {
		// ** 중요 **
		
		try {
			// 메일을 보내려면 smtp서버가 있어야하고 그걸 내가 만들수도 있고 남이 만든걸 쓸수도 있다.
			// google smtp 서버 설정 (구글이 주는 거라서 거기서 하라는 대로 스는거임)
			Properties props = new Properties();
			props.put("mail.smtp.starttls.enable", "true");
			props.put("mail.transport.protocol", "smtp");
			props.put("mail.smtp.host", "smtp.gmail.com");
			props.put("mail.smtp.port", "465");
			props.put("mail.smtp.auth", "true");
			props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			
			// 인증 환경 설정
			MyAuthenticator authenticator = new MyAuthenticator(fromMail, fromPassword);
			
			// 접속 후 연결 환경
			Session session = Session.getDefaultInstance(props, authenticator);
			
			// 메세지 내용
			MimeMessage msg = new MimeMessage(session);
			
			// 전체적인 설정
			msg.setHeader("Content-Type", "text/plain; charset=utf-8");
			
			// 받는 사람 설정
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail, toName, "utf-8"));
			
			// 제목
			msg.setSubject(subject);
			
			// 내용
			msg.setContent(content, "text/plain; charset=utf-8");
			msg.setSentDate(new java.util.Date());
			
			Transport.send(msg);
			
			System.out.println("메일 전송 완료");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

단,  내 구글 계정은 2단계 보안 인증이 되어있어서 보안성이 낮은 앱의 접속을 허용하려면앱 비밀번호를 따로 받아야 했다...

따라서 구글에서 만들라고 하는 앱 비밀번호 만들고...

아래처럼 메일 서버 코드 내에 구글 계정 비번을 넣는 자리에 만든 앱 비밀번호를 넣으면 인증이 되고 메일 전송이 된다..

 

받는 메일에 접속하면 메일이 와있는 걸 확인 가능하다.

메일을 보내려면 smtp서버가 있어야하고 그걸 내가 만들수도 있고 남이 만든걸 쓸수도 있다.

여기선 구글이 제공하는 걸 쓰는 거다.

 

 

2. html 데이터 보내기 + 이미지 보내기

html을 텍스트 보내듯이 그냥 넣어 보내면 태그 그대로 나온다. text/plain으로 되어있으면 그렇다 

전체설정이랑 내용을 text/plain에서 text/html로 바꿔야한다.

이미지는 반드시 url을 표시한 절대경로로 보내야한다.

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailSender2 {
	private String fromMail;
	private String fromPassword;
	
	public MailSender2() {
		this.fromMail = "kimhaeseon1@gmail.com";
		this.fromPassword = "ribecudmzjmlodcd";
	}
	
	public static void main(String[] args) {
		String toMail = "khs51777@naver.com";
		String toName = "테스터";
		String subject = "테스트 제목";
		//html로 보내기 / 밑에서 text/html 설정 필수
		//String content = "<html><head><meta charset='utf-8'/></head><body><font color = 'blue'>html 내용</font></body></html>";
		//이미지 보내기 / 반드시 url을 표시한 절대경로로 보내야함
		String content = "<html><head><meta charset='utf-8'/></head><body><font color = 'blue'>html 내용</font><br /><img src='https://ssl.pstatic.net/tveta/libs/1313/1313466/5f5d81fa7f2d6adb4704_20201211101154645.jpg'></body></html>";
		
		MailSender2 mailSender = new MailSender2();
		mailSender.sendMail(toMail, toName, subject, content);
	}
	
	public void sendMail(String toMail, String toName, String subject, String content) {
		// ** 중요 **
		
		try {
			// 메일을 보내려면 smtp서버가 있어야하고 그걸 내가 만들수도 있고 남이 만든걸 쓸수도 있다.
			// google smtp 서버 설정 (구글이 주는 거라서 거기서 하라는 대로 스는거임)
			Properties props = new Properties();
			props.put("mail.smtp.starttls.enable", "true");
			props.put("mail.transport.protocol", "smtp");
			props.put("mail.smtp.host", "smtp.gmail.com");
			props.put("mail.smtp.port", "465");
			props.put("mail.smtp.auth", "true");
			props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			
			// 인증 환경 설정
			MyAuthenticator authenticator = new MyAuthenticator(fromMail, fromPassword);
			
			// 접속 후 연결 환경
			Session session = Session.getDefaultInstance(props, authenticator);
			
			// 메세지 내용
			MimeMessage msg = new MimeMessage(session);
			
			// 전체적인 설정
			msg.setHeader("Content-Type", "text/html; charset=utf-8");
			
			// 받는 사람 설정
			// CC / BCC - 여러사람한테 보내기
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail, toName, "utf-8"));
			
			// 제목
			msg.setSubject(subject);
			
			// 내용
			msg.setContent(content, "text/html; charset=utf-8");
			msg.setSentDate(new java.util.Date());
			
			Transport.send(msg);
			
			System.out.println("메일 전송 완료");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

html로 출력하고자 햇던 'html 내용' 과 이미지가 잘 보내진 것을 확인 가능하다.

 

 

 

 

 

 

 

 

 

Java로 메일 보내기 (텍스트, html, 이미지, 첨부파일)


 

메일 보낼수 있는 창 만들어보기

여러명한테 보내려면 sendMail을 여러번 돌려도되고,  받는 사람 설정 코드에서  CC / BCC 를 사용해도된다.

SMS는 무료가 없어서 안된다. 반드시 유료로 사야 이렇게 보내는게 가능하다.

위 사진에서 보내기 버튼을 누르면

아래와 같이 html로 작성된 텍스트, 이미지와 첨부된 파일이 함께 전송된다.

 

 

 

 

 

-- 코드 작성법 --

1) 가장 먼저 JFrame 창에서 입력받은 값을 메일 서버에 보내는 코드를 작성한다.

'보내기' 버튼을 눌렀을 때 메일 서버를 생성하고, 값을 메일 서버로 보내야한다.

따라서 아래의 코드는 모두 '보내기' 버튼의 mouse click 이벤트 메서드 안에 작성한다.

String toMail;
String toName;
String subject;
String isText = "";
String content;
String file;

MailSenderUI mailSender = new MailSenderUI();

SendMailUIEx01 frame = new SendMailUIEx01();
frame.setVisible(true);

toMail = textField1.getText();
toName = textField2.getText();
subject = textField3.getText();
if(rdbtn1.isSelected()) {
    isText = "plain";
}else if(rdbtn2.isSelected()) {
    isText = "html";
}
content = textArea.getText();
// textField4에 입력된 String타입의 파일의 주소를 file에 넣음
file = textField4.getText();

// 첨부해야 할 파일 주소를 인자로 같이 전달
mailSender.sendMail(toMail, toName,subject, isText, content, file);

 

 

전체 코드는 다음과 같다.

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JFileChooser;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

import javax.activation.DataHandler;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.swing.ButtonGroup;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class SendMailUIEx01 extends JFrame {

	private JPanel contentPane;
	private JTextField textField1;
	private JTextField textField3;
	private JRadioButton rdbtn1;
	private JRadioButton rdbtn2;
	private JTextArea textArea;
	private JButton btn2;
	private final ButtonGroup buttonGroup = new ButtonGroup();
	private JButton btn1;
	private JTextField textField4;
	private JLabel lblNewLabel_2;
	private JLabel lblNewLabel_3;
	private JTextField textField2;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SendMailUIEx01 frame = new SendMailUIEx01();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public SendMailUIEx01() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 538, 528);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		textField1 = new JTextField();
		textField1.setBounds(119, 12, 363, 24);
		contentPane.add(textField1);
		textField1.setColumns(10);
		
		textField3 = new JTextField();
		textField3.setBounds(119, 75, 363, 24);
		contentPane.add(textField3);
		textField3.setColumns(10);
		
		JLabel lblNewLabel = new JLabel("받는 사람 : ");
		lblNewLabel.setBounds(39, 12, 97, 18);
		contentPane.add(lblNewLabel);
		
		JLabel lblNewLabel_1 = new JLabel("제목 : ");
		lblNewLabel_1.setBounds(74, 75, 62, 18);
		contentPane.add(lblNewLabel_1);
		
		rdbtn1 = new JRadioButton("text");
		buttonGroup.add(rdbtn1);
		rdbtn1.setBounds(140, 107, 139, 27);
		contentPane.add(rdbtn1);
		
		rdbtn2 = new JRadioButton("html");
		buttonGroup.add(rdbtn2);
		rdbtn2.setBounds(328, 107, 139, 27);
		contentPane.add(rdbtn2);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(29, 150, 458, 237);
		contentPane.add(scrollPane);
		
		textArea = new JTextArea();
		scrollPane.setViewportView(textArea);
		
		btn2 = new JButton("보내기");
		btn2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});
		btn2.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						try {
							String toMail;
							String toName;
							String subject;
							String isText = "";
							String content;
							String file;
							
							MailSenderUI mailSender = new MailSenderUI();
							
							SendMailUIEx01 frame = new SendMailUIEx01();
							frame.setVisible(true);
							
							toMail = textField1.getText();
							toName = textField2.getText();
							subject = textField3.getText();
							if(rdbtn1.isSelected()) {
								isText = "plain";
							}else if(rdbtn2.isSelected()) {
								isText = "html";
							}
							content = textArea.getText();
							// textField4에 입력된 String타입의 파일의 주소를 file에 넣음
							file = textField4.getText();
							
							// 첨부해야 할 파일 주소를 인자로 같이 전달
							mailSender.sendMail(toMail, toName,subject, isText, content, file);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
			}
		});
		btn2.setBounds(381, 438, 105, 27);
		contentPane.add(btn2);
		
		btn1 = new JButton("찾기");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				JFileChooser fileChooser = new JFileChooser("c:\\");
				
				// 디렉토리 선택기 
				//fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				// 파일 선택기를 가려줌
				//fileChooser.setAcceptAllFileFilterUsed(false);
				
				// return 값이 int 임.
				int result = fileChooser.showOpenDialog(SendMailUIEx01.this);
				
				// save일 때랑 같은 if문
				if(result == JFileChooser.APPROVE_OPTION) {
					System.out.println("확인");
					File selectedFile = fileChooser.getSelectedFile();
					textField4.setText(selectedFile.getAbsolutePath());
					//System.out.println(selectedFile.getName());
					//System.out.println(selectedFile.getAbsolutePath());
							
				}else if(result == JFileChooser.CANCEL_OPTION) {
					System.out.println("취소");
				}
			}
		});
		btn1.setBounds(380, 399, 105, 27);
		contentPane.add(btn1);
		
		textField4 = new JTextField();
		textField4.setEnabled(false);
		textField4.setEditable(false);
		textField4.setBounds(123, 400, 243, 24);
		contentPane.add(textField4);
		textField4.setColumns(10);
		
		lblNewLabel_2 = new JLabel("첨부");
		lblNewLabel_2.setBounds(39, 403, 62, 18);
		contentPane.add(lblNewLabel_2);
		
		lblNewLabel_3 = new JLabel("이름 :");
		lblNewLabel_3.setBounds(74, 42, 62, 18);
		contentPane.add(lblNewLabel_3);
		
		textField2 = new JTextField();
		textField2.setBounds(119, 42, 363, 24);
		contentPane.add(textField2);
		textField2.setColumns(10);
	}
	
}

 

2) 이제 JFrame으로부터 인자로 받아온 값을 메일 서버에서 처리해야한다.

중요한건 텍스트와 첨부파일 이렇게 2개 타입이라는 것이다. 

하나만 있다면 아래와 같이 처리하면 되었다.

// 보내는 메일 객체
MimeMessage msg = new MimeMessage(session);

// 메일 객체에 html 세팅
msg.setContent(content, "text/html; charset=utf-8");

그러나 두가지 일땐 다르다. 바로 메일 객체에 넣는 것이 아니라.

두가지 객체를 따로 생성하고 합친 후,  그걸 메일 객체에 넣어야한다.

 

두가지 타입을 따로 생성하기 위해 사용해야하는 클래스는 MimeBodyPart 클래스이다.

// 텍스트 
MimeBodyPart mbp1 = new MimeBodyPart();
// 첨부 파일 
MimeBodyPart mbp2 = new MimeBodyPart();

위처럼 두개의 MimeBodyPart 객체를 생성하고 

// 텍스트 담기
mbp1.setContent(content, "text/" + isText + "; charset=utf-8");

// 첨부파일 담기
FileDataSource fds = new FileDataSource(file);
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(fds.getName());

각자 넣고자하는 콘텐츠(텍스트, 파일)를 넣은 후,

 

Multipart 클래스를 사용하여 두개를 합친다.

Multipart mp = new MimeMultipart();
// mp에 파일 담기
mp.addBodyPart(mbp1);
// mp에 첨부파일 담기
mp.addBodyPart(mbp2);

// 보낼 메일에 mp 담기
msg.setContent(mp);

 

 

전체 코드는 다음과 같다.

import java.awt.EventQueue;
import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
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 MailSenderUI {
	private String fromMail;
	private String fromPassword;
	
	public MailSenderUI() {
		this.fromMail = "kimhaeseon1@gmail.com";
		this.fromPassword = "ribecudmzjmlodcd";
	}
	
	// main은 지워버림
	
	public void sendMail(String toMail, String toName, String subject, String isText, String content, String file) {
		// ** 중요 **
		
		try {
			// 메일을 보내려면 smtp서버가 있어야하고 그걸 내가 만들수도 있고 남이 만든걸 쓸수도 있다.
			// google smtp 서버 설정 (구글이 주는 거라서 거기서 하라는 대로 스는거임)
			Properties props = new Properties();
			props.put("mail.smtp.starttls.enable", "true");
			props.put("mail.transport.protocol", "smtp");
			props.put("mail.smtp.host", "smtp.gmail.com");
			props.put("mail.smtp.port", "465");
			props.put("mail.smtp.auth", "true");
			props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			
			// 인증 환경 설정
			MyAuthenticator authenticator = new MyAuthenticator(fromMail, fromPassword);
			
			// 접속 후 연결 환경
			Session session = Session.getDefaultInstance(props, authenticator);
			
			// 메세지 내용
			MimeMessage msg = new MimeMessage(session);
			
			// 전체적인 설정
			msg.setHeader("Content-Type", "text/" + isText + "; charset=utf-8");
			
			// 받는 사람 설정
			// CC / BCC - 여러사람한테 보내기
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail, toName, "utf-8"));
			
			// 제목
			msg.setSubject(subject);
			
			// 보내는 날짜
			msg.setSentDate(new java.util.Date());
			
			
			
			
			// ===================  내용 (텍스트 , 첨부파일)
			
			// ------------------ 텍스트
			MimeBodyPart mbp1 = new MimeBodyPart();
			mbp1.setContent(content, "text/" + isText + "; charset=utf-8");
			
			
			// ------------------ 파일 첨부 / MimeBodyPart , Multipart
			MimeBodyPart mbp2 = new MimeBodyPart();
			// 인자 file은 첨부해야할 파일 주소.
			// 파일 이름과 파일 내용등을 가져옴
			FileDataSource fds = new FileDataSource(file);
			mbp2.setDataHandler(new DataHandler(fds));
			mbp2.setFileName(fds.getName());
			
			
			// 텍스트 + 첨부파일
			Multipart mp = new MimeMultipart();
			mp.addBodyPart(mbp1);
			mp.addBodyPart(mbp2);
			msg.setContent(mp);
			
			// msg를 보냄
			Transport.send(msg);
			
			System.out.println("메일 전송 완료");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 

완성! 

 

클래스만 알아내면 아주 쉬운 문제였다.

728x90
반응형