• 廖雪峰Java13网络编程-2Email编程-2接收Email


    ## 1接收Email协议类型 接收Email:收件人通过MUA软件把邮件从MDA抓取到本地计算机的过程。

    1.1 POP3

    从MUA到MDA使用最广泛的是协议是POP3 * Post Office Protocol version 3,建立在tcp之上的协议 * 标准端口110 * 整个会话加密,加密端口995

    1.2 IMAP

    与POP3的区别:IMAP在本地的所有操作都会自动同步到服务器上,允许用户自己创建文件夹 * Internet Mail Access Protocol * 标准端口143 * 加密端口993

    2如何接收Email

    • 使用Java Mail API,实现邮件的接收
    • 无需关心POP3协议原理
        //创建session
        Session session = Session.getInstance(props, null);
        //创建Store对象,代表用户在邮件服务器上的整个存储
        Store store = new POP3SSLStore(session, url);
        //获取Folder对象,最常用的是收件箱INBOX
        Folder folder = store.getFolder("INBOX");
        //获取Message:返回收件箱所有的邮件,并循环处理message对象
        Message[] messages = folder.getMessages();
        for(Message message:messages){
            ...
        }
    
    package com.feiyangedu.sample.pop3;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Properties;
    
    import javax.mail.Address;
    import javax.mail.Authenticator;
    import javax.mail.BodyPart;
    import javax.mail.Flags;
    import javax.mail.Folder;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.Multipart;
    import javax.mail.Part;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Store;
    import javax.mail.URLName;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMessage.RecipientType;
    import javax.mail.internet.MimeUtility;
    
    import com.sun.mail.pop3.POP3SSLStore;
    
    public class Pop3 {
    
    	final String popHost;
    	final String username;
    	final String password;
    	final boolean debug;
    
    	public Pop3(String popHost, String username, String password) {
    		this.popHost = popHost;
    		this.username = username;
    		this.password = password;
    		this.debug = true;
    	}
    
    	public static void main(String[] args) throws Exception {
    		Pop3 pop = new Pop3("pop.qq.com","123456789@qq.com","pop3授权码");//注意,不能用手机号,要用qq号
    		Folder folder = null;
    		Store store = null;
    		try {
    			store = pop.createSSLStore(); //获取到Store对象后,就可以获取Folder对象
    			folder = store.getFolder("INBOX"); 
    			folder.open(Folder.READ_WRITE);
    			System.out.println("Total messages: " + folder.getMessageCount()); //邮件数量
    			System.out.println("New messages: " + folder.getNewMessageCount()); //新邮件数量
    			System.out.println("Unread messages: " + folder.getUnreadMessageCount()); //未读邮件数量
    			System.out.println("Deleted messages: " + folder.getDeletedMessageCount()); //已删除的邮件数量
    			Message[] messages = folder.getMessages();
    			for (Message message : messages) {
    				printMessage((MimeMessage) message);
    			}
    		} finally {
    			if (folder != null) {
    				try {
    					folder.close(true);
    				} catch (MessagingException e) {
    					e.printStackTrace();
    				}
    			}
    			if (store != null) {
    				try {
    					store.close();
    				} catch (MessagingException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
            //创建Store对象
    	public Store createSSLStore() throws MessagingException {
    		Properties props = new Properties();
    		props.setProperty("mail.store.protocol", "pop3");
    		props.setProperty("mail.pop3.port", "995"); // 主机端口号
    		props.setProperty("mail.pop3.host", this.popHost);// POP3主机名
    		// 启动SSL:
    		props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    		props.put("mail.smtp.socketFactory.port", "995");
    		URLName url = new URLName("pop3", this.popHost, 995, "", this.username, this.password);
    		Session session = Session.getInstance(props, null);
    		session.setDebug(this.debug); // 显示调试信息
    		Store store = new POP3SSLStore(session, url);
    		store.connect(); //连接到服务器
    		return store;
    	}
    
    	Session createTLSStore() {
    		Properties props = new Properties();
    		props.put("mail.smtp.host", this.popHost); // POP3主机名
    		props.put("mail.smtp.port", "587"); // 主机端口号
    		props.put("mail.smtp.auth", "true"); // 是否需要用户认证
    		props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
    		Session session = Session.getInstance(props, new Authenticator() {
    			protected PasswordAuthentication getPasswordAuthentication() {
    				return new PasswordAuthentication(Pop3.this.username, Pop3.this.password);
    			}
    		});
    		session.setDebug(this.debug); // 显示调试信息
    		return session;
    	}
    
    	Session createInsecureStore() {
    		Properties props = new Properties();
    		props.put("mail.smtp.host", this.popHost); // POP3主机名
    		props.put("mail.smtp.port", "25"); // 主机端口号
    		props.put("mail.smtp.auth", "true"); // 是否需要用户认证
    		Session session = Session.getInstance(props, new Authenticator() {
    			protected PasswordAuthentication getPasswordAuthentication() {
    				return new PasswordAuthentication(Pop3.this.username, Pop3.this.password);
    			}
    		});
    		session.setDebug(this.debug); // 显示调试信息
    		return session;
    	}
    
    	static void printMessage(MimeMessage msg) throws IOException, MessagingException {
    		System.out.println("--------------------");
    		System.out.println("Subject: " + MimeUtility.decodeText(msg.getSubject())); //邮件的主题
    		System.out.println("From: " + getFrom(msg)); //发件人
    		System.out.println("To: " + getTo(msg)); //收件人
    		System.out.println("Sent: " + msg.getSentDate().toString()); //发送时间
    		System.out.println("Seen: " + msg.getFlags().contains(Flags.Flag.SEEN)); //是否已读
    		System.out.println("Priority: " + getPriority(msg)); //优先级
    		System.out.println("Size: " + msg.getSize() / 1024 + "kb"); //邮件大小
    		System.out.println("Body: " + getBody(msg)); //邮件正文
    		System.out.println("--------------------");
    		System.out.println();
    	}
    
    	static String getFrom(MimeMessage msg) throws IOException, MessagingException {
    		Address[] froms = msg.getFrom();
    		return addressToString(froms[0]);
    	}
    
    	static String getTo(MimeMessage msg) throws MessagingException, IOException {
    		// 使用 msg.getAllRecipients() 获取所有收件人
    		Address[] tos = msg.getRecipients(RecipientType.TO);
    		List<String> list = new ArrayList<>();
    		for (Address to : tos) {
    			list.add(addressToString(to));
    		}
    		return String.join(", ", list);
    	}
    
    	static String addressToString(Address addr) throws IOException {
    		InternetAddress address = (InternetAddress) addr;
    		String personal = address.getPersonal();
    		return personal == null ? address.getAddress()
    				: (MimeUtility.decodeText(personal) + " <" + address.getAddress() + ">");
    	}
    
    	static String getPriority(MimeMessage msg) throws MessagingException {
    		String priority = "Normal";
    		String[] headers = msg.getHeader("X-Priority");
    		if (headers != null) {
    			String header = headers[0];
    			if ("1".equals(header) || "high".equalsIgnoreCase(header)) {
    				priority = "High";
    			} else if ("5".equals(header) || "low".equalsIgnoreCase(header)) {
    				priority = "Low";
    			}
    		}
    		return priority;
    	}
    
    	static String getBody(Part part) throws MessagingException, IOException {
    		if (part.isMimeType("text/*")) {//如果邮件的正文是text开头,是一个文本邮件或html邮件
    			return part.getContent().toString();
    		}
    		if (part.isMimeType("multipart/*")) { //如果是以multipart开头,那么他是一个带附件的邮件,还需要递归的把附件的内容读出来
    			Multipart multipart = (Multipart) part.getContent();
    			for (int i = 0; i < multipart.getCount(); i++) {
    				BodyPart bodyPart = multipart.getBodyPart(i);
    				String body = getBody(bodyPart);
    				if (!body.isEmpty()) {
    					return body;
    				}
    			}
    		}
    		return "";
    	}
    }
    

    3总结

    Java接收Email:

    • 用maven引入javamail依赖
    • 确定POP3服务器信息:域名/端口/使用明文/SSL
    • 调用相关API接收Email(无需关心底层TCP Socket连接)
    • 设置debug模式可以查看通信详细内容(便于排查错误)
  • 相关阅读:
    IEnumerable<T>转DataTable的几种方法
    关于IAsyncResult接口的CompletedSynchronously属性
    为WCF增加UDP绑定(储备篇)
    WPF自定义集合控件概述与遇到的问题
    WPF嵌套模板引发的血案
    为WCF增加UDP绑定(实践篇)
    Uva 10557 XYZZY(DFS+BFS)
    Uva 572 Oil Deposits(DFS)
    Uva 532 Dungeon Master(三维迷宫)
    Uva 10004 Bicoloring
  • 原文地址:https://www.cnblogs.com/csj2018/p/11257193.html
Copyright © 2020-2023  润新知