日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

整合rabbitmq+redis发送验证码消息

發(fā)布時(shí)間:2024/9/30 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 整合rabbitmq+redis发送验证码消息 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 配置:
  • 驗(yàn)證碼工具類
  • 處理發(fā)送驗(yàn)證碼的消息
  • controller層
  • 驗(yàn)證驗(yàn)證碼是否正確

配置:

server:port: 8084 #郵件相關(guān)配置 spring:application:name: subtlechat-mailservermail:host: smtp.qq.comprotocol: smtpdefault-encoding: UTF-8#郵箱名username: #申請(qǐng)的授權(quán)碼password: port: 587properties.mail.stmp.socketFactory.class: javax.net.ssl.SSLSocketFactoryproperties.mail.debug: true#RabbitMQ的配置rabbitmq:host: localhostport: 5672username: guestpassword: guestvirtual-host: /subtlechat# 如果rabbitmq中沒(méi)有創(chuàng)建這個(gè)名字的虛擬主機(jī)會(huì)報(bào)錯(cuò)#開啟手動(dòng)確認(rèn)是否消息消費(fèi)成功listener:simple:acknowledge-mode: manualprefetch: 100#Redis的配置redis:database: 0password: redishost: port: 6379

rabbitmq配置:

/*** @author Hai* @date 2020/10/1 - 18:32*/ @Configuration public class RabbitMQConfig {@Value("${mail.exchange:mail-exchange}")private String mailExchange;@Value("${mail.queue.verifyCode:mail-queue-verifyCode}")private String mailQueueVerifyCode;@Value("${mail.route.verifyCode:mail-route-verifyCode}")private String mailRouteVerifyCode;@Value("${mail.queue.feedback:mail-queue-feedback}")private String mailQueueFeedback;@Value("${mail.route.feedback:mail-route-feedback}")private String mailRouteFeedback;@BeanDirectExchange mailExchange(){return new DirectExchange(mailExchange,true,false);}/*** 驗(yàn)證碼消息隊(duì)列* @return*/@BeanQueue mailQueueVerifyCode(){return new Queue(mailQueueVerifyCode,true);}@BeanBinding mailQueueVerifyCodeBinding(){return BindingBuilder.bind(mailQueueVerifyCode()).to(mailExchange()).with(mailRouteVerifyCode);}}}

自定義rabbitmqtemplate:

/*** 自定義消息發(fā)送RabbitTemplate* @author Hai* @date 2020/10/2 - 14:35*/ @Configuration public class RabbitMQConfig {public static final Logger LOGGER= LoggerFactory.getLogger(RabbitMQConfig.class);@AutowiredCachingConnectionFactory cachingConnectionFactory;@AutowiredMailSendLogService mailSendLogService;@Beanpublic RabbitTemplate rabbitTemplate(){RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);//成功投遞消息到Broker交換機(jī)站點(diǎn)的回調(diào)函數(shù)rabbitTemplate.setConfirmCallback((data,ack,cause)->{String msgId = data.getId();if(ack){LOGGER.info(msgId+"消息發(fā)送成功");//修改數(shù)據(jù)庫(kù)中的記錄,消息發(fā)送成功,將status設(shè)為1mailSendLogService.updateMailSendLogStatus(msgId, MailConstants.SUCCESS);}else{LOGGER.error(msgId+"消息發(fā)送失敗!");}});//消息投遞到Queue隊(duì)列失敗的回調(diào)函數(shù)rabbitTemplate.setReturnCallback((msg,repCode,repText,exchange,routingKey)->{LOGGER.error(msg.getBody()+"----消息從交換機(jī)投遞到隊(duì)列失敗!\n錯(cuò)誤原因:"+repText);LOGGER.error("發(fā)送錯(cuò)誤的交換機(jī):"+exchange+",發(fā)生錯(cuò)誤的路由key:"+routingKey);});return rabbitTemplate;} }

驗(yàn)證碼工具類

/*** 生成驗(yàn)證碼的工具類*/ public class VerificationCode {private int width = 100;// 生成驗(yàn)證碼圖片的寬度private int height = 30;// 生成驗(yàn)證碼圖片的高度private String[] fontNames = { "宋體", "楷體", "隸書", "微軟雅黑" };private Color bgColor = new Color(255, 255, 255);// 定義驗(yàn)證碼圖片的背景顏色為白色private Random random = new Random();private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";private String text;// 記錄隨機(jī)字符串/*** 獲取一個(gè)隨意顏色** @return*/private Color randomColor() {int red = random.nextInt(150);int green = random.nextInt(150);int blue = random.nextInt(150);return new Color(red, green, blue);}/*** 獲取一個(gè)隨機(jī)字體** @return*/private Font randomFont() {String name = fontNames[random.nextInt(fontNames.length)];int style = random.nextInt(4);int size = random.nextInt(5) + 24;return new Font(name, style, size);}/*** 獲取一個(gè)隨機(jī)字符** @return*/private char randomChar() {return codes.charAt(random.nextInt(codes.length()));}/*** 創(chuàng)建一個(gè)空白的BufferedImage對(duì)象** @return*/private BufferedImage createImage() {BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D) image.getGraphics();g2.setColor(bgColor);// 設(shè)置驗(yàn)證碼圖片的背景顏色g2.fillRect(0, 0, width, height);return image;}public BufferedImage getImage() {BufferedImage image = createImage();Graphics2D g2 = (Graphics2D) image.getGraphics();StringBuffer sb = new StringBuffer();for (int i = 0; i < 4; i++) {String s = randomChar() + "";sb.append(s);g2.setColor(randomColor());g2.setFont(randomFont());float x = i * width * 1.0f / 4;g2.drawString(s, x, height - 8);}this.text = sb.toString();drawLine(image);return image;}/*** 繪制干擾線** @param image*/private void drawLine(BufferedImage image) {Graphics2D g2 = (Graphics2D) image.getGraphics();int num = 5;for (int i = 0; i < num; i++) {int x1 = random.nextInt(width);int y1 = random.nextInt(height);int x2 = random.nextInt(width);int y2 = random.nextInt(height);g2.setColor(randomColor());g2.setStroke(new BasicStroke(1.5f));g2.drawLine(x1, y1, x2, y2);}}public String getText() {return text;}public static void output(BufferedImage image, OutputStream out) throws IOException {ImageIO.write(image, "JPEG", out);} }

處理發(fā)送驗(yàn)證碼的消息

package top.javahai.subtlechat.mail.receiver;import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.impl.AMQImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.AmqpHeaders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Component;import java.io.IOException; import java.util.Date;/*** 處理發(fā)送驗(yàn)證碼的消息,保證消息不會(huì)重復(fù)消費(fèi)* @author Hai* @date 2020/10/2 - 23:25*/ @Component public class VerifyCodeReceiver {@AutowiredJavaMailSender javaMailSender;@AutowiredStringRedisTemplate redisTemplate;private static final Logger LOGGER= LoggerFactory.getLogger(VerifyCodeReceiver.class);@RabbitListener(queues = "${mail.queue.verifyCode:mail-queue-verifyCode}")public void getMessage(Message message, Channel channel) throws IOException {//獲取消息內(nèi)容String code = message.getPayload().toString();//獲取消息頭,消息標(biāo)志tagMessageHeaders headers = message.getHeaders();Long tag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);//獲取消息IDString msgId = (String) headers.get("spring_returned_message_correlation");LOGGER.info("【"+msgId+"】-正在處理的消息");//查看消息是否已消費(fèi)if (redisTemplate.opsForHash().entries("mail_log").containsKey(msgId)){//手動(dòng)確認(rèn)消息已消費(fèi)channel.basicAck(tag,false);LOGGER.info("【"+msgId+"】消息出現(xiàn)重復(fù)消費(fèi)");return;}//否則進(jìn)行消息消費(fèi)try{SimpleMailMessage msg = new SimpleMailMessage();msg.setSubject("-驗(yàn)證碼驗(yàn)證");msg.setText("本次登錄的驗(yàn)證碼:"+code);msg.setFrom("發(fā)送者的郵箱地址");msg.setSentDate(new Date());msg.setTo("接受者的郵箱地址");javaMailSender.send(msg);//消息發(fā)送成功,將id放到redis中,不能這樣put//redisTemplate.opsForHash().entries("mail_log").put(msgId,code);redisTemplate.opsForHash().put("mail_log",msgId,code);//確認(rèn)消息消費(fèi)成功channel.basicAck(tag,false);}catch (Exception e){//不批量處理,將消息重新放回到隊(duì)列中channel.basicNack(tag,false,true);LOGGER.info("【"+msgId+"】消息重新放回到了隊(duì)列中");e.printStackTrace();}} }

controller層

@RestController public class LoginController {/*** 獲取驗(yàn)證碼圖片寫到響應(yīng)的輸出流中,保存驗(yàn)證碼到session* @param response* @param session* @throws IOException*/@GetMapping("/verifyCode")public void getVerifyCode(HttpServletResponse response, HttpSession session) throws IOException {VerificationCode code = new VerificationCode();BufferedImage image = code.getImage();String text = code.getText();session.setAttribute("verify_code",text);VerificationCode.output(image,response.getOutputStream());}@AutowiredVerifyCodeService verifyCodeService;/*** 獲取郵箱驗(yàn)證碼,并保存到本次會(huì)話* @param session*/@GetMapping("/admin/mailVerifyCode")public RespBean getMailVerifyCode(HttpSession session){String code = verifyCodeService.getVerifyCode();//保存驗(yàn)證碼到本次會(huì)話session.setAttribute("mail_verify_code",code);verifyCodeService.sendVerifyCodeMail(code);return RespBean.ok("驗(yàn)證碼已發(fā)送到郵箱,請(qǐng)注意查看!");}}}

其中sendVerifyCodeMail方法:

@Overridepublic void sendVerifyCodeMail(String code) {//添加消息記錄String msgId = UUID.randomUUID().toString();MailSendLog mailSendLog = new MailSendLog();mailSendLog.setMsgId(msgId);mailSendLog.setContent(code);mailSendLog.setContentType(MailConstants.VERIFY_CODE_TYPE);mailSendLog.setCount(1);mailSendLog.setCreateTime(new Date());mailSendLog.setTryTime(new Date(System.currentTimeMillis()+1000*10*MailConstants.MEG_TIMEOUT));mailSendLog.setUpdateTime(new Date());mailSendLog.setExchange(mailExchange);mailSendLog.setRouteKey(mailRouteVerifyCode);mailSendLog.setStatus(MailConstants.DELIVERING);mailSendLogService.insert(mailSendLog);rabbitTemplate.convertAndSend(mailExchange,mailRouteVerifyCode,code,new CorrelationData(msgId));}

驗(yàn)證驗(yàn)證碼是否正確

/*** 攔截登錄請(qǐng)求,驗(yàn)證輸入的驗(yàn)證碼是否正確* @author Hai* @date 2020/5/28 - 17:31*/ @Component public class VerificationCodeFilter extends GenericFilter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//如果是登錄請(qǐng)求則攔截if ("POST".equals(request.getMethod())&&"/doLogin".equals(request.getServletPath())){//TODO 不啟動(dòng)驗(yàn)證碼filterChain.doFilter(request,response);//用戶輸入的驗(yàn)證碼String code = request.getParameter("code");//session中保存的驗(yàn)證碼String verify_code = (String) request.getSession().getAttribute("verify_code");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();//驗(yàn)證session中保存是否存在try {//驗(yàn)證是否相同if (!code.toLowerCase().equals(verify_code.toLowerCase())){//輸出jsonwriter.write(new ObjectMapper().writeValueAsString( RespBean.error("驗(yàn)證碼錯(cuò)誤!")));return;}else {filterChain.doFilter(request,response);}}catch (NullPointerException e){writer.write(new ObjectMapper().writeValueAsString(RespBean.error("請(qǐng)求異常,請(qǐng)重新請(qǐng)求!")));}finally {writer.flush();writer.close();}}else {filterChain.doFilter(request,response);}} }

總結(jié)

以上是生活随笔為你收集整理的整合rabbitmq+redis发送验证码消息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。