Spring Mail Send (asynchronous + sync)

Source: Internet
Author: User
Tags getmessage log log ssl connection stringbuffer

Thank you: http://r164.blog.163.com/blog/static/19749695201043084930451/

Before the project to do a send mail, because the attachment is very large, sent very slowly, but after the asynchronous send, found

The user experience is really good.

JavaMail Realistic synchronous or asynchronous mail delivery using the Spring Framework package

Network collection 2010-05-30 08:49:30 read 60 comments 0 Size: Big Small Subscribe

Reprinted from Http://howsun.blog.sohu.com/129043957.html

Author: Zhang Jihao

Java-EE is simply an extension of the standard specification of various applications on the JDK, and mail processing is one of the most important applications. Since it is a specification, we can write a mail processing system through the JDK following the Mail protocol, but in fact there are already many vendors and open source organizations doing so. Apache is one of the most active of Java EE, and of course, our eldest brother--sun.

Talk about the boss, Sentovan. He has joined oracle--Oracle (not the one engraved on the turtle shell). Is my Chinese, is also the earliest human language ah, thousands of years earlier than Java, and its boss Ellison is a good sailor, do not think that is only on the sailboat, at least he is not so heartless gates-open source Long live. There is reason to believe that the Java world still has a glorious course. Google's Android and Chrome OS two operating systems will also prefer Java as the basic language for application development, even if it is easy to launch its own language. At the same time, I have a hunch that ChromeOS's future is immeasurable, it may be an important part of driving cloud computing, andtroid (mainly used on mobile devices, the future may be the mainstream of mobile phone operating system), and even Microsoft's windows in the future may be a small window of the system. Microsoft has become senile, and then with the lost Yahoo cooperation, the pace of progress will be greatly slowed down. Investors can now buy Google shares in the long term (investment advice, must be judged). I also use Google search engine, gmail.

Well, gossip less, talk to the theme.

Perhaps everybody as the author uses most is the eldest brother's JavaMail, although the eldest realizes the mail function, but calls up still needs the more complex code to complete, moreover the beginner call success rate is very low (because it also wants to communicate with the outside server), this makes the beginner to it learns more confused. But there are a lot of examples, so the author no longer repeats the sample code here, but focuses on the message processing capabilities encapsulated in the spring framework.

Before we start, we understand the environment. I am open to the Web project, the required basic configuration is as follows:

▲JDK 1.6

▲J2EE 1.5

▲javamail 1.4: Java EE 1.5 has been incorporated into the message specification, so do not import jar packs from JavaMail during development, so you can put jar packages into the Web container's library (for example, under Tomcat's Lib directory). To understand its meaning can refer to the use of database-driven package. The end of the article will be further explained;

▲spring 2.5

▲ a mailbox As mentioned above, I love to use Google's Gmail mailbox.

List of main documents:

Mailservice.java Mail Processing Object interface

Mailserviceimpl.java above realization

Email.java an ordinary JavaBean for encapsulating mail data and corresponding to form forms in HTML pages

Mailcontroller.java Action Processor

Spring-core-config.xml Spring Core Configuration

In the author's Web project, the Web layer uses spring @MVC, of course, we only need to understand its principles, using a servlet or struts framework to do the Web Layer action processor can be achieved. Other files, such as the Web.xml,web layer configuration, are slightly different.

The following start code: spring-core-config.xml:

<!--① Mail server-->
<bean id= "MailSender" class= "Org.springframework.mail.javamail.JavaMailSenderImpl" >
<property name= "Protocol" value= "SMTP"/>
<property name= "host" value= "smtp.gmail.com"/>
<property name= "Port" value= "465"/><!--Gmail's SMTP port is this, to Google website to understand it-->
<property name= "username" value= "to Google to register a gmail account"/>
<property name= "Password" value= "This is the code"/>
<property name= "Javamailproperties" >
<props>
<prop key= "Mail.smtp.auth" >true</prop>
<prop key= "Mail.smtp.starttls.enable" >true</prop>
<prop key= "Mail.smtp.socketFactory.class" >javax.net.ssl.SSLSocketFactory</prop>
<!--SSL connection required by Gmail-->
</props>
</property>
</bean>

<!--② Asynchronous thread executor-->
<bean id= "Taskexecutor" class= "Org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<property name= "Corepoolsize" value= "ten"/>
<property name= "maxpoolsize" value= "/>"
</bean>

