`
liangcmwn
  • 浏览: 16318 次
  • 性别: Icon_minigender_1
  • 来自: 南京
最近访客 更多访客>>
社区版块
存档分类
最新评论

[转] JavaMail API 详解

阅读更多

JavaMail API简介

JavaMail API是一种可选的、能用于读取、编写和发送电子消息的包(标准扩展)。您可使用这种包创建邮件用户代理(Mail User Agent ,MUA) 类型的程序,它类似于Eudora、Pine及Microsoft Outlook这些邮件程序。其主要目的不是像发送邮件或其他邮件传输代理(Mail Transfer Agent,MTA)类型的程序那样用于传输、发送和转发消息。换句话说,用户可以与MUA类型的程序交互,以阅读和撰写电子邮件。MUA依靠MTA处理实际的发送任务。

 

JavaMail API简介

JavaMail API是一种可选的、能用于读取、编写和发送电子消息的包(标准扩展)。您可使用这种包创建邮件用户代理(Mail User Agent ,MUA) 类型的程序,它类似于Eudora、Pine及Microsoft Outlook这些邮件程序。其主要目的不是像发送邮件或其他邮件传输代理(Mail Transfer Agent,MTA)类型的程序那样用于传输、发送和转发消息。换句话说,用户可以与MUA类型的程序交互,以阅读和撰写电子邮件。MUA依靠MTA处理实际的发送任务。

JavaMail API的设计是,为收发信息提供与协议无关的访问。方式是把该API划分成两个部分:

· 该API的第一个部分是本课程的重点。基本上是如何发送和接收独立于提供程序/协议的消息。

· 第二个部分则使用特定的协议语言,如:SMTP、POP、IMAP和NNTP。如果要让JavaMail API与服务器通信,就需要为之提供协议。由于Sun公司对特定协议提供程序有充分的介绍,用户可以免费获取,所以本课程没有介绍创建特定协议提供程序的内容。

复习相关协议

在学习JavaMail API的深层知识之前,让我们回过头来看一看在该API中使用的协议,本质上有4种人们常用的协议:

· SMTP

· POP

· IMAP

· MIME

您还需要了解NNTP及其他一些协议。理解这些协议的基本原理有助于您理解如何使用JavaMail API。而该API的设计要与协议无关,所以不能克服这些基础协议的限制。如果选用的协议不支持某种功能,那么JavaMail API也无法在其上添加这种功能。(正如您一会儿就会看到的,在操作POP协议时,常常会碰到这种问题)。

SMTP

简单邮件传输协议(SMTP)是用于传送电子邮件的机制。在JavaMail API环境中,您的基于JavaMail的程序将与您公司或Internet服务提供商(ISP)的SMTP服务器通信。该SMTP服务器将会把消息转发给用作接收消息的SMTP服务器,最后用户可通过POP或IMAP协议获取该消息。由于支持身份验证,所以不需要SMTP服务器是一种开放的转发器,但需要确保SMTP服务器配置正确。JavaMail API中没有集成用于处理诸如配置服务器以转发消息或添加/删除电子邮件帐户这一类任务的功能。

POP

POP的含义是邮局协议,当前的版本为3,也称作POP3,该协议是在RFC 1939中定义的。POP是Internet上的大多数人用来接收邮件的机制。它为每个用户的每个邮箱定义支持,这是它所做的全部工作,也是大多数问题的根源。在使用POP协议时,人们熟悉的很多功能,如查看收到了多少新邮件消息的功能,POP根本不支持。这些功能都内置到诸如Eudora或Microsoft Outlook之类的邮件程序中,能为您记住接收的上一封邮件,以及计算有多少新邮件这类信息。因此,使用JavaMail API时,如果想获取这类信息,将需要由自己进行计算。

IMAP

IMAP是用于接收消息的更加高级的协议,它是在RFC 2060中定义的。IMAP的含义是"Internet消息访问协议",当前版本是第4版,也称作IMAP4。使用IMAP时,您的邮件服务器必须支持该协议。您不能只是简单地把程序转变为支持IMAP,而不是支持POP,就指望能支持IMAP中的一切。假定您的邮件服务器支持IMAP,那么基于JavaMail的程序就可利用在服务器上拥有多个文件夹的用户,并且这些文件夹可以被多个用户共享的功能。

由于IMAP协议具有更高级的功能,您也许会想IMAP应该被每一个人使用,但事实不是这样。因为IMAP会加重邮件服务器的负荷,它需要服务器接收新消息,发送消息给请求的用户,并在多个文件夹中为每个用户维护这些消息。而这要集中备份,因而长期下去用户的文件夹会变得越来越大,当磁盘空间用光了时,每个人都会遭受损失。而使用POP协议时,已保存消息可以解除服务器的重负。

MIME

MIME的含义是"多用途的网际邮件扩充协议"。它不是一种邮件传输协议,相反,它定义传输的内容:消息的格式、附件等。许多文档都定义了MIME协议,包含:RFC 822、RFC 2045、RFC 2046和RFC 2047。作为JavaMail API的用户,一般不需要担心这些格式。但是,这些格式确实存在,并为您的程序所用。

NNP和其他协议

由于JavaMail API分开了提供程序和其他部分,所以您可以轻松地为附加协议添加支持。Sun公司提供第3方提供程序清单,这些提供程序要利用 Sun公司不支持的少见的协议。在这份清单中,您将会看到对NNTP(网络新闻传输协议)[新闻组]、S/MIME(安全多用途的网际邮件扩充协议)及其他协议的提供支持的第3方提供程序。

安装

目前有两种版本的JavaMail API最常用:1.2和1.1.3。本课程中的所有例子都适用于这两种版本。其中JavaMail API 1.2是最新的,而JavaMail API 1.1.3中包含了Java 2企业版(J2EE)平台1.2.1版,所以它仍然很常用。使用JavaMail API的版本会对您的下载和安装产生一些影响。这两种版本的JavaMail API都能与JDK 1.1.6、Java 2标准版(J2SE)平台1.2.x和1.3.x协同工作。

注意:在安装了Sun公司的JavaMail工具后,会在演示目录下看到许多示例程序。

安装JavaMail 1.2

要使用JavaMail 1.2 API,可以下载JavaMail 1.2工具,然后解压缩javamail-1_2.zip文件,并把mail.jar文件添加到典型安装路径下。JavaMail 1.2工具带有SMTP、IMAP4和POP3提供程序以及核心类。

安装完JavaMail 1.2后,再安装JavaBeans Activation Framework。

安装JavaMail 1.1.3

要使用JavaMail 1.1.3 API,可以下载JavaMail 1.1.3工具,然后解压缩javamail1_1_3.zip文件,并把mail.jar文件添加到典型安装路径下。JavaMail 1.1.3工具带有SMTP和IMAP4提供程序以及核心类。

如果您想用JavaMail 1.1.3访问POP服务器,需要下载并安装POP3提供程序。Sun公司拥有一个独立于 JavaMail 工具的提供程序。在下载并解压缩pop31_1_1.zip文件后,也还需要把pop3.jar添加到典型安装路径下。

安装完JavaMail 1.1.3后,再安装JavaBeans Activation Framework。

安装JavaBeans Activation Framework

JavaMail API的所有版本都需要JavaBeans Activation Framework(JavaBeans激活框架),这种框架提供了对输入任意数据块的支持,并能相应地对其进行处理。看上去效果好像不太好,但该框架是在当今的许多浏览器和邮件工具中可以找到的基本MIME类型支持。下载该框架后,解压缩jaf1_0_1.zip文件,并将activation.jar文件添加到典型安装路径下。

对于JavaMail 1.2用户,现在应该把mail.jar和activation.jar文件添加到典型安装路径下。

对于JavaMail 1.1.3用户,现在应该把mail.jar、pop3.jar和activation.jar添加到典型安装路径下。如果您不打算使用POP3,就不需要把pop3.jar文件添加到典型安装路径下。

如果您不想更改安装路径环境变量,可以把JAR文件复制到Java运行时环境(JRE)目录下的lib/ext目录下。例如,对于J2SE 1.3版本,Windows平台上的默认目录应该是C:\jdk1.3\jre\lib\ext。

使用Java 2企业版

如果您使用的是J2EE,则在使用基本JavaMail API时,不需要做什么特殊的工作;JavaMail API带有J2EE类。只要确保j2ee.jar文件位于典型安装路径下,并完成了所有的设置工作。

对于J2EE 1.2.1,POP3提供程序是单独提供的,因此需要下载该提供程序,并按安装JavaMail 1.1.3的步骤,在J2EE 1.2.1中包含POP3提供程序。J2EE 1.3的用户会获得J2EE和POP3提供程序,因而不需要对POP3提供程序执行独立安装。使用这两种版本的J2EE用户,都不需要安装JavaBeans Activation Framework。

练习

设置您的 JavaMail 环境。

复习核心类

在开始深入研究JavaMail类之前,首先让用户浏览一下构成API的核心类:会话、消息、地址、验证程序、传输,存储和文件夹。所有这些类都可以在JavaMail API即javax.mail的顶层包中找到,尽管您将频繁地发现您自己使用的子类是在javax.mail.internet包中找到的。

Session类

Session类定义了一个基本的邮件会话。通过该会话可让别的工作顺利执行。Session对象利用java.util.Properties对象获取诸如邮件服务器、用户名、密码等信息,以及其他可在整个应用程序中共享的信息。

Session类的构造器是私有的。您可以获得一个可被getDefaultInstance()方法共享的单一的默认会话:

Properties props = new Properties();

// fill props with any information

Session session = Session.getDefaultInstance(props, null);

或者,您可以用getInstance()方法创建一个独特的会话:

Properties props = new Properties();

// fill props with any information

Session session = Session.getInstance(props, null);

这两种情形下的null参数都是一种Authenticator对象,它不是在此时使用的。详细信息请参阅其后的"Autherticator"一节。

在大多数情况下,使用共享会话就足够了,即使为多个用户邮箱处理邮件会话也是如此。您可以在通信过程的后面一步添加上用户名和密码的组合,并保持所有的一切是独立的。

Message类

一旦创建了自己的Session对象,就是该去创建要发送的消息的时候了。这时就要用到消息类型。作为一个抽象类,您必须操作一个子类,在大多数情况下,该子类是javax.mail.internet.MimeMessage。一个MimeMessage是一种理解MIME类型和报头(在不同的RFC文档中均有定义)的消息。消息的报头被严格限制成只能使用US-ASCII字符,尽管非ASCII字符可以被编码到某些报头字段中。

可以通过将Session对象传递给MimeMessage构造器的方法来创建消息:

MimeMessage message = new MimeMessage(session);

注意:还有其他的构造器,像用于创建消息的源于RFC822格式化的输入流的构造器。

一旦创建了消息,就可以设置其各个部分,如Message(消息)实现Part(部分)接口(以MimeMessage实现MimePart)。设置内容的基本机制是setContent()方法,它带有表示内容和MIME类型的参数:

message.setContent("Hello", "text/plain");

但是,如果正在使用 MimeMessage,并且您的消息是纯文本,那么您就可以使用setText()方法。该方法只需要一个表示实际内容的参数,默认的MIME类型为纯文本:

message.setText("Hello");

对于纯文本消息,setText()方法更常常被用来设置内容。要发送其他类型的消息,如HTML消息,就要使用setContent方法()。现在用的更多的是HTML消息。

要设置主题,可以使用setSubject()方法:

message.setSubject("First");

Address类

一旦创建了会话和消息,并为消息填充了内容,就需要用Address类为您的信件标上地址了。同Message类一样,Address类也是一种抽象类。您可以使用javax.mail.internet.InternetAddress类。

要创建只带有电子邮件地址的地址,可以把电子邮件地址传递给Address类的构造器:

Address address = new InternetAddress("president@whitehouse.gov");

如果想让一个名字出现在电子邮件地址后,也可以将其传递给构造器:

Address address = new InternetAddress("president@whitehouse.gov", "George Bush");

您要为消息的from(发送者)字段和to(接收者)字段创建地址对象。除非您的邮件服务器阻止这样做,否则要在发送的消息中注明该消息的发送者。

一旦创建好了地址,有两种方法可让您将地址与消息连接起来。为了鉴别发送者,您可以使用setFrom()和setReplyTo()方法。

message.setFrom(address)

如果您的消息需要显示多个地址来源,则可以使用addFrom()方法:

Address address[] = ...;

message.addFrom(address);

为了鉴别消息接收者,您可以使用addRecipient()方法。该方法除了需要一个地址参数外,还需要一个Message.RecipientType属性(消息的接收类型)。

message.addRecipient(type, address)

地址的3种预定义类型如下:

· Message.RecipientType.TO

· Message.RecipientType.CC

· Message.RecipientType.BCC

因此,如果一条消息将发送给副总统,同时还将发送该消息的副本给第一夫人,则采用下面的代码:

Address toAddress = new InternetAddress("vice.president@whitehouse.gov");

Address ccAddress = new InternetAddress("first.lady@whitehouse.gov");

message.addRecipient(Message.RecipientType.TO, toAddress);

message.addRecipient(Message.RecipientType.CC, ccAddress);

JavaMail API没有提供检查电子邮件地址有效性的机制。您可以自己编写支持扫描有效字符(在RFC 822文档中所定义的)的程序或检验MX(邮件交换)记录,这些都超越了JavaMail API的范围。

Authenticator类

与java.net类一样,JavaMail API可以利用Authenticator(验证程序)类通过用户名和密码来访问受保护的资源。对于JavaMail API来说,这种受保护的资源是指邮件服务器。JavaMail的Authenticator类可以在javax.mail包中找到,并有别于同名的java.net类。当JavaMail API在Java 1.1下工作时,JavaMail和java.net不会共享同一个Authenticator类名称,这是因为Java 1.1中不含有java.net。

要使用Authenticator类,您可以使用该抽象类的子类,并通过getPasswordAuthentication()方法返回一个PasswordAuthentication实例。在创建时,您必须用会话记录Authentication类。其后,当需要进行身份验证时,会通知您的Authenticator。会弹出一个窗口,或从一个配置文件(尽管不加密就不安全)中读取用户名和密码,并把它们作为一个PasswordAuthentication对象返回给调用程序。

Properties props = new Properties();

// fill props with any information

Authenticator auth = new MyAuthenticator();

Session session = Session.getDefaultInstance(props, auth);

Transport类

发送消息的最后一步操作是使用Transport类。该类使用特定于协议(通常是SMTP)的语言来发送消息。它是一个抽象类,其操作与Session类有些相似。您可以通过只调用静态的send()方法来使用该类的默认版本:

Transport.send(message);

或者,您可以从用于您的协议的会话中获取一个特定的实例,然后传递用户名和密码(不必要时可以为空)并发送消息,最后关闭连接:

message.saveChanges(); // implicit with send()

Transport transport = session.getTransport("smtp");

transport.connect(host, username, password);

transport.sendMessage(message, message.getAllRecipients());

transport.close();

当您需要发送多个消息时,建议采用后一种方法,因为它将保持消息间活动服务器的连接。而基本的send()机制会为每一个方法调用都建立一条独立的连接。

注意:要查看经过邮件服务器邮件命令,可以用session.setDebug(true)方法设置调试标志。

Store和Folder类

使用Session类来获取消息,开始时与发送消息很相似。但是,在获取会话后,很有可能使用用户名和密码或Authenticator类来连接Store类。与Transport类一样,您要告诉Store类将使用什么协议:

// Store store = session.getStore("imap");

Store store = session.getStore("pop3");

store.connect(host, username, password);

在连接Store类后,就可以获取一个Folder类,在读取其中的消息前必须先打开该类。

Folder folder = store.getFolder("INBOX");

folder.open(Folder.READ_ONLY);

Message message[] = folder.getMessages();

对于POP3协议,惟一可用的文件夹是INBOX。如果使用的是IMAP协议,则可以使用其他的文件夹。

注意:Sun公司的提供程序本来想提供方便。而Message message[]=folder.getMessages();这条语句却是一种从服务器逐条读取消息的缓慢操作,所以仅当您确实需要获取消息部分(该内容是所检索消息的内容)时可以使用这条语句。

一旦读取消息,就可以使用getContent()方法获取其内容,或使用writeTo()方法将其内容写到一个流中。getContent()方法只获取消息内容,而writeTo()方法则还会输出报头。

System.out.println(((MimeMessage)message).getContent());

一旦您阅读完邮件,就可以关闭对文件夹和存储的连接。

folder.close(aBoolean);

store.close();

传递给文件夹的close()方法的布尔变量指定了是否通过清除已删除的消息来更新文件夹。

继续前进

实际上,理解使用这7个类的方式,是使用JavaMail API处理几乎所有事情所需要的全部内容。用这7个类以外的方式构建的JavaMail API,其大多数功能都是以几乎完全相同或特定的方式来执行任务的,就好像内容是附件。特定的任务,如:搜索、隔离等将在后面进行介绍。

使用JavaMail API

您已经看到了如何操作JavaMail API的核心部分。在下面几节中,您将学习如何连接几个部分以执行特定的任务。

发送消息

发送电子邮件消息涉及到获取会话、创建和填充消息并发送消息这些操作。您可以在获取Session时,通过为要传递的Properties对象设置mail.smtp.host属性来指定您的SMTP服务器。

String host = ...;

String from = ...;

String to = ...;

// Get system properties

Properties props = System.getProperties();

// Setup mail server

props.put("mail.smtp.host", host);

// Get session

Session session = Session.getDefaultInstance(props, null);

// Define message

MimeMessage message = new MimeMessage(session);

message.setFrom(new InternetAddress(from));

message.addRecipient(Message.RecipientType.TO,

new InternetAddress(to));

message.setSubject("Hello JavaMail");

message.setText("Welcome to JavaMail");

// Send message

Transport.send(message);

您应该在try-catch块中编写代码,以在创建消息并发送它时可以抛出一个异常。

练习

发送您的第一个消息

获取消息

对于阅读邮件来说,首先您要获取一个会话,然后获取并连接到一个相应的用于您的收件箱的存储上,接着打开相应的文件夹,再获取消息。同时,不要忘记了操作完成后关闭连接。

String host = ...;

String username = ...;

String password = ...;

// Create empty properties

Properties props = new Properties();

// Get session

Session session = Session.getDefaultInstance(props, null);

// Get the store

Store store = session.getStore("pop3");

store.connect(host, username, password);

// Get folder

Folder folder = store.getFolder("INBOX");

folder.open(Folder.READ_ONLY);

// Get directory

Message message[] = folder.getMessages();

for (int i=0, n=message.length; i<n; i++) {

System.out.println(i + ": " + message.getFrom()[0]

+ "\t" + message.getSubject());

}

// Close connection

folder.close(false);

store.close();

每一条消息执行何种操作取决于自己决定。上面的代码块只是显示了消息的发送者和主题。从技术上讲,发送者地址列表可以为空,此时getFrom()[0]调用会抛出一个异常。

为了显示整条消息,您可以提示用户在看完消息的发送者和主题字段后,如果想看到消息的内容,可以再调用消息的writeTo()方法。

BufferedReader reader = new BufferedReader (

new InputStreamReader(System.in));

// Get directory

Message message[] = folder.getMessages();

for (int i=0, n=message.length; i<n; i++) {

System.out.println(i + ": " + message.getFrom()[0]

+ "\t" + message.getSubject());

System.out.println("Do you want to read message? " +

"[YES to read/QUIT to end]");

String line = reader.readLine();

if ("YES".equals(line)) {

message.writeTo(System.out);

} else if ("QUIT".equals(line)) {

break;

}

}

练习

检查邮件

删除消息和标志

删除消息涉及到操作与消息关联的标志。对不同的状态有不同的标志,有些标志是系统定义的,有些则是由用户定义的。预定义的标志都是在内部类Flags.Flag中定义的,如下所示:

· Flags.Flag.ANSWERED

· Flags.Flag.DELETED

· Flags.Flag.DRAFT

· Flags.Flag.FLAGGED

· Flags.Flag.RECENT

· Flags.Flag.SEEN

· Flags.Flag.USER

仅仅因为标志存在,并不表示标志为所有的邮件服务器/提供程序所支持。例如,除了删除消息外,POP协议对它们都不支持。检查新邮件不是POP的任务,但它已内置到邮件客户程序中。要搞清楚什么标志受到支持,可以使用getPermanentFlags()方法来询问文件夹。

要删除消息,需要为消息设置DELETE标志:

message.setFlag(Flags.Flag.DELETED, true);

第一次以READ_WRITE(读-写)模式打开文件夹:

folder.open(Folder.READ_WRITE);

然后,处理完了所有的消息,请关闭文件夹,并传递true值以擦去删除的消息。

folder.close(true);

用户可使用Folder类的expunge()方法来删除消息。但是,该方法对Sun公司的POP3提供程序不起作用。其他提供程序或许能也或许不能实现其功能。它更有可能适用于IMAP提供程序。由于POP只支持对收件箱的简单访问,使用Sun公司的提供程序时,您将不得不关闭文件夹以删除消息。

要移去标志,只需传递一个false值给setFlag()方法。要看看是否设置了某个标志,可以使用isSet()进行检查。

自我验证

先前学到的是使用Authenticator类,以在需要时提示输入用户名和密码,而不是以字符串的形式传入它们。这里,您将真正看到如何更加充分地使用验证。

不需使用主机、用户名和密码连接到Store,您可以配置Properties带有主机,并告诉Session关于您自定义的Authenticator实例,如下所示:

// Setup properties

Properties props = System.getProperties();

props.put("mail.pop3.host", host);

// Setup authentication, get session

Authenticator auth = new PopupAuthenticator();

Session session = Session.getDefaultInstance(props, auth);

// Get the store

Store store = session.getStore("pop3");

store.connect();

然后您可以使用Authenticator类的子类,并通过getPasswordAuthentication()方法返回一个PasswordAuthentication对象。下面是这种实现的一个例子,其中一个字段同时适用于两部分内容。它不是一个Project Swing指南,只是在一个字段中输入了两部分内容,它们是用逗号隔开的。

import javax.mail.*;

import javax.swing.*;

import java.util.*;

public class PopupAuthenticator extends Authenticator {

public PasswordAuthentication getPasswordAuthentication() {

String username, password;

String result = JOptionPane.showInputDialog(

"Enter 'username,password'");

StringTokenizer st = new StringTokenizer(result, ",");

username = st.nextToken();

password = st.nextToken();

return new PasswordAuthentication(username, password);

}

}

由于PopupAuthenticator依赖于Swing,因而将会启动用于AWT的事件处理线程。这在本质上要求您在代码中添加一个对System.exit()的调用,以终止程序的执行。

回复消息

Message类包含一个reply()方法,以用正确的接收者和主题(添加"Re::",如果没有的话)配置一条新消息。该方法不会为消息添加任何内容,只是为新的接收者复制发送者或回复到的报头。该方法使用一个布尔型参数,提示是否只回复给发送者(false)或回复给所有人(true)。

MimeMessage reply = (MimeMessage)message.reply(false);

reply.setFrom(new InternetAddress("president@whitehouse.gov"));

reply.setText("Thanks");

Transport.send(reply);

在发送消息时要配置回复到地址,可使用setReplyTo()方法。

练习

回复邮件

转发消息

转发消息涉及的内容要稍微多一点,没有一个专门用于转发消息的方法,您可以通过处理组成消息的各个部分来创建要转发的消息。

一条邮件消息可由多个部分组成,每一部分是一个BodyPart(报文部分),或更特殊一点,在操作MIME消息时则是MimeBodyPart。不同的报文部分组合到一个称为Multipart的容器中,或者又更特殊一点,是一个MimeMultipart容器。要转发消息,您要创建一个用于消息文本的部分,和用于要转发的消息的第二个部分,并将这两个部分组合成一个multipart(多个部分)。然后您可以把这个multipart添加到一个合适的注明地址的消息中并发送它。

这就是转发消息的本质。要把一条消息的内容复制给另一条消息,只需通过它的DataHandler类复制即可,它是出自于JavaBeans Activation Framework的一个类。

// Create the message to forward

Message forward = new MimeMessage(session);

// Fill in header

forward.setSubject("Fwd: " + message.getSubject());

forward.setFrom(new InternetAddress(from));

forward.addRecipient(Message.RecipientType.TO,

new InternetAddress(to));

// Create your new message part

BodyPart messageBodyPart = new MimeBodyPart();

messageBodyPart.setText(

"Here you go with the original message:\n\n");

// Create a multi-part to combine the parts

Multipart multipart = new MimeMultipart();

multipart.addBodyPart(messageBodyPart);

// Create and fill part for the forwarded content

messageBodyPart = new MimeBodyPart();

messageBodyPart.setDataHandler(message.getDataHandler());

// Add part to multi part

multipart.addBodyPart(messageBodyPart);

// Associate multi-part with message

forward.setContent(multipart);

// Send message

Transport.send(forward);

操作附件

附件是与邮件消息关联的资源,通常保存在消息之外,如:一个文本文件,电子表格或图片。对于像Eudora和Pine之类的常用邮件程序,您可以通过JavaMail API把资源附加到邮件消息上,并在您接收消息时获取附件。

发送附件

发送附件与转发消息非常相似,您要创建组成完整消息的各个部分。在创建好第一个部分即消息文本之后,您添加的用DataHandler类处理的其他部分就是您的附件,而不是转发消息中的共享处理程序。当您从一个文件读取附件时,附件的数据资源是FileDataSource;从URL读取时,则是URLDataSource。一旦您有了自己的DataSource,在将其通过setDataHandler()方法最终附加到BodyPart上之前,只需将其传递给DataHandler类的构造器即可。假定您想保留附件的原始文件名,要做的最后一件事就是用BodyPart类的setFileName()方法设置与附件关联的文件名。所有这些操作如下所示:

// Define message

Message message = new MimeMessage(session);

message.setFrom(new InternetAddress(from));

message.addRecipient(Message.RecipientType.TO,

new InternetAddress(to));

message.setSubject("Hello JavaMail Attachment");

// Create the message part

BodyPart messageBodyPart = new MimeBodyPart();

// Fill the message

messageBodyPart.setText("Pardon Ideas");

Multipart multipart = new MimeMultipart();

multipart.addBodyPart(messageBodyPart);

// Part two is attachment

messageBodyPart = new MimeBodyPart();

DataSource source = new FileDataSource(filename);

messageBodyPart.setDataHandler(new DataHandler(source));

messageBodyPart.setFileName(filename);

multipart.addBodyPart(messageBodyPart);

// Put parts in message

message.setContent(multipart);

// Send the message

Transport.send(message);

在消息中包含附件时,如果您的程序是一个servlet,您的用户就必须上传附件,并告诉您要把消息发送到什么位置。上传的每一个文件都可以用一个表单来处理,该表单是以multipart/表单数据(form-data)来编码的。

<FORM ENCTYPE="multipart/form-data"

method=post action="/myservlet">

<INPUT TYPE="file" NAME="thefile">

<INPUT TYPE="submit" VALUE="Upload">

</FORM>

注意:消息的大小要受到您的SMTP服务器的限制,而不是由JavaMail API限制的。如果出现了问题,可以通过设置ms和mx参数来考虑增加Java堆区的空间尺寸。

练习

发送附件

获取附件

从消息中取出附件比发送附件涉及的操作要稍微多一点,而MIME没有简单的附件概念。当消息带有附件时,消息的内容就是一个Multipart对象。然后需要处理各个部分,以获取主要内容和附件。通过part.getDisposition()方法标记上Part.ATTACHMENT配置的部分显然就是附件。同时,附件也可以不带有配置(和非文本MIME类型)或Part.INLINE配置。当配置是Part.ATTACHMENT或Part.INLINE时,您可以脱离该消息部分的内容将其保存起来。只需通过getFileName()方法获取原始文件名,并通过getInputStream()方法获取输入流即可。

Multipart mp = (Multipart)message.getContent();

for (int i=0, n=multipart.getCount(); i<n; i++) {

Part part = multipart.getBodyPart(i));

String disposition = part.getDisposition();

if ((disposition != null) &&

((disposition.equals(Part.ATTACHMENT) ||

(disposition.equals(Part.INLINE))) {

saveFile(part.getFileName(), part.getInputStream());

}

}

saveFile()方法只用于根据文件名创建一个文件,从输入流中读取字节,并将它们写入一个文件中去。如果文件已存在,将在文件名后添加一个编号,直到找到一个不存在的文件为止。

// from saveFile()

File file = new File(filename);

for (int i=0; file.exists(); i++) {

file = new File(filename+i);

}

上面的代码介绍了消息的各个部分被标上相应的标志的一个最简单的例子。要想包含所有的情况,还要对disposition值为null及消息部分为MIME类型的情况作相应处理。

if (disposition == null) {

// Check if plain

MimeBodyPart mbp = (MimeBodyPart)part;

if (mbp.isMimeType("text/plain")) {

// Handle plain

} else {

// Special non-attachment cases here of image/gif, text/html, ...

}

...

}

处理HTML消息

发送基于HTML的消息比发送纯文本消息要稍微复杂一点,尽管它不需要做大量的工作。它全部取决于您特定的需求。

发送HTML消息

如果您所要做的全部工作是发送一个等价的HTML文件作为消息,并让邮件阅读者忧心于取出任何嵌入的图片或相关片段,那么就可以使用消息的setContent()方法,以字符串形式传递消息内容,并把内容类型设置为text/html。

String htmlText = "<H1>Hello</H1>" +

"<img src=\"http://www.jguru.com/images/logo.gif\">";

message.setContent(htmlText, "text/html"));

在接收端,如果您用JavaMail API获取消息,在该API中没有内置任何用于以HTML格式显示消息的功能。JavaMail API只以字节流的形式来查看消息。要以HTML格式显示消息,您必须使用Swing JeditorPane或某些第3方HTML阅读器组件。

if (message.getContentType().equals("text/html")) {

String content = (String)message.getContent();

JFrame frame = new JFrame();

JEditorPane text = new JEditorPane("text/html", content);

text.setEditable(false);

JScrollPane pane = new JScrollPane(text);

frame.getContentPane().add(pane);

frame.setSize(300, 300);

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.show();

}

在消息中包含图片

另一方面,如果您的HTML消息中嵌入了作为消息一部分的图片,并且您想保持消息内容的完整,就必须把图片看作附件,并用特殊的通信标识符URL引用该图片,该通信标识符引用的是图片附件的内容ID报文。

嵌入图片的处理与附加一个文件到消息上非常相似,惟一的不同之处在于:您必须区分MimeMultipart中,哪些部分是在构造器(或通过setSubType()方法)通过设置其子类型而使之相关的,以及将图片的内容ID报头设置成任意字符串,它将在img标记中用作图片的源路径。下面显示了一个完整的示例:

String file = ...;

// Create the message

Message message = new MimeMessage(session);

// Fill its headers

message.setSubject("Embedded Image");

message.setFrom(new InternetAddress(from));

message.addRecipient(Message.RecipientType.TO,

new InternetAddress(to));

// Create your new message part

BodyPart messageBodyPart = new MimeBodyPart();

String htmlText = "<H1>Hello</H1>" +

"<img src=\"cid:memememe\">";

messageBodyPart.setContent(htmlText, "text/html");

// Create a related multi-part to combine the parts

MimeMultipart multipart = new MimeMultipart("related");

multipart.addBodyPart(messageBodyPart);

// Create part for the image

messageBodyPart = new MimeBodyPart();

// Fetch the image and associate to part

DataSource fds = new FileDataSource(file);

messageBodyPart.setDataHandler(new DataHandler(fds));

messageBodyPart.setHeader("Content-ID","memememe");

// Add part to multi-part

multipart.addBodyPart(messageBodyPart);

// Associate multi-part with message

message.setContent(multipart);

练习

发送带有图片的 HTML 消息

用SearchTerm搜索

JavaMail API包含一种可用于创建SearchTerm(搜索条件)的筛选机制,它可以在javax.mail.search包中找到。一旦创建了SearchTerm,您就可以询问某个文件夹匹配的消息,并检索出消息对象数组:

SearchTerm st = ...;

Message[] msgs = folder.search(st);

有22种不同的类可用于帮助创建搜索条件。

· AND条件(AndTerm类)

· OR条件(OrTerm类)

· NOT条件(NotTerm类)

· SENT DATE条件(SentDateTerm类)

· CONTENT条件(BodyTerm类)

· HEADER条件(FromTerm / FromStringTerm, RecipientTerm / RecipientStringTerm, SubjectTerm, etc.)

本质上,您可以为匹配的消息创建一个逻辑表达式,然后进行搜索。例如,下面显示了一条消息的条件搜索示例,该消息带有(部分带有)一个ADV主题字符串,其发送者字段为friend@public.com。您可能考虑定期运行该查询,并自动删除任何返回的消息。

SearchTerm st =

new OrTerm(

new SubjectTerm("ADV:"),

new FromStringTerm("friend@public.com"));

Message[] msgs = folder.search(st);


[ Last edited by GShadow on 2004-11-16 at 22:58 ]

 

不知道自己每天都在干什么

不知道自己的未来

不知道活着是为了什么

除了不知道还是不知道


http://gshadow.5dblog.com

mail:13959560305@fj172.com

 2004-11-16 17:11                    

大嘴

 

 


积分 49

发贴 49

注册 2004-11-21

来自 北方

状态 离线  我想学


我想学,难吗?

 2004-11-30 19:31                

黄新

 

 


积分 293

发贴 263

注册 2003-6-22

来自 福建漳州

状态 离线  友情支持一下 -贴一个我很久以前写的支持多附件的mail发送类


package mail;


import javax.mail.*;

import javax.mail.internet.*;

import java.util.*;

import javax.activation.*;

import java.io.*;

/**

* <p>Title: </p>

* <p>Description: </p>

* <p>Copyright: Copyright (c) 2004</p>

* <p>Company: </p>

* @author 黄新

* @version 1.0

*/


public class Mail {

 

  public Mail() {

  }


  /**

   * 发送邮件

   * @param to 收件人

   * @param subject 主题

   * @param body 主体 邮件内容

   * @param from 法件人

   * @param PassWord 密码

   * @param str_files 附件 数组

   * @return 是否发送成功 只能以是否跑出异常来做判断 寻求更好的判断方法

   */

  public boolean sendMail(String to,String subject,String body, String from,String PassWord,String []str_files){

    Properties props = new Properties();

    boolean isSended = true;

    try {

      String protocol = "smtp";//smtp  pop3

      String host = getHost(from,protocol);

      String username = getUsername(from);

      //Setup mail server

      props.put("mail."+protocol+".host",host);//smtp  pop3

      //Get Session

      props.put("mail."+protocol+".auth","true");

      PopupAuthenticator popAuthenticator = new PopupAuthenticator();

      PasswordAuthentication pop = popAuthenticator.performCheck(username,PassWord);

      Session session = Session.getInstance(props,popAuthenticator);


      //Define message

      MimeMessage message=new MimeMessage(session);

      message.setFrom(new InternetAddress(from));


      message.setSentDate(new java.util.Date ()) ;


      message.addRecipient(Message.RecipientType.TO,

                           new InternetAddress(to));

      message.setSubject(subject);

      //给消息对象设置内容

      BodyPart textBodyPart=new MimeBodyPart();

      textBodyPart.setContent(body,"text/html;charset=gb2312") ;

      Multipart mm=new MimeMultipart();

      mm.addBodyPart(textBodyPart);

      int i = str_files.length ;

        mm.addBodyPart(getFileBodyPart(str_files[i-1])) ;

        i--;

      }

      message.setContent(mm) ;

      message.saveChanges() ;

      Transport.send(message);

    }

    catch(AuthenticationFailedException afe){

      isSended = false;

      System.out.println("登陆验证出现错误 ,请检查你的用户名和密码") ;

      afe.printStackTrace() ;

    }

    catch(MessagingException me){

      isSended = false;

      me.printStackTrace() ;

      System.out.print("") ;

    }

    catch(Exception e){

      isSended = false;

      e.printStackTrace() ;

    }

    return isSended;

  }

  /**

   * 获得通过邮件地址获取用户名

   * @param email 邮件地址

   * @return 用户名

   */

  private String getUsername(String email){

    StringBuffer str = new StringBuffer(email);

    String usename = str.substring(0,str.indexOf("@") ) ;

    return usename;

  }

  /**

   * 通过邮件地址获取邮件服务器地址

   * @param email 邮件地址

   * @param protocol 邮件协议

   * @return 邮件服务器主机地址

   */

  private String getHost(String email,String protocol){

    StringBuffer str = new StringBuffer(email);

    String host = protocol+"." + str.substring(str.indexOf("@")+1 ) ;

    return host;

  }

  private BodyPart getFileBodyPart(String str_file){

    BodyPart  fileBodyPart = new MimeBodyPart();

//    int NO_files = str_files.length ;

    try {

      File file = new File(str_file);

      FileDataSource fds=new FileDataSource(file);//用本地文件

      DataHandler dh = new DataHandler(fds);

      fileBodyPart.setFileName(file.getName());//可以和原文件名不一致

      fileBodyPart.setDataHandler(dh);


    }

    catch (MessagingException ME) {

      ME.printStackTrace() ;

      System.out.println("获取文件名setFileName或设置setDataHandler时出现错误") ;

      return null;

    }

    return fileBodyPart;

  }

  public static void main(String[] args) {

    String[] str_files ={"G:\\192.168.7.144备份\\学习资料\\技术文章\\eclipse 参考手册\\CSDN_eclipse 参考手册(三).htm ","G:\\日立.html"};

    Mail m = new Mail();

    System.out.println(m.sendMail("xini_huang@hotmail.com","nihao","helloworld!!!!","huangxinyi2003@163.com","差点把自己的密码给泄漏了",str_files)) ;

    //System.out.println(m.getUsername("huangxinyi2003@163.com")+"======"+m.getHost("huangxinyi2003@163.com")  ) ;

  }

}


[ Last edited by 黄新 on 2004-12-2 at 16:31 ]

 2004-12-2 16:26                

黄新

 

 


积分 293

发贴 263

注册 2003-6-22

来自 福建漳州

状态 离线  验证


package mail;

import javax.mail.*;

import javax.mail.internet.*;

/**

* <p>Title: </p>

* <p>Description: </p>

* <p>Copyright: Copyright (c) 2004</p>

* <p>Company: </p>

* @author 黄新

* @version 1.0

*/


public class PopupAuthenticator extends Authenticator{

  String username=null;

  String password=null;

  public PopupAuthenticator(){

  }

  public PasswordAuthentication performCheck(String user,String pass){

    username = user;

    password = pass;

    return getPasswordAuthentication();

  }

  protected PasswordAuthentication getPasswordAuthentication() {

    return new PasswordAuthentication(username, password);

  }

  public static void main(String[] args) {

  }


}

分享到:
评论

相关推荐

    电力系统中基于MATLAB的价格型需求响应与电价弹性矩阵优化

    内容概要:本文详细介绍了如何利用MATLAB进行价格型需求响应的研究,特别是电价弹性矩阵的构建与优化。文章首先解释了电价弹性矩阵的概念及其重要性,接着展示了如何通过MATLAB代码实现弹性矩阵的初始化、负荷变化量的计算以及优化方法。文中还讨论了如何通过非线性约束和目标函数最小化峰谷差,确保用户用电舒适度的同时实现负荷的有效调节。此外,文章提供了具体的代码实例,包括原始负荷曲线与优化后负荷曲线的对比图,以及基于历史数据的参数优化方法。 适合人群:从事电力系统优化、能源管理及相关领域的研究人员和技术人员。 使用场景及目标:适用于希望深入了解并掌握价格型需求响应机制的专业人士,旨在帮助他们更好地理解和应用电价弹性矩阵,优化电力系统的负荷分布,提高能源利用效率。 其他说明:文章强调了实际应用中的注意事项,如弹性矩阵的动态校准和用户价格敏感度的滞后效应,提供了实用的技术细节和实践经验。

    一级医院医疗信息管理系统安装调试技术服务合同20240801.pdf

    一级医院医疗信息管理系统安装调试技术服务合同20240801.pdf

    表5 文献综述.doc

    表5 文献综述.doc

    36W低压输入正激电源, 正激变压器设计方法步骤及谐振电感的设计方法,主要讲诉了正激电源变压器测的输入输出参数,按输入的条件设计相关的变压器的参数,同时将输出电感的设计方法一并例出,详细的设计步骤

    36W低压输入正激电源 变压器电感设计

    基于YOLOv8的深度学习课堂行为检测系统源码(含检测图片和视频)

    基于YOLOv8的深度学习课堂行为检测系统源码,软件开发环境python3.9,系统界面开发pyqt5。在使用前安装python3.9,并安装软件所需的依赖库,直接运行MainProgram.py文件即可打开程序。模型训练时,将train,val数据集的绝对路径改为自己项目数据集的绝对路径,运行train.py文件即可开始进行模型训练,内含项目文件说明,以及检测图片和视频。

    odbc-oracle zabbix模版原版

    odbc_oracle zabbix模版原版

    基于纳什谈判理论的风光氢多主体能源系统合作运行方法——综合能源交易与优化模型

    内容概要:本文探讨了利用纳什谈判理论来优化风光氢多主体能源系统的合作运行方法。通过MATLAB代码实现了一个复杂的优化模型,解决了风电、光伏和氢能之间的合作问题。文中详细介绍了ADMM(交替方向乘子法)框架的应用,包括联盟效益最大化和收益分配谈判两个子任务。此外,还涉及了加权残差计算、目标函数构造、可视化工具以及多种博弈模式的对比等功能模块。实验结果显示,合作模式下系统总成本显著降低,氢能利用率大幅提升。 适合人群:从事能源系统研究的专业人士、对博弈论及其应用感兴趣的学者和技术人员。 使用场景及目标:适用于需要优化多主体能源系统合作运行的场合,如工业园区、电网公司等。主要目标是提高能源利用效率,降低成本,增强系统的灵活性和稳定性。 其他说明:代码中包含了丰富的可视化工具,能够帮助研究人员更好地理解和展示谈判过程及结果。同时,提供了多种博弈模式的对比功能,便于进行性能评估和方案选择。

    C#与Halcon联合编程实现高效视觉几何定位与测量框架

    内容概要:本文详细介绍了如何利用C#与Halcon联合编程构建高效的视觉几何定位与测量框架。主要内容涵盖模板创建与匹配、圆测量、数据持久化以及图像采集等方面的技术细节。首先,通过创建形状模板并进行匹配,实现了工件的精确定位。接着,针对圆形物体的测量,提出了动态ROI绘制、亚像素边缘提取和稳健圆拟合的方法。此外,还讨论了模板管理和图像采集的最佳实践,确保系统的稳定性和高效性。最后,强调了Halcon对象的内存管理和错误处理机制,提供了实用的优化建议。 适合人群:具备一定编程基础,尤其是对C#和Halcon有一定了解的研发人员和技术爱好者。 使用场景及目标:适用于工业生产线上的自动化检测设备开发,旨在提高工件定位和尺寸测量的精度与效率。主要目标是帮助开发者掌握C#与Halcon联合编程的具体实现方法,从而构建稳定可靠的视觉检测系统。 其他说明:文中提供了大量实战代码片段和调试技巧,有助于读者快速理解和应用相关技术。同时,作者分享了许多实际项目中的经验和教训,使读者能够避开常见陷阱,提升开发效率。

    QT6 C++视频播放器实现(基于QGraphicsVideo)

    QT视频播放器实现(基于QGraphicsView)

    评估管线钢环焊缝质量及其对氢脆的敏感性.pptx

    评估管线钢环焊缝质量及其对氢脆的敏感性.pptx

    机器学习(预测模型):专注于 2024 年出现的漏洞(CVE)信息数据集

    该是一个在 Kaggle 上发布的数据集,专注于 2024 年出现的漏洞(CVE)信息。以下是关于该数据集的详细介绍:该数据集收集了 2024 年记录在案的各类漏洞信息,涵盖了漏洞的利用方式(Exploits)、通用漏洞评分系统(CVSS)评分以及受影响的操作系统(OS)。通过整合这些信息,研究人员和安全专家可以全面了解每个漏洞的潜在威胁、影响范围以及可能的攻击途径。数据主要来源于权威的漏洞信息平台,如美国国家漏洞数据库(NVD)等。这些数据经过整理和筛选后被纳入数据集,确保了信息的准确性和可靠性。数据集特点:全面性:涵盖了多种操作系统(如 Windows、Linux、Android 等)的漏洞信息,反映了不同平台的安全状况。实用性:CVSS 评分提供了漏洞严重程度的量化指标,帮助用户快速评估漏洞的优先级。同时,漏洞利用信息(Exploits)为安全研究人员提供了攻击者可能的攻击手段,有助于提前制定防御策略。时效性:专注于 2024 年的漏洞数据,反映了当前网络安全领域面临的新挑战和新趋势。该数据集可用于多种研究和实践场景: 安全研究:研究人员可以利用该数据集分析漏洞的分布规律、攻击趋势以及不同操作系统之间的安全差异,为网络安全防护提供理论支持。 机器学习与数据分析:数据集中的结构化信息适合用于机器学习模型的训练,例如预测漏洞的 CVSS 评分、识别潜在的高危漏洞等。 企业安全评估:企业安全团队可以参考该数据集中的漏洞信息,结合自身系统的实际情况,进行安全评估和漏洞修复计划的制定。

    QML Combobox 自动过滤,输入字符串后自动匹配

    博客主页:https://blog.csdn.net/luoyayun361 QML ComboBox控件,输入关键字后自动过滤包含关键字的列表,方便快速查找列表项

    【人工智能领域】人工智能技术发展历程、核心原理及应用指南:涵盖机器学习、深度学习、NLP和计算机视觉的全面介绍

    内容概要:本文全面介绍了人工智能技术的发展历程、核心技术原理、应用方法及其未来趋势。首先阐述了人工智能的定义和核心目标,随后按时间顺序回顾了其从萌芽到爆发的五个发展阶段。接着详细讲解了机器学习、深度学习、自然语言处理和计算机视觉等核心技术原理,并介绍了使用现成AI服务和开发自定义AI模型的应用方法。此外,还展示了智能客服系统、图像分类应用和智能推荐系统的具体实现案例。针对普通用户,提供了使用大模型的指南和提问技巧,强调了隐私保护、信息验证等注意事项。最后展望了多模态AI、可解释AI等未来发展方向,并推荐了相关学习资源。; 适合人群:对人工智能感兴趣的初学者、技术人员以及希望了解AI技术应用的普通大众。; 使用场景及目标:①帮助初学者快速了解AI的基本概念和发展脉络;②为技术人员提供核心技术原理和应用方法的参考;③指导普通用户如何有效地使用大模型进行日常查询和任务处理。; 其他说明:本文不仅涵盖了AI技术的基础知识,还提供了丰富的实际应用案例和实用技巧,旨在帮助读者全面理解人工智能技术,并能在实际工作中加以应用。同时提醒读者关注AI伦理和版权问题,确保安全合法地使用AI工具。

    本学习由 Matrix 工作室制作并开发,包括算法与数据结构的学习路线和各种题解

    本学习由 Matrix 工作室制作并开发,包括算法与数据结构的学习路线和各种题解。

    基于智慧图书馆基础业务流程Axure11高保真原型设计

    本项目致力于构建基于微服务架构的智慧图书馆管理平台,重点突破多校区图书馆异构系统间的数据壁垒。通过建立统一数据治理规范、部署智能分析模块、重构业务流程引擎,系统性实现以下建设目标:构建跨馆业务数据的标准化整合通道,实施容器化部署的弹性资源管理体系,开发具备机器学习能力的业务辅助决策系统,打造可量化评估的管理效能提升模型,最终形成支持PB级数据处理的分布式存储体系与全维度数据资产图谱。

    mysql中慢sql分析

    根据processlist查询出慢sql 1.修改配置文件中的mysql链接 2.目前是15秒执行一次获取执行时间在5秒上的sql,可以在配置中修改 3.执行后查出的慢sql会记录到log文件夹中以日期命名的txt文件中,可自行查验

    全域通航 低空经济服务平台建设实施方案.pptx

    全域通航 低空经济服务平台建设实施方案.pptx

    全国联合交通查询手册,涵盖各大城市

    全国交通一卡通互联互通服务手册,支持在线查询

    电力电子中移相全桥DC-DC变换器的Simulink离散化建模与优化

    内容概要:本文详细介绍了如何在Simulink中进行移相全桥DC-DC变换器的离散化建模及其优化。主要内容包括搭建主电路、PWM波形生成、数字PI调节器的设计以及针对负载突变情况下的闭环控制优化。文中特别强调了移相控制、死区时间设置、采样周期选择、积分限幅、前馈补偿等关键技术点的应用,确保在极端负载条件下(如从3kW突变为3.6W)输出电压仍能保持稳定。此外,作者还分享了许多实践经验,如避免非线性磁化曲线带来的数值振荡、合理设置仿真步长等。 适合人群:从事电力电子研究或开发的技术人员,尤其是对移相全桥变换器感兴趣的研究者和技术爱好者。 使用场景及目标:适用于需要深入了解移相全桥DC-DC变换器工作原理及其在Simulink环境下的离散化建模和优化的人群。目标是掌握如何通过合理的参数设定和算法改进,使系统能够在复杂工况下保持良好的性能。 其他说明:文中提供了大量具体的Matlab/Simulink代码片段,帮助读者更好地理解和实践相关概念。同时,作者也指出了许多常见的陷阱和注意事项,有助于初学者少走弯路。

    西门子S7-1200 PLC污水处理项目的博途V17程序设计与优化

    内容概要:本文详细介绍了西门子S7-1200 PLC在污水处理项目中的应用,涵盖模拟量处理、设备轮换、Modbus通讯控制以及事件记录等多个方面。具体包括:使用4-20mA超声波传感器进行液位检测并采用滑动窗口滤波法处理信号,确保液位波动控制在±2cm以内;通过SCL代码实现两组提升泵的智能轮换,避免长时间连续运行带来的设备损耗;利用Modbus TCP和RTU协议对变频器进行精确控制,确保鼓风机和其他设备的稳定运行;采用ALARM_S函数和循环存储队列实现高效的报警管理和事件记录。此外,文中还分享了许多实际操作中的经验和技巧,如硬件滤波与软件校验结合、防止设备同时启动的延时机制等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是熟悉西门子PLC编程和博途软件使用的专业人士。 使用场景及目标:适用于污水处理厂或其他类似工业环境中,旨在提高PLC系统的稳定性和可靠性,减少维护成本,延长设备使用寿命。通过对文中提供的代码片段和实践经验的学习,可以帮助工程师更好地理解和掌握PLC编程技巧,从而应用于实际工程项目中。 其他说明:文中不仅提供了具体的编程实例,还分享了很多宝贵的实战经验,如如何处理传感器异常、优化通讯协议配置等。这些内容对于初学者来说是非常宝贵的知识财富,能够帮助他们快速成长并在工作中游刃有余。

Global site tag (gtag.js) - Google Analytics