RabbitMQ系列之六 Spring RabbitMQ整合实现案例之 异步邮件发送

摘要:给用户发送邮件的场景,其实也是比较常见的,比如用户注册需要邮箱验证,用户异地登录发送邮件通知等等,在这里我以 RabbitMQ 实现异步发送邮件。
项目git地址:https://github.com/gitcaiqing/RabbitMQ-Email
1.项目结构
RabbitMQ系列之六 Spring RabbitMQ整合实现案例之 异步邮件发送_第1张图片
2.构建项目
创建maven项目,引入jar包,pom.xml配置如下


  4.0.0
  com.sc
  RabbitMQ-Emali
  0.0.1-SNAPSHOT
  war
  
  
    UTF-8
    4.1.4.RELEASE
	2.5.0
	1.2.3
  
  
  
  		
  		
			com.rabbitmq
			amqp-client
			3.4.1
		
		
       		org.springframework.amqp
       		spring-rabbit
       		1.4.0.RELEASE
    	 
    	
    	
	    
	         javax.mail
	         mail
	         1.4.7
	    
  
   		  
          
            org.springframework  
            spring-core  
            ${spring.version}  
          
  
          
            org.springframework  
            spring-web  
            ${spring.version}  
          
          
            org.springframework  
            spring-oxm  
            ${spring.version}  
          
          
            org.springframework  
            spring-tx  
            ${spring.version}  
          
  
          
            org.springframework  
            spring-jdbc  
            ${spring.version}  
          
  
          
            org.springframework  
            spring-webmvc  
            ${spring.version}  
          
          
            org.springframework  
            spring-aop  
            ${spring.version}  
          
  
          
            org.springframework  
            spring-context-support  
            ${spring.version}  
          
  
          
            org.springframework  
            spring-test  
            ${spring.version}  
         

		
		
			log4j
			log4j
			1.2.17
		
		
		
			org.slf4j
			slf4j-api
			1.7.7
		
		
			org.slf4j
			slf4j-log4j12
			1.7.7
		
	
		
		
		    javax.servlet
		    javax.servlet-api
		    3.0.1
		    provided
		
		
		
			javax.servlet
			jstl
			1.2
		
	
		
		
			org.codehaus.jackson
			jackson-mapper-asl
			1.9.13
		
	
		
			com.fasterxml.jackson.core
			jackson-annotations
			${jackson.version}
		
	
		
			com.fasterxml.jackson.core
			jackson-core
			${jackson.version}
		
	
		
			com.fasterxml.jackson.core
			jackson-databind
			${jackson.version}
		
		
  
  
    
		
			org.apache.maven.plugins
			maven-compiler-plugin
			3.2
			
				1.7
				1.7
			
		
	
  

3.项目配置,着重实现邮件发送,配置简化处理
3.1 RabbitMQ和邮件地址配置config->config.properties

#RabbitMQ 连接配置
rmq.host=127.0.0.1
rmq.port=5672
rmq.user=guest
rmq.password=guest
rmq.channelCacheSize=25
rmq.virtual=/

#邮件发送配置

# 163 mail server
mail.protocol=smtp
mail.port=25
mail.host=smtp.163.com
#发送邮件的邮箱地址账号信息
[email protected]
[email protected]
mail.password=xxxxxxxxx

# qq mail server
#mail.protocol=smtp
#mail.port=465
#mail.host=smtp.exmail.qq.com
#[email protected]
#mail.password=

3.2 spring 配置spring->applicationContext.xml




	
	
	


3.3 spring邮件配置spring->spring-mail.xml

  
    	Spring 邮件发送bean配置
     	
     	
     		
           
           
           
           
               
                  true
                  25000
                  javax.net.ssl.SSLSocketFactory
                    
                  true
               
           
     	
     	
    

3.4 RabbitMQ配置spring-rabbitmq.xml


	Spring RabbitMQ 路由模式(Routing)配置
	
	
	
	
 	
 	
 	
 	
 	
 
 	
 	
 	
 	
 	
 		
 			
 		
 	
 	
 	
 	

	
 	
	
 	
 		
 	
 	

3.5 spring mvc配置servlet->spring-mvc.xml



		
	
    
    	
		
	
    
	
	
	
		
        
        
	
	

3.6 web.xml配置

 
    
       RabbitMQ-Emali	
       
         
        
    		contextConfigLocation 
     		 classpath*:spring/*.xml,classpath*:servlet/*.xml 
     	 
     	
     	  
    	
    		org.springframework.web.context.ContextLoaderListener
    	
    	
          
    	
    		encodingFilter
    		org.springframework.web.filter.CharacterEncodingFilter
    		
    			encoding
    			utf-8
    		
    		
    			forceEncoding
    			true
    		
    	
    	
    		encodingFilter
    		/*
    	
    	
    	  
    	
    		springMvc
    		org.springframework.web.servlet.DispatcherServlet
    		
    			contextConfigLocation
    			
    				classpath*:servlet/*.xml
    			
    		
    		1
    	
    	
    		springMvc
    		/
    	
      
    	
    		30
    	
    	
    		login.jsp
    	
    

4.创建用户对象entity->user
简单创建用户对象包含用户名,密码,邮箱属性

package com.sc.entity;
public class User implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	private String username;
	private String pwd;
	private String email;
	
	public User(String username, String pwd, String email) {
		super();
		this.username = username;
		this.pwd = pwd;
		this.email = email;
	}
	public String getUsername() {return username;}
	public String getPwd() {return pwd;}
	public String getEmail() {return email;}
	public void setUsername(String username) {this.username = username;}
	public void setPwd(String pwd) {this.pwd = pwd;}
	public void setEmail(String email) {this.email = email;}
	
	@Override
	public String toString() {
		return "User [username=" + username + ", pwd=" + pwd + ", email=" + email + "]";
	}
}

5.邮件发送服务及其实现(生产者端)

package com.sc.service;
import com.sc.entity.User;
public interface MailSendService {
        	void sendMail(User user);
}

实现类

package com.sc.service.impl;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.mail.MailSender;
   import org.springframework.mail.SimpleMailMessage;
   import org.springframework.stereotype.Service;
   import com.sc.entity.User;
   import com.sc.service.MailSendService;
   
   @Service
   public class MailSendServiceImpl implements MailSendService {
   	
   	@Autowired
   	private MailSender mailSender;
   	/**
   	 * 发送邮件
   	 */
   	@Override
   	public void sendMail(User use) {
   		SimpleMailMessage message = new SimpleMailMessage();
           message.setFrom("[email protected]");
           message.setTo(use.getEmail());
           message.setSubject(use.getUsername());
           //这里暂时已用户名作为发送的内容
           message.setText(use.getUsername());
           mailSender.send(message);
   	}
   }

6.用户登录业务中邮件信息发布
这里可忽略登录业务,这里其实就是代指一个业务入口,简单处理。主要关注产生邮件信息

package com.sc.service;
public interface UserService {
	//登陆
	void login(String username, String pwd, String email);
}

实现类

package com.sc.service.impl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sc.entity.User;
import com.sc.service.UserService;

@Service
public class UserServiceImpl implements UserService{
	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	@Override
	public void login(String username, String pwd, String email) {
		//TODO 执行登陆的业务逻辑,这里主要是介绍消息队列发送邮件,这里就忽略
		User user = new User(username, pwd, email);
		//这里将用户对象作为队列消息发送
		rabbitTemplate.convertAndSend("info", user);
	}
}

7消费者端消费信息,即实现邮件的异步发送

package com.sc.consumer;
import org.apache.commons.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.utils.SerializationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import com.rabbitmq.client.Channel;
import com.sc.entity.User;
import com.sc.service.MailSendService;

/**
 * 消费的消费者 实现 MessageListener或ChannelAwareMessageListener(需手动确认的实现此接口)
 */
public class Consumer implements ChannelAwareMessageListener{
	
	private static final Logger log = LoggerFactory.getLogger(Consumer.class);
	
	@Autowired
	private MailSendService mailSendService;

	@Override
	public void onMessage(Message message, Channel channel) throws Exception {
		try {
			if(StringUtils.isEmpty(new String(message.getBody(),"UTF-8"))) {
				return;
			}
			User user = (User) SerializationUtils.deserialize(message.getBody());
			log.info("消费者消费{}",user);
			//发送邮件
			mailSendService.sendMail(user);
			//手动确认
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

8.编写Controller层的接口测试

package com.sc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.sc.service.UserService;

@Controller
@RequestMapping("/user")
public class UserLoginController {
	@Autowired
	private UserService userService;

	@RequestMapping(value="/login", method=RequestMethod.POST)
	@ResponseBody
	public boolean login(String username,String pwd,String email) {
		//这里简单模拟正常注册,没有数据库交互
		//执行登陆逻辑
		userService.login(username,pwd,email);
		return true;
	}
}

你可能感兴趣的:(消息中间件)