This is the two core configuration of mail processing, the first configuration (①) is to assemble a javamailsender Bean into the container, which is the JavaMail encapsulation, in which the most critical is the attribute parameters of the assembly process, which are strictly in accordance with the JavaMail specification, Also meet the requirements of the mail provider, for example, the number of SMTP server ports, whether to authenticate when sending, whether the server is securely connected, encrypted when connected, and what encryption method to use, the mail service provider of these parameters directly affect the above configuration, this is often the most easy to ignore the novice link, Therefore, be sure to go to the mail provider's site to learn more about the technical parameters of the mailbox before you configure it.

Synchronous asynchronous Send problem: JavaMail message processing is synchronous, that is, the user triggers events, communication with SMTP server, server return status message, program end is single-threaded, at this time because of socket communication, server business processing speed and other reasons, so that processing times is unknown. A simple example: if a user sends an activation account message at the same time as the registration, the user may not know that the mail server is blocking the day without responding to the failure of registration and give up, which will be the failure of the design, but asynchronous way to solve these problems. Asynchronous way is simply to give the mail processing task to another thread, Java EE has two solutions, one is the use of JMS,JMS can achieve synchronous and asynchronous message processing, the message as an asynchronous message, you can implement asynchronous mail delivery. JMS is an advanced application of Java EE, so it is not supported for web-only containers, such as Tomcat (which can certainly be found to solve), and this article no longer involves new modules due to space limitations. Another option is to take advantage of the support of executor in JDK, and the subsequent version of JDK 5.0 adds java.util.concurrent a powerful concurrency toolkit that includes actuators, timers, locks, thread-safe queues, thread-task frameworks, and so on. executor--actuator, which separates the "commit" and "execute" of the task, and our mail Processing task can use it to implement asynchronously. And the Spring framework provides encapsulation, see ②. Let's look at how to use it, as shown in the following code.

Mailserviceimpl.java:

Package Com.zhangjihao.service.impl;

Import java.io.IOException;

Import Javax.annotation.Resource;
Import javax.mail.MessagingException;
Import Javax.mail.internet.MimeMessage;

Import Org.apache.commons.logging.Log;
Import Org.apache.commons.logging.LogFactory;
Import Org.springframework.core.io.ByteArrayResource;
Import Org.springframework.core.task.TaskExecutor;
Import Org.springframework.mail.javamail.JavaMailSender;
Import Org.springframework.mail.javamail.MimeMessageHelper;
Import Org.springframework.stereotype.Service;
Import Org.springframework.web.multipart.MultipartFile;

Import Com.zhangjihao.bean.Email;
Import Com.zhangjihao.service.MailService;
Import Com.zhangjihao.util.StringUtil;

/**
* Description:<br>
*
* @author Zhang Jihao
* @version
* Build Time June 24, 2009
*/
@Service ("Mailservice")
public class Mailserviceimpl implements Mailservice {

@Resource Javamailsender mailsender;//injected into the javamail,spring XML in the spring package had the framework assembled
@Resource taskexecutor taskexecutor;//injected into the spring encapsulated asynchronous actuator

Private log log = Logfactory.getlog (GetClass ());
Private StringBuffer message = new StringBuffer ();

public void SendMail (email email) throws Messagingexception, IOException {
if (email.getaddress () = null | | email.getaddress (). Length = = 0) {
This.message.append ("no Recipient");
Return
}
if (email.getaddress (). length > 5) {//recipient is greater than 5, send asynchronously
Sendmailbyasynchronousmode (email);
This.message.append ("Too many recipients, sending ...<br/> in asynchronous mode");
}else{
Sendmailbysynchronizationmode (email);
This.message.append ("Sending mail in sync ...<br/>");
}
}

/**
* Send asynchronously
* @see Com.zhangjihao.service.mailservice#sendmailbyasynchronousmode (com.zhangjihao.bean.Email)
*/
public void Sendmailbyasynchronousmode (final email email) {
Taskexecutor.execute (New Runnable () {
public void Run () {
try {
Sendmailbysynchronizationmode (email);
catch (Exception e) {
Log.info (e);
}
}
});
}

/**
* Sync Send
* @throws IOException
* @see Com.zhangjihao.service.mailservicemode#sendmail (com.zhangjihao.bean.Email)
*/
public void Sendmailbysynchronizationmode (email email) throws Messagingexception, IOException {
MimeMessage MIME = Mailsender.createmimemessage ();
Mimemessagehelper helper = new Mimemessagehelper (MIME, True, "utf-8");
Helper.setfrom ("cs@chinaptp.com");/sender
Helper.setto (Email.getaddress ());//Recipient
HELPER.SETBCC ("administrator@chinaptp.com")/Dark Send
if (Stringutil.haslength (EMAIL.GETCC ())) {
String cc[] = EMAIL.GETCC (). Split (";");
HELPER.SETCC (cc);/CC
}
Helper.setreplyto ("cs@chinaptp.com");/reply to
Helper.setsubject (Email.getsubject ());//Mail subject
Helper.settext (Email.getcontent (), true);//true indicates HTML format

Embedded resources, which are rarely used, because most of the resources are on the web, just a URL in the body of the message is enough.
Helper.addinline ("logo", New Classpathresource ("logo.gif"));

Handling Attachments
For (Multipartfile file:email.getAttachment ()) {
if (file = = NULL | | file.isempty ()) {
Continue
}
String fileName = File.getoriginalfilename ();
try {
FileName = new String (filename.getbytes ("Utf-8"), "iso-8859-1");
catch (Exception e) {}
Helper.addattachment (FileName, New Bytearrayresource (File.getbytes ()));
}
Mailsender.send (MIME);
}

Public StringBuffer GetMessage () {
return message;
}

public void Setmessage (StringBuffer message) {
this.message = message;
}
}

This class implements the Mailservice interface, which has only three methods (the interface file code is omitted): A transmitter, a synchronous sending method, an asynchronous send method. Through its implementation of Mailserviceimpl code can be seen, the message sent only in the synchronous send this method, when the need to execute asynchronously, just throw it into the taskexecutor asynchronous actuator, it is so simple. These three methods are all public decorated, so it's OK to call at random on the top. Here's a simple call code.

Before calling, to allow beginners to better accept, first list Email.java code: Email.java:

Package Com.zhangjihao.bean;

Import java.io.Serializable;

Import Org.springframework.web.multipart.MultipartFile;

Import Com.zhangjihao.util.StringUtil;

/**
* Description:<br>
*
* @author Zhang Jihao
* @version
* Build Time June 24, 2009
*/
public class Email implements Serializable {

Private static final long serialversionuid = 9063903350324510652L;

/** User group: You can send messages in bulk by user group **/
Private Usergroups usergroups;

 /** recipient **/
 private String addressee;
&NBSP
 /** Copy to **/
 private String cc;
&NBSP
 /** Message subject **/
 private String subject;
&NBSP
 /** message content **/
 private String content;
&NBSP
 /** attachment **/
 private multipartfile[] attachment = new Multipartfile[0];
 
 //////////////////////////resolves mail addresses//////////////////////////////
 
 public String [] GetAddress () {
  if (! Stringutil.haslength (This.addressee)) {
   return null;
&NBSP;&NBSP}
  addressee = Addressee.trim ();
  addressee.replaceall (";", ";");
  addressee.replaceall ("", ";");
  addressee.replaceall (",", ";");
  addressee.replaceall (",", ";");
  addressee.replaceall ("|", ";");
  return addressee.split (";");
 }

Getter && setter///////////////////////////////

......
}

This class is a simple javabean that encapsulates mail data and can be understood as a actionform for readers accustomed to using the struts framework. However, it may be difficult to understand the multipartfile type and the attachment attribute of the array, and familiarity with the struts framework can be regarded as formfile, which may be well understood in Struts2. The author is using spring MVC, which is built into the framework, so it's easy to convert the file that the form form uploads into this field.

Let's take a look at the Web-tier call, which is the end of the article, so the web calls all around the three methods in Mailservice, a comprehensive understanding of the code, but it's best to know some of the knowledge of spring @MVC.

Mailcontroller.java:

Package Com.zhangjihao.web.controller.system;

Import java.util.List;

Import Javax.annotation.Resource;
Import Javax.servlet.http.HttpServletRequest;

Import Org.springframework.mail.javamail.JavaMailSender;
Import Org.springframework.stereotype.Controller;
Import Org.springframework.ui.ModelMap;
Import Org.springframework.validation.BindingResult;
Import Org.springframework.web.bind.annotation.ModelAttribute;
Import org.springframework.web.bind.annotation.RequestMapping;
Import Org.springframework.web.bind.annotation.RequestMethod;
Import Org.springframework.web.bind.annotation.RequestParam;

Import Com.zhangjihao.bean.Email;
Import Com.zhangjihao.domain.user.User;
Import Com.zhangjihao.service.MailService;
Import Com.zhangjihao.service.UserService;
Import Com.zhangjihao.util.StringUtil;
Import Com.zhangjihao.web.controller.MasterController;
Import Com.zhangjihao.web.validator.EmailValidator;

/**
* Description:<br>
* Mail Sending processor
* @author Zhang Jihao
* @version
* Build Time June 24, 2009
*/
@Controller
public class Mailcontroller extends Mastercontroller {

@Resource Mailservice Mailservice;
@Resource UserService UserService;

@RequestMapping (value = "/sendemail", Method=requestmethod.get)
public string SendEmail (@RequestParam (value= "email", required=false) string singleemailaddress, HttpServletRequest Request) {
email email = new email ();
if (Stringutil.haslength (singleemailaddress)) {
Email.setaddressee (singleemailaddress);
}
Request.setattribute ("email", email);
return "System/sendmail";
}

@RequestMapping (value = "/sendemail", Method=requestmethod.post)
Public String Send (
@ModelAttribute email email,//spring MVC encapsulates data from form forms into this object
Bindingresult result,
Modelmap model,
HttpServletRequest request) {
try {
New Emailvalidator (). Validate (email, result);
if (Result.haserrors ()) {
throw new RuntimeException ("Incorrect data filling");
}
if (Email.getemailgroup ()!=null) {
list<user> users = userservice.getuserbyusergroups (Email.getemailgroup (), "Username,email", NULL, NULL);
StringBuffer sb = new StringBuffer (Stringutil.haslengthbytrim () (Email.getaddressee)? (Email.getaddressee (). Trim () + ";") : "");
for (User user:users) {
Sb.append (User.getemail ()). Append (";");
}
Email.setaddressee (Sb.tostring ());
}
if (email.getaddress () ==null | | email.getaddress (). length==0) {
Request.setattribute ("message", "No recipient!");
return "message";
}

Mailservice.sendmail (email); When larger than 5 recipients, the splitter automatically chooses to send asynchronously
Request.setattribute ("Message", Mailservice.getmessage (). Append ("This has been sent together"). Append (Email.getaddress (). length). Append ("email."). ToString ());

catch (Exception e) {
Request.setattribute ("message", "has errors! The info by "+e.getmessage () +" <br/>can log into to view more detailed information on abnormalities. ");
Log.error (Exception in This.getclass (). GetName () + "---------------:/n", e);
}
Return to + "message";
}
}

When a get-method-requested connection comes in, the controller shifts to an HTML page with form forms, fields in the form that correspond to Email.java, and when the Post method comes in, Spring MVC fills the data in the form into an email object. It's OK to give mailservice treatment.

Finally, the most likely error is described:

Many people on the internet say that j2ee5 compatibility is not good, such as the typical javamail1.4 in the package and J2ee5 in the package interface package caused the conflict, resulting in unit testing often reported the following error:

Java.lang.noclassdeffounderror:com/sun/mail/util/bencoderstream

Of course, this error is not the javamail of the implementation of the introduction of the Project (no guide package), but after the guide package, there will be another error:

Java.lang.noclassdeffounderror:com/sun/mail/util/lineinputstream

At this time even the Web container can not start, often have netizens for these two abnormal make a mess, so replace j2ee1.4, will affect the project. But the concept must be clear, the problem can be solved. J2ee5 in the Mail.jar package is defined as only the interface, not implemented, is not really send mail, but the development of the compilation must be able to pass, because we are in accordance with the code of the Java EE program. and the operating period with the Sun Company's JavaMail1.4 implementation can begin to send mail, but the boss why the two conflict?

The author's solution is:

    Development period do not guide the package, the runtime will javamail1.4 the Mail.jar package in the compressed file into the Tomcat/lib directory, which can be developed and run completely. To do unit tests, you open a new Java project, note that, not Web engineering, you can put the Mail.jar in the javamail1.4 compression pack under the classpath of the project.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.