Spring Integration - 自动轮询发送手机短信
Spring Integration 系统集成
Spring Integration 系统集成Spring Ingegration 提供了基于Spring的EIP(Enterprise Integration Patterns,企业集成模式)的实现。
Spring Integration 主要解决的问题是不同系统之间交互的问题,通过异步消息驱动来达到系统交互时系统之间的松耦合。
Spring Integration 主要有Message、Channel、Message EndPoint组成。
MessageMessage是用来在不同部分之间传递的数据。
Message有两部分组成:消息体(payload)与消息头(header)。
消息体可以是任何数据类型;消息头表示的元数据就是解释消息体的内容。
/*** A generic message representation with headers and body.** @author Mark Fisher* @author Arjen Poutsma* @since 4.0* @seeorg.springframework.messaging.support.MessageBuilder */public interface Message {/*** Return the message payload.*/T getPayload();/*** Return message headers for the message (never {@code null} but may be empty).*/MessageHeaders getHeaders();}123456789101112131415161718192021Channel在消息系统中,消息发送者发送消息到通道(Channel),消息接受者从通道(Channel)接收消息。
1、顶级接口(1) MessageChannelMessageChannel 是Spring Integration消息通道的顶级接口:public interface MessageChannel {/*** Constant for sending a message without a prescribed timeout.*/long INDEFINITE_TIMEOUT = -1;/*** Send a {@link Message} to this channel. If the message is sent successfully,* the method returns {@code true}. If the message cannot be sent due to a* non-fatal reason, the method returns {@code false}. The method may also* throw a RuntimeException in case ofnon-recoverable errors.* This method may block indefinitely, depending on the implementation.* To provide a maximum wait time, use {@link#send(Message, long)}.* @param message the message to send* @return whether or not the message was sent*/boolean send(Message message);/*** Send a message, blocking until either the message is accepted or the* specified timeout period elapses.* @param message the message to send* @param timeout the timeout in milliseconds or {@link #INDEFINITE_TIMEOUT}* @return {@code true} if the message is sent,{@code false} if not* including a timeout of an interrupt of the send*/boolean send(Message message, long timeout);}1234567891011121314151617181920212223242526272 8293031MessageChannel 有两大子接口,分别是PollableChannel(可轮询)和SubscribableChannel(可订阅)。
springboot整合mqtt实现消息发送和消费,以及客户端断线重连之后的消息恢复
springboot整合mqtt实现消息发送和消费,以及客户端断线重连之后的消息恢复参考资料:MQTT简介MQTT是⼀种基于发布/订阅模式的轻量级通讯协议,该协议构建在TCP/IP协议上。
MQTT最⼤的有点在于可以以极少的代码和有限的带宽,为远程设备提供实时可靠的消息服务。
做为⼀种低开销、低带宽占⽤的即时通讯协议,MQTT在物联⽹、⼩型设备、移动应⽤等⽅⾯有⼴泛应⽤。
特点开放消息协议,简单易实现发布订阅模式,⼀对多消息发布基于TCP/IP⽹络连接,提供有序,⽆损,双向连接2字节固定报头,2字节⼼跳报⽂,最⼩化传输开销和协议交换,有效减少⽹络流量消息QoS⽀持,可靠传输保证应⽤物联⽹M2M通信,物联⽹⼤数据采集Android消息推送,WEB消息推送智能硬件、智能家具、智能电器车联⽹通信,电动车站桩采集智慧城市、远程医疗、远程教育电⼒、⽯油与能源等⾏业市场MQTT控制报⽂的结构MQTT通过交换⼀些预定义的MQTT控制报⽂来⼯作,每条MQTT命令消息的消息头都包含⼀个固定的报头,有些消息会携带⼀个可变报⽂头和⼀个负荷。
消息格式如下:|固定包头,存在于所有MQTT控制包|可变包头,存在于某些MQTT控制包|载荷,存在于某些MQTT控制包固定报⽂头(Fixed Header)MQTT固定报⽂头最少有两个字节,第⼀个字节包含消息类型(Message Type)和QoS级别等标志位。
第⼆个字节开始是剩余长度字段,该长度是后⾯的可变报⽂头加消息负载的总长度,该字段最多允许四个字节。
剩余长度使⽤了⼀种可变长度的结构来编码,这种结构使⽤单⼀字节表⽰0-127的值。
⼤于127的值如下处理。
每个字节的低7位⽤来编码数据,最⾼位⽤来表⽰是否还有后续字节。
因此每个字节可以编码128个值,再加上⼀个标识位。
剩余长度最多可以⽤四个字节来表⽰。
例如⼗进制的数字64可以被编码成⼀个单独的字节,⼗进制为64,⼋进制为0x40。
⼗进制数字321(=65+2×128)被编码为两个字节,低位在前。
Springintegration基本概念【转】
Springintegration基本概念【转】1.spring integration 's architecture主要提供两个功能:在系统内提供实现轻量级、事件驱动交互⾏为的框架在系统间提供⼀种基于适配器的平台,以⽀持灵活的系统间交互2.spring integration对于企业集成模式的⽀持2.1Message:⼀个信息的单元,通常有消息头(header)和消息内容(payload)组成2.2Message channel:消息处理节点之间的连接,负责将Message从⽣产者传输到消费者。
根据消费者的多少,可分为point to point和publish-subscribe两种根据消息传输⽅式的不同,分为同步和异步两种2.3Message Endpoint:消息处理节点,消息从节点进⼊通道,也是从节点离开通道⼏个常见的Message EndPoint:CHANNEL ADAPTER,⽤于连接该适配器的特点是单向消息流的,要么是消息通过该适配器进⼊通道,要么是消息通过该适配器离开通道MESSAGING GATEWAY,处理的消息流和Channel Adapter不同,不是单向的,即有进⼊该节点的消息,也会从该节点发出消息。
SERVICE ACTIVATOR,该节点调⽤服务来处理输⼊的消息,并将服务返回的数据发送到输出通道。
在spring integration中,调⽤的⽅法被限定为本地⽅法调⽤。
ROUTER,路由器,将输⼊的消息路由到某个输出通道中SPLITTER,将输⼊的消息拆分成⼦消息AGGREGATOR,将输⼊的多个消息合并为⼀个消息3.观看书中例⼦hello-world思考测试gateway时,下⾯代码向通道names内放⼊消息world?然后service-activator从names通道中获得消息world,调⽤⽅法sayHello返回值到给gateway?解释:gateway有⼀个service-interface的属性,这个属性指向⼀个interface。
springBoot整合websocket实现服务端向客户端推送消息
springBoot整合websocket实现服务端向客户端推送消息Spring Boot提供了简单易用的WebSocket模块,用于实现服务端向客户端推送消息的功能。
在本文中,我们将介绍如何使用Spring Boot来整合WebSocket,并实现服务端向客户端推送消息的功能。
在项目的pom.xml文件中,添加以下依赖:```<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>```接下来,我们需要创建一个WebSocket配置类,用于配置WebSocket 相关的信息。
在该类中,我们需要实现WebSocketConfigurer接口,并重写其中的registerWebSocketHandlers方法,来配置WebSocket的处理器和拦截器。
```javapublic class WebSocketConfig implements WebSocketConfigurer private WebSocketHandler webSocketHandler;private WebSocketInterceptor webSocketInterceptor;public voidregisterWebSocketHandlers(WebSocketHandlerRegistry registry) registry.addHandler(webSocketHandler, "/ws").addInterceptors(webSocketInterceptor).setAllowedOrigins("*");}```然后,我们需要创建一个WebSocketHandler类,用于处理WebSocket的连接和消息。
Spring企业集成流SpringIntegration
Spring企业集成流SpringIntegrationspring集成(Spring Integration)在本章中,将看到如何使⽤ Spring Integration 的通⽤集成模式。
Spring Integration 是由 Gregor Hohpe 和 Bobby Woolf 在*《企业级集成模式》*⼀书中编⽬的许多集成模式的实现。
每个模式都被实现为⼀个组件,消息通过该组件传输管道中的数据Why??那么,我们为什么⽤它呢?spring-integration的官⽹上,给出了以下说法spring-integration的⽬标提供⼀个简单的模型来实现复杂的企业集成解决⽅案为基于spring的应⽤添加异步的、消息驱动的⾏为让更多的Spring⽤户来使⽤他看这种解释,我的直观感觉是:啥玩意?不懂啊!接着看到spring-integration的原则组件之间应该是松散的,模块性的易测的应⽤框架应该强迫分离业务逻辑和集成逻辑扩展节点应该有更好的抽象和可以再使⽤的能⼒感觉,这个应该说的是解耦吧。
另外看了下其他⼈的理解,如果你的系统处在各个系统的中间,需要JMS交互,⼜需要Database/Redis/MongoDB,还需要监听Tcp/UDP等,还有固定的⽂件转移,分析。
还⾯对着时不时的更改需求的风险。
那么,它再适合不过了。
导⼊依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-file</artifactId></dependency>第⼀项依赖是Spring Integration的spring Boot start。
spring_integration[详解]
spring_integration迈入Spring 2.*之后,很多东西都有了改进。
Spring Integration 作为一个Spring的孵化项目,我也是今年年初的时候才听到的。
(下个关注点应该就是Spring的工作流了)。
Integration 可以通过xml 和annotation来进行相应的配置。
它的功能有点像EJB中的消息驱动bean,不过这里换成了消息驱动Spring的bean了。
开始我们的旅程之前先废话两句,说说目标和原则。
Integration 的目标是(比较官方的说法):1.提供一个简单的模型,实现企业系统的集成的解决方案2.使用方便的,基于Spring应用的消息驱动行为3.使得更多的Spring用户来使用它原则是:1.组件之间应该是松散的,模块性的和易测的2.应用框架应该强迫分离业务逻辑和集成逻辑3.扩展节点应该有更好的抽象和可以再使用的能力废话不多说了,直接切入正题:Spring Integration的主要组件包括以下部分,这里务必了解这些概念,以便后续更好的理解整个集成的体系1.Message就是消息包括header(头)和payload(负载)message的header一般是id,时间戳或者目的地址什么的,比如如果你发的消息是个文件,那么header应该存放文件的名称,如果是邮件那么,header应该放目的邮件地址,from,cc等内容。
至于payload负载,放什么都行,随你2.Message channel至于channel就好像一个管子,生产者生产一个消息到channel,消费者从channel消费一个消息,所以channel可以对消息组件解耦,并且提供一个方便的拦截功能和监控功能。
这里channel分两种,一种是point-to-point点对点的,一种是publish-subscribe发布订阅形式的,这个和JMS是一样的。
(所有消息都是这样的)。
如果是点对点的channel,至少会有一个消费者consumer能收到发送的message,另一种订阅发布的channel,spring integration试图去用广播的形式发布message给那些订阅者subscriber,这些都被spring支持。
SpringIntegration框架面试题
SpringIntegration框架面试题Spring Integration框架面试题Spring Integration是一个基于Spring框架的扩展,用于实现企业应用程序的消息通信和集成。
它提供了一系列的组件和模式,用于处理和路由消息、执行异步任务、实现消息转换和适配等。
在面试过程中,以下是一些常见的Spring Integration框架面试题,希望对您有所帮助。
1. 什么是Spring Integration框架?它的主要特点是什么?Spring Integration是一个基于Spring框架的集成框架,用于简化企业级应用程序的集成和消息通信。
其主要特点包括:- 提供了丰富的组件和模式,如通道、适配器、过滤器、路由器等,用于处理和转换消息。
- 支持多种消息协议和传输机制,如JMS、AMQP、HTTP、FTP等。
- 支持异步处理和线程池管理,提高系统性能和响应能力。
- 集成了Spring的依赖注入和AOP等特性,便于与其他Spring框架无缝集成。
2. 请简要介绍一下Spring Integration的消息通道(Channel)和消息端点(Endpoint)。
- 消息通道:消息通道用于连接消息发送者和消息接收者,是消息传递的媒介。
Spring Integration提供了多种类型的消息通道,如直接通道(DirectChannel)、发布-订阅通道(PublishSubscribeChannel)和队列通道(QueueChannel)等。
消息通道是实现消息传递的基础。
- 消息端点:消息端点是消息通道的终点,用于处理和接收消息。
端点可以是消息消费者,也可以是消息处理器。
消息消费者从消息通道接收消息,并将其传递给后续的处理组件;消息处理器则负责处理消息,可以是转换、过滤、路由等操作。
3. Spring Integration中的适配器(Adapter)和过滤器(Filter)有什么作用?- 适配器:适配器用于将外部系统或协议的消息转换为Spring Integration的消息格式,以便进行后续的处理。
messagebuilder.withpayload的用法
messagebuilder.withpayload的用法`messageBuilder.withPayload`是Spring Integration 中用于构建消息的方法。
它将一个对象作为消息的有效载荷(payload)添加到消息中。
以下是`messageBuilder.withPayload` 的基本用法:1. 导入必要的包:```javaimport org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message;```2. 使用`messageBuilder.withPayload` 创建消息:```javaObject payload = ...; // 构建消息的有效载荷对象Message<Object> message = MessageBuilder.withPayload(payload).build();```3. 使用消息进行进一步的处理:创建消息后,您可以将其传递给Spring Integration 中的其他组件进行处理,例如消息通道、消息处理器等。
示例:```java@Servicepublic class MyService {public void processMessage(Object payload) {// 创建消息Message<Object> message = MessageBuilder.withPayload(payload).build();// 将消息发送到消息通道myChannel.send(message);}}```在上述示例中,`processMessage` 方法将有效载荷对象作为参数,并使用`messageBuilder.withPayload` 创建一个带有有效载荷的消息。
unicastreceivingchanneladapter原理 -回复
unicastreceivingchanneladapter原理-回复unicastReceivingChannelAdapter是Spring Integration框架中的一个组件,用于接收单播消息并将其发送到消息通道。
本文将一步一步详细介绍unicastReceivingChannelAdapter的原理及其在Spring Integration 中的应用。
一、unicastReceivingChannelAdapter概述unicastReceivingChannelAdapter主要用于从外部系统接收单播消息,并将其传递到消息通道中。
它可以与不同类型的传输协议一起使用,如TCP、UDP和HTTP。
unicastReceivingChannelAdapter可以接收单个消息,也可以批量接收多个消息。
unicastReceivingChannelAdapter常用的配置选项包括绑定到特定的端口、设置接收超时时间、指定消息的编码方式等。
通过这些选项的配置,我们可以实现对外部系统的数据接收和处理。
二、unicastReceivingChannelAdapter的原理unicastReceivingChannelAdapter的工作原理可以简单概括为以下几个步骤:1. 创建接收通道(receivingChannel)和处理通道(processingChannel);2. 通过特定的传输协议监听指定端口,等待外部系统发送单播消息;3. 当接收到消息时,unicastReceivingChannelAdapter会将消息转换为Spring Integration的内部消息表示形式,并发送到receivingChannel;4. Spring Integration框架将从receivingChannel接收到的消息传递给后续的处理器进行处理;5. 处理器根据配置的条件对消息进行过滤、转换或者其他操作;6. 最终处理结果将被发送到processingChannel,供其他组件使用。
integrationflow的使用
integrationflow的使用IntegrationFlow是Spring Integration框架中的一个关键概念,用于实现不同组件之间的消息传递和集成。
它提供了一种简单而强大的方式来定义和管理消息的流动。
在IntegrationFlow中,可以定义各种组件,包括消息源(Message Source)、消息处理器(Message Handler)、转换器(Transformer)等。
通过将这些组件连接起来,可以构建一个完整的消息处理流程。
我们需要定义一个消息源,它可以是一个消息队列、一个数据库表或者一个HTTP API。
消息源负责从外部系统中获取消息,并将其转换为标准的消息格式。
接下来,我们可以定义一个或多个消息处理器,它们负责对消息进行处理和转换。
消息处理器可以执行各种任务,例如验证消息、转换消息格式、将消息发送到其他系统等。
除了消息源和消息处理器,IntegrationFlow还支持使用转换器来对消息进行转换。
转换器可以将消息从一种格式转换为另一种格式,以满足不同系统之间的数据格式要求。
在IntegrationFlow中,消息是通过通道(Channel)进行传递的。
通道可以是同步的也可以是异步的,可以是基于内存的也可以是基于消息队列的。
通过定义不同类型的通道,可以灵活地控制消息的传递方式和效率。
IntegrationFlow还支持使用路由器(Router)来决定消息的流向。
路由器根据消息的内容、标签或其他属性将消息发送到不同的处理器中。
IntegrationFlow还支持使用过滤器(Filter)来过滤消息。
过滤器可以根据消息的内容、属性或其他标准来决定是否将消息传递给下一个处理器。
总结一下,IntegrationFlow提供了一种简单而强大的方式来定义和管理消息的流动。
通过将不同的组件连接起来,可以构建一个完整的消息处理流程。
在这个过程中,可以使用消息源、消息处理器、转换器、通道、路由器和过滤器等不同的组件来实现各种功能。
基于Spring Integration框架的多点FTP传输系统的设计与实现
气象数据传输中根据业务流程的不同,需要对数据进行 入库、上传、共享、备份等工作,传统的方案是在报文接收 系统上安装 FTP 客户端上传数据,并利用文件同步软件进行 共享。这些软件往往功能单一,配置不灵活,难以满足本地 化的业务要求。同时,随着数据接收系统的不断增加,使得 网络环境变得复杂,增加了维护工作量。 本文基于 Spring Integration 框架提供的 FTP Adapter 设 计了一个多目录采集多点分发系统,定时对单雨量站、两要 素站等独立系统实时接收的数据进行侦测,将侦测到的数据 文件封装成消息,并根据不同的业务流程对消息进行分发, 最后在消息处理终端对消息的负载进行基于 FTP 协议的传 输。实现了对不同系统数据的集中管理,配置灵活,弥补了 传统数据处理过程缺乏灵活性、难于维护的不足。
[1]
。 Spring
Integration 支持不同应用场景,包括 FTP 、 HTTP 、 JDBC 、 Web Service 、 MongoDB 等。 将 各 种 需 要 处 理 的 数 据 实 体 封装在消息中,并根据具体逻辑的需要提供一系列如消息 通 道( channel )、 消 息 适 配 器( Adapter )、 消 息 转 换 器 ( Transformer )等各种组件对消息进行传输和处理。使得 开发者只需要关注具体业务逻辑的实现,所以,业务组件能 更好地与基础设施隔离,从而降低开发者所要面对的复杂的
1 Spring Integration 简介
Spring Integration 是 Spring 的 一 个 子 项 目, 它 扩 展 了 Spring 的 编 程 模 型 到 消 息 领 域。 在 Spring 已 存 在 的 企 业 集 成 支 持 的 基 础 上, 提 供 了 更 高 级 别 的 抽 象
前端开发技术中的消息通知实现
前端开发技术中的消息通知实现随着科技的发展和互联网的普及,人们对实时消息的需求越来越高。
前端开发技术中的消息通知实现成为了一个热门话题。
消息通知是一种将消息推送到用户前端页面的方式,让用户能够及时了解到重要信息。
本文将介绍几种常见的消息通知实现方式。
一、Web SocketWeb Socket 是一种在单个 TCP 连接上进行全双工通信的协议,可以在客户端和服务器之间传送消息。
它允许服务器主动推送消息给客户端,以实现实时通信的效果。
Web Socket 技术的实现需要前后端的配合。
后端需要运行支持 Web Socket协议的服务器,如 Node.js。
前端需要使用 WebSocket 对象来与服务器建立连接,并通过 onmessage 来接收服务器推送的消息。
Web Socket 技术的优点是实时性好,能够做到毫秒级的推送,适用于在线客服、游戏聊天等需要实时交互的场景。
二、Server-Sent EventsServer-Sent Events (SSE) 是一种基于 HTTP 的单向实时通信技术,通过在客户端与服务器之间建立持久连接,服务器可以主动发送消息给客户端。
与 Web Socket 不同的是,SSE 是单向的,只能由服务器向客户端推送消息。
使用 SSE 技术,前端需要在客户端页面上创建一个 EventSource 对象,并通过 onmessage 事件来处理服务器推送的消息。
SSE 技术具有易于实现、低延迟的特点,适合于需要实时更新数据的监控系统、新闻资讯等场景。
三、长轮询(Long Polling)长轮询是一种模拟真实时间的技术,通过客户端向服务器发送请求,服务器在有新消息时才返回响应,否则会一直等待一段时间后再返回。
客户端在收到服务器的响应后再重新发送请求。
长轮询的过程使得客户端与服务器保持了长时间的连接,实现了实时性的效果。
与 SSE 不同的是,长轮询是双向的,客户端能够与服务器进行交互。
SpringBoot使用榛子云实现手机短信发送验证码
SpringBoot使⽤榛⼦云实现⼿机短信发送验证码有账号的话就直接登录,没有注册⼀个即可,很简单的注册登录成功后就是这个样⼦,官⽅提供免费发送⼀条,但是我反复测试⼀些功能效果显然1条是不够的,我冲了20,为了开发我冲了凭这20元,我要20个赞不过分吧QAQ, 充值最低的话是20元,⽀持微信⽀付宝⽀付,⼀条短信也就3分钱左右,可以给朋友装b⽤什么的,接下来进⼊正题在"应⽤管理"——>"我的应⽤"⾥,AppId,AppSecret,这都是⽤户的唯⼀标识,很重要,⼀会在Java代码中要⽤到在"短信管理"——>"短信模板"中可以看到⾃⼰要发送的短信模板,会有⾃⼰默认的模板,当然也可以⾃⼰新建⾃定义模板,不要违规就好,这边需要注意的是审核状态,审核通过后可以发送短信,我遇到好⼏次出错都是因为我新建的模板还没审核通过就发送,所以⼀直失败,这也是我后⾯想到的做到这⾥,以及可以实现简单的借助第三⽅发送短信啦,但是逼格肯定不够,进别⼈的⽹址操作肯定不是我们的最终⽬标,我们接下来把它搬到⾃⼰的项⽬代码中进⾏实现,这边我以SpringBoot为例话不多说直接上代码1.pom添加依赖<!--转换json数据--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.58</version></dependency><!--榛⼦云提供短信接⼝平台--><dependency><groupId>com.zhenzikj</groupId><artifactId>zhenzisms</artifactId><version>2.0.2</version></dependency>2.创建controller⽅法写发送⽅法package com.wyh.controller;import com.alibaba.fastjson.JSONObject;import com.zhenzi.sms.ZhenziSmsClient;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpSession;import java.util.HashMap;import java.util.Map;import java.util.Random;/*** @program: SpringBoot_01* @description: 短信发送* @author: wyh* @createDate: 2021-04-27 22:24**/@Controllerpublic class SendCodeController {//短信平台相关参数//这个不⽤改private String apiUrl = "https://sms_";//榛⼦云系统上获取private String appId = "108850";private String appSecret = "NzhmN2JhNGQtNmRmOC00MWIwLTk1OGEtOTEyYzFiYjFlY2Vk";@ResponseBody@RequestMapping("/sendCode")public boolean getCode(String memPhone, HttpSession httpSession){try {JSONObject json = null;//随机⽣成验证码String code = String.valueOf(new Random().nextInt(999999));//将验证码通过榛⼦云接⼝发送⾄⼿机ZhenziSmsClient client = new ZhenziSmsClient(apiUrl, appId, appSecret);Map<String, Object> params = new HashMap<String, Object>();//前台输⼊的⼿机号params.put("number", memPhone);//这个模板id对应的是榛⼦云个⼈中⼼的模板idparams.put("templateId", 5032);String[] templateParams = new String[2];templateParams[0] = code;templateParams[1] = "5分钟";params.put("templateParams", templateParams);String result = client.send(params);System.out.println(result);json = JSONObject.parseObject(result);if (json.getIntValue("code")!=0){//发送短信失败return false;}//将验证码存到session中,同时存⼊创建时间//以json存放,这⾥使⽤的是阿⾥的fastjsonjson = new JSONObject();json.put("memPhone",memPhone);json.put("code",code);json.put("createTime",System.currentTimeMillis());// 将认证码存⼊SESSIONhttpSession.setAttribute("code",json);return true;} catch (Exception e) {e.printStackTrace();return false;}}/**/* @Author wyh* @Description 跳转发送短信页⾯* @Date 21:01 2021/5/7* @Param []* @return ng.String**/@RequestMapping("/goSendCode")public String goSendCode(){return "/sendCode";}}3.新建短信发送jsp页⾯(ui我选⽤的是layui,前⾯⽂章有说关于springboot引⼊layui等相关js)<%@ taglib prefix="c" uri="/jsp/jstl/core" %><%--Created by IntelliJ IDEA.User: wyhDate: 2021/4/20Time: 21:45短信发送--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>短信发送</title><!--引⼊layui的css--><link rel="stylesheet" href="../layui/css/layui.css" rel="external nofollow" ><!--引⼊layui的js--><script type="text/javascript" src="../layui/layui.js"></script><!--引⼊jquery的js --><script type="text/javascript" src="../jquery/jquery.js"></script></head><body><center><div id="model2" ><div class="layui-form-item input-item"><input type="text" placeholder="请输⼊⼿机号" autocomplete="off" id="memPhone" name="memPhone" class="layui-input" style="width: 10%;"></div><div class="layui-form-item input-item"><input type="text" placeholder="请输⼊验证码" autocomplete="off" id="code" name="code" maxlength="6" class="layui-input" style="width: 10%;"><input type="button" class="layui-btn layui-btn-primary" value="获取验证码" id="sendBtn" style="width:10%;border-color:#1e9fff !important;" onclick="sendCode()" ></input> </div></div></center></body><script>function sendCode(){var memPhone = $("#memPhone").val();if(memPhone == '' || memPhone.length != 11){layer.msg("请输⼊正确的⼿机号!");return;}else{$.ajax({type: 'get',url: '/sendCode',data: {memPhone : memPhone,},dataType: 'json',success: function(data) {if(data){timer();}else{layer.msg("获取验证码失败");}},error: function(data) {layer.msg('连接超时!');},});}}var wait = 60;//倒计时function timer() {if(wait == 0){$("#sendBtn").val("获取验证码");$("#sendBtn").removeAttr("disabled");$("#sendBtn").css("border-color","1e9fff").css("background", "#ffffff").css("cursor", "pointer");wait = 60;}else{$("#sendBtn").attr("disabled","true");$("#sendBtn").css("border-color","fbfbfb").css("background", "#ccc").css("cursor", "not-allowed"); $("#sendBtn").val(wait + "秒后重发");wait--;setTimeout(function() {timer()}, 1000);}}</script></html>⼀个简单的页⾯样式如下输⼊正确的⼿机号进⾏测试收到短信如下这样⼀个简单的⾃⼰代码实现短信发送就完成啦,以下为官⽅的⼀些参数类型以及说明到此这篇关于SpringBoot使⽤榛⼦云实现⼿机短信发送验证码的⽂章就介绍到这了,更多相关SpringBoot短信发送验证码内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
spring-boot集成短信验证码服务
spring-boot集成短信验证码服务目前,手机号对于我们的日常生活有着非常重要的作用,特别是手机号码实名认证以后,手机号如同你的身份证一样记录着我们的各种信息。
所以短信验证码作为手机号的验证方式也显得尤为重要。
因此,很多公司或网站用短信验证码来验证我们的身份信息。
常见的使用场景有:登录注册、信息修改、异常登录、找回密码等操作。
今天给大家分享一下如何接入当前应用比较广泛的阿里云短信服务平台和容联云短信平台,其实每个短信平台接入方式都大同小异。
首先我们需要去各家短信平台申请属于我们自己的开发者账号,容联云通讯会有一定数量的免费短信条数用来测试,但是免费短信不可以自定义发送内容的模板,充值一定金额后可以申请。
阿里云是后付费模式,可以使用短信自定义的短信模板或者签名。
申请好了以后我们就要这些需要的信息添加到我们的配置文件中。
pom.xml添加依赖阿里云短信提供了通过maven方式添加依赖,容联云通讯则需要自己手动去下载jar包添加到工程目录中。
<dependency><groupId>com.aliyun.mns</groupId><artifactId>aliyun-sdk-mns</artifactId><version>1.1.8</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-sms</artifactId><version>3.0.0-rc1</version></dependency>•1•2•3•4•5•6•7•8•9•10验证码配置文件smscode.properties:#容联云通讯短信验证码user.smsCode.accountSid = #user.smsCode.accountT oken = #user.smsCode.serverIp = user.smsCode.serverPort = 8883user.smsCode.appId = ##短信验证码失效时间(单位秒)user.smsCode.expires = 60#短信验证码长度user.smsCode.smsCodelen = 6#阿里云AccessIduser.aliyun.smsCode.accessId=##阿里云AccessKeyuser.aliyun.smsCode.accessKey=##访问MNS服务的接入地址user.aliyun.smsCode.mnsEndpoint=##发送短信使用的主题user.aliyun.smsCode.topic=sms.topic-cn-hangzhou #发送短信使用的签名user.aliyun.smsCode.signName=竞技世界#注册模板Codeuser.aliyun.smsCode.regTemplateCode=##登录模板Codeuser.aliyun.smsCode.loginT emplateCode=##忘记密码模板Codeuser.aliyun.smsCode.forgetTemplateCode=# #绑定手机模板Codeuser.aliyun.smsCode.bindTemplateCode=##免注账号升级模板Codeuser.aliyun.smsCode.upgradeTemplateCode=# •1•2•3•4•5•6•7•8•9•10•11•12•13•14•15•16•17•18•19•20•21•22•23•24•25•26•27•28•29•30•31•32阿里云短信配置自动加载**** @ClassName: AliyunSmsCodeProperties* @Description: TODO(阿里云短信配置)* @author huasc* @date 2017年8月29日下午1:44:51**/@Configuration//自动加载配置文件前缀是user.aliyun.smsCode的配置文件@ConfigurationProperties(prefix = "user.aliyun.smsCode") //配置文件的启用条件当ponent的值为aliyunSmcodeService时该配置文件才会被启用@ConditionalOnProperty(name = "ponent",havingValue = "aliyunSmcodeService")//配置文件地址@PropertySource(value = "classpath:smscode.properties", encoding = "UTF-8")public class AliyunSmsCodeProperties {private String accessId;private String accessKey;private String mnsEndpoint;private String topic;private String signName;private String regT emplateCode;private String loginTemplateCode;private String forgetTemplateCode;private String bindTemplateCode;private String upgradeTemplateCode;private CloudT opic tp;public String getAccessId() {return accessId;}public void setAccessId(String accessId) {this.accessId = accessId;}public String getAccessKey() {return accessKey;}public void setAccessKey(String accessKey) { this.accessKey = accessKey;}public String getMnsEndpoint() {return mnsEndpoint;}public void setMnsEndpoint(String mnsEndpoint) { this.mnsEndpoint = mnsEndpoint;}public String getT opic() {return topic;}public void setTopic(String topic) {this.topic = topic;}public String getSignName() {return signName;public void setSignName(String signName) {this.signName = signName;}public String getRegTemplateCode() {return regTemplateCode;}public void setRegTemplateCode(String regTemplateCode) { this.regTemplateCode = regTemplateCode;}public String getLoginTemplateCode() {return loginTemplateCode;}public void setLoginTemplateCode(String loginTemplateCode) {this.loginTemplateCode = loginTemplateCode;}public String getForgetTemplateCode() {return forgetTemplateCode;}public void setForgetTemplateCode(String forgetTemplateCode) {this.forgetTemplateCode = forgetTemplateCode;public String getBindTemplateCode() {return bindTemplateCode;}public void setBindTemplateCode(String bindTemplateCode) {this.bindTemplateCode = bindTemplateCode;}@Bean("mnsClient")MNSClient createClient() {CloudAccount account = new CloudAccount(this.accessId, this.accessKey, this.mnsEndpoint);MNSClient client = account.getMNSClient();this.client = client;return client;}@BeanCloudTopic cloudT opic(MNSClient mnsClient) {CloudTopic tp = mnsClient.getTopicRef(this.topic);this.tp = tp;return tp;}private MNSClient client;@PreDestroypublic void destroy() {client.close();}public String getUpgradeTemplateCode() {return upgradeTemplateCode;}public void setUpgradeTemplateCode(String upgradeTemplateCode) {this.upgradeTemplateCode = upgradeTemplateCode;}}•1•2•3•4•5•6•7•8•9•10•11•12•13•14 •15 •16 •17 •18 •19 •20 •21 •22 •23 •24 •25 •26 •27 •28 •29 •30 •31 •32 •33 •34 •35 •36 •37 •38 •39 •40 •41 •42 •43•45 •46 •47 •48 •49 •50 •51 •52 •53 •54 •55 •56 •57 •58 •59 •60 •61 •62 •63 •64 •65 •66 •67 •68 •69 •70 •71 •72 •73•75 •76 •77 •78 •79 •80 •81 •82 •83 •84 •85 •86 •87 •88 •89 •90 •91 •92 •93 •94 •95 •96 •97 •98 •99 •100 •101 •102 •103•105 •106 •107 •108 •109 •110 •111 •112 •113 •114 •115 •116 •117 •118 •119 •120 •121 •122 •123 •124 •125 •126 •127 •128 •129 •130 •131 •132 •133•135•136•137•138•139•140•141•142•143•144•145•146容联云短信配置自动加载类:@ConfigurationProperties(prefix = "user.smsCode")@ConditionalOnProperty(name = "ponent",havingValue = "ronglianService") @PropertySource(value = "classpath:smscode.properties", encoding = "UTF-8")@Configurationpublic class RonglianSmsCodeProperties {private String accountSid;private String accountT oken;private String appId;private String serverIp;private String serverPort;public String getAccountSid() {return accountSid;}public void setAccountSid(String accountSid) { this.accountSid = accountSid;}public String getAccountT oken() {return accountT oken;}public void setAccountToken(String accountT oken) { this.accountToken = accountT oken;}public String getAppId() {return appId;}public void setAppId(String appId) {this.appId = appId;}public String getServerIp() {return serverIp;public void setServerIp(String serverIp) {this.serverIp = serverIp;}public String getServerPort() {return serverPort;}public void setServerPort(String serverPort) {this.serverPort = serverPort;}@Beanpublic CCPRestSmsSDK createPhoneClient() { CCPRestSmsSDK phoneClient = new CCPRestSmsSDK(); phoneClient.setAccount(accountSid, accountToken); phoneClient.init(serverIp, serverPort); phoneClient.setAppId(appId);return phoneClient;}•1•2•3•4•5•6•7•9 •10 •11 •12 •13 •14 •15 •16 •17 •18 •19 •20 •21 •22 •23 •24 •25 •26 •27 •28 •29 •30 •31 •32 •33 •34 •35 •36 •37•39 •40 •41 •42 •43 •44 •45 •46 •47 •48 •49 •50 •51 •52 •53 •54 •55 •56 •57 •58 •59 •60 •61 •62 •63 •64 •65 •66 •67开启服务:指定使用哪个短信服务,只需把响应的注释打开就可以啦。
SpringKafka和SpringBoot整合实现消息发送与消费简单案例
SpringKafka和SpringBoot整合实现消息发送与消费简单案例本⽂主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来⾃Spring Kafka的消息。
先前我已经分享了Kafka的基本介绍与集群环境搭建⽅法。
关于Kafka的介绍请阅读,关于Kafka安装请阅读,关于Kafka集群环境搭建请阅读。
这⾥关于服务器环境搭建不在赘述。
Spring Kafka整合Spring Boot创建⽣产者客户端案例创建⼀个kafka-producer-master的maven⼯程。
整个项⽬结构如下:Maven的依赖<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.gzh.kafka.producer</groupId><artifactId>producer</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>kafka-producer-master</name><description>demo project for kafka producer</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-kafka.version>2.1.5.RELEASE</spring-kafka.version><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- https:///artifact/org.springframework.kafka/spring-kafka --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>${spring-kafka.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https:///artifact/org.springframework.kafka/spring-kafka-test --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka-test</artifactId><version>${spring-kafka.version}</version><scope>test</scope></dependency><!-- https:///artifact/io.springfox/springfox-swagger2 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.8.0</version></dependency><!-- https:///artifact/io.springfox/springfox-swagger-ui --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.8.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>使⽤application.properties配置应⽤程序当然,根据个⼈喜好,你也可以使⽤application.yml属性⽂件重写配置。
springboot如何集成mqtt消息推送
springboot如何集成mqtt消息推送1.需求分析近期笔者项⽬需要⽤到mqtt实现消息推送,笔者选择emq作为mqtt服务器载体,上篇笔者讲解了如何在linux中安装mqtt服务,安装链接:https:///zhangxing52077/article/details/80567270,接下来笔者将讲解如何在springboot中集成mqtt2.实现⽅案①pom依赖<!--mqtt--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-stream</artifactId></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId></dependency>②yml中配置mqtt(⾃定义配置)#mq配置com:mqtt:host: tcp://ip:1883clientid: mqttjs_e8022a4d0btopic: good,test,yesusername: zhangxingpassword: zxp52077timeout: 10keepalive: 20③创建mqtt消息属性配置类@Component@ConfigurationProperties(prefix = "com.mqtt")@Setter@Getterpublic class MqttConfiguration {private String host;private String clientid;private String topic;private String username;private String password;private int timeout;private int keepalive;}④创建mqtt消息推送实体@Slf4j@Setter@Getterpublic class PushPayload {//推送类型private String type;//推送对象private String mobile;//标题private String title;//内容private String content;//数量private Integer badge = 1;//铃声private String sound = "default";public PushPayload(String type, String mobile, String title, String content, Integer badge , String sound){this.type = type;this.mobile = mobile;this.title = title;this.content = content;this.badge = badge;this.sound = sound;}public static class Builder{//推送类型private String type;//推送对象private String mobile;//标题private String title;//内容private String content;//数量private Integer badge = 1;//铃声private String sound = "default";public Builder setType(String type) {this.type = type;return this;}public Builder setMobile(String mobile) {this.mobile = mobile;return this;}public Builder setTitle(String title) {this.title = title;return this;}public Builder setContent(String content) {this.content = content;return this;}public Builder setBadge(Integer badge) {this.badge = badge;return this;}public Builder setSound(String sound) {this.sound = sound;return this;}public PushPayload bulid(){return new PushPayload(type,mobile,title,content,badge,sound);}}public static Builder getPushPayloadBuider(){return new Builder();}@Overridepublic String toString() {return JSON.toJSONString(this, SerializerFeature.DisableCircularReferenceDetect);}}⑤创建mqtt消息推送或订阅客户端@Slf4jpublic class MqttPushClient {private MqttClient client;private static volatile MqttPushClient mqttPushClient = null;public static MqttPushClient getInstance(){if(null == mqttPushClient){synchronized (MqttPushClient.class){if(null == mqttPushClient){mqttPushClient = new MqttPushClient();}}}return mqttPushClient;}private MqttPushClient() {connect();}private void connect(){try {client = new MqttClient(PropertiesUtil.MQTT_HOST, PropertiesUtil.MQTT_CLIENTID, new MemoryPersistence());MqttConnectOptions options = new MqttConnectOptions();options.setCleanSession(false);options.setUserName(PropertiesUtil.MQTT_USER_NAME);options.setPassword(PropertiesUtil.MQTT_PASSWORD.toCharArray());options.setConnectionTimeout(PropertiesUtil.MQTT_TIMEOUT);options.setKeepAliveInterval(PropertiesUtil.MQTT_KEEP_ALIVE);try {client.setCallback(new PushCallback());client.connect(options);} catch (Exception e) {e.printStackTrace();}} catch (Exception e) {e.printStackTrace();}}/*** 发布,默认qos为0,⾮持久化* @param topic* @param pushMessage*/public void publish(String topic,PushPayload pushMessage){publish(0, false, topic, pushMessage);}/*** 发布* @param qos* @param retained* @param topic* @param pushMessage*/public void publish(int qos,boolean retained,String topic,PushPayload pushMessage){ MqttMessage message = new MqttMessage();message.setQos(qos);message.setRetained(retained);message.setPayload(pushMessage.toString().getBytes());MqttTopic mTopic = client.getTopic(topic);if(null == mTopic){log.error("topic not exist");}MqttDeliveryToken token;try {token = mTopic.publish(message);token.waitForCompletion();} catch (MqttPersistenceException e) {e.printStackTrace();} catch (MqttException e) {e.printStackTrace();}}/*** 订阅某个主题,qos默认为0* @param topic*/public void subscribe(String topic){subscribe(topic,0);}/*** 订阅某个主题* @param topic* @param qos*/public void subscribe(String topic,int qos){try {client.subscribe(topic, qos);} catch (MqttException e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {String kdTopic = "good";PushPayload pushMessage =PushPayload.getPushPayloadBuider().setMobile("153********").setContent("designModel").bulid();MqttPushClient.getInstance().publish(0, false, kdTopic, pushMessage);}}⑥配置获取类的编写public class PropertiesUtil {public static String MQTT_HOST;public static String MQTT_CLIENTID;public static String MQTT_USER_NAME;public static String MQTT_PASSWORD;public static int MQTT_TIMEOUT;public static int MQTT_KEEP_ALIVE;public static final String ELASTIC_SEARCH_HOST;public static final int ELASTIC_SEARCH_PORT;public static final String ELASTIC_SEARCH_CLUSTER_NAME;static {MQTT_HOST = loadMqttProperties().getProperty("MQTT_HOST");MQTT_CLIENTID = loadMqttProperties().getProperty("MQTT_CLIENTID");MQTT_USER_NAME = loadMqttProperties().getProperty("MQTT_USER_NAME");MQTT_PASSWORD = loadMqttProperties().getProperty("MQTT_PASSWORD");MQTT_TIMEOUT = Integer.valueOf(loadMqttProperties().getProperty("MQTT_TIMEOUT")); MQTT_KEEP_ALIVE =Integer.valueOf(loadMqttProperties().getProperty("MQTT_KEEP_ALIVE"));}static {ELASTIC_SEARCH_HOST = loadEsProperties().getProperty("ES_HOST");ELASTIC_SEARCH_PORT =Integer.valueOf(loadEsProperties().getProperty("ES_PORT"));ELASTIC_SEARCH_CLUSTER_NAME =loadEsProperties().getProperty("ES_CLUSTER_NAME");}private static Properties loadMqttProperties() {InputStream inputstream = PropertiesUtil.class.getResourceAsStream("/mqtt.yml");Properties properties = new Properties();try {properties.load(inputstream);return properties;} catch (IOException e) {throw new RuntimeException(e);} finally {try {if (inputstream != null) {inputstream.close();}} catch (IOException e) {throw new RuntimeException(e);}}}private static Properties loadEsProperties() {InputStream inputstream =PropertiesUtil.class.getResourceAsStream("/elasticsearch.properties");Properties properties = new Properties();try {properties.load(inputstream);return properties;} catch (IOException e) {throw new RuntimeException(e);} finally {try {if (inputstream != null) {inputstream.close();}} catch (IOException e) {throw new RuntimeException(e);}}}}⑦mqtt推送回调类/*** @auther zx* @date 2018/5/28 9:20*/public class PushCallback implements MqttCallback {public void connectionLost(Throwable cause) {// 连接丢失后,⼀般在这⾥⾯进⾏重连System.out.println("连接断开,可以做重连");}public void deliveryComplete(IMqttDeliveryToken token) {System.out.println("deliveryComplete---------" + token.isComplete());}public void messageArrived(String topic, MqttMessage message) throws Exception { // subscribe后得到的消息会执⾏到这⾥⾯System.out.println("接收消息主题 : " + topic);System.out.println("接收消息Qos : " + message.getQos());System.out.println("接收消息内容 : " + new String(message.getPayload()));}}3.效果测试@Testpublic void test() {PushPayload pushPayload = PushPayload.getPushPayloadBuider().setContent("test") .setMobile("119").setType("2018").bulid();mqttClientComponent.push("yes",pushPayload);}mqtt客户端效果显⽰。
SpringBoot整合阿里云短信服务的方法
SpringBoot整合阿⾥云短信服务的⽅法⽬录⼀、新建短信微服务1、在service模块下创建⼦模块service-msm3.配置application.properties4、创建启动类⼆、阿⾥云短信服务三、编写发送短信接⼝1.在service-msm的pom中引⼊依赖2.编写controller,根据⼿机号发送短信3.编写service⼀、新建短信微服务1、在service模块下创建⼦模块service-msm2.创建controller和service代码3.配置application.properties# 服务端⼝server.port=8006# 服务名=service-msm# mysql数据库连接spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8ername=rootspring.datasource.password=rootspring.redis.host=192.168.44.131spring.redis.port=6379spring.redis.database= 0spring.redis.timeout=1800000spring.redis.lettuce.pool.max-active=20spring.redis.lettuce.pool.max-wait=-1#最⼤阻塞等待时间(负数表⽰没限制)spring.redis.lettuce.pool.max-idle=5spring.redis.lettuce.pool.min-idle=0#最⼩空闲#返回json的全局时间格式spring.jackson.date-format=yyyy-MM-dd HH:mm:ssspring.jackson.time-zone=GMT+8#配置mapper xml⽂件的路径mybatis-plus.mapper-locations=classpath:com/atguigu/cmsservice/mapper/xml/*.xml#mybatis⽇志mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl4、创建启动类@ComponentScan({"com.south"})@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源⾃动配置public class ServiceMsmApplication {public static void main(String[] args) {SpringApplication.run(ServiceMsmApplication.class, args);}}⼆、阿⾥云短信服务帮助⽂档:三、编写发送短信接⼝1.在service-msm的pom中引⼊依赖<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId></dependency></dependencies>2.编写controller,根据⼿机号发送短信@CrossOrigin //跨域public class MsmApiController {@Autowiredprivate MsmService msmService;@Autowiredprivate RedisTemplate<String, String> redisTemplate;@GetMapping(value = "/send/{phone}")public R code(@PathVariable String phone) {String code = redisTemplate.opsForValue().get(phone);if(!StringUtils.isEmpty(code)) return R.ok();code = RandomUtil.getFourBitRandom();Map<String,Object> param = new HashMap<>();param.put("code", code);boolean isSend = msmService.send(phone, "SMS_180051135", param);if(isSend) {redisTemplate.opsForValue().set(phone, code,5,TimeUnit.MINUTES);return R.ok();} else {return R.error().message("发送短信失败");}}}3.编写service@Servicepublic class MsmServiceImpl implements MsmService {/*** 发送短信*/public boolean send(String PhoneNumbers, String templateCode, Map<String,Object> param) {if(StringUtils.isEmpty(PhoneNumbers)) return false;DefaultProfile profile =DefaultProfile.getProfile("default", "LTAIq6nIPY09VROj", "FQ7UcixT9wEqMv9F35nORPqKr8XkTF"); IAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();//request.setProtocol(ProtocolType.HTTPS);request.setMethod(MethodType.POST);request.setDomain("");request.setVersion("2017-05-25");request.setAction("SendSms");request.putQueryParameter("PhoneNumbers", PhoneNumbers);request.putQueryParameter("SignName", "我的⾕粒在线教育⽹站");request.putQueryParameter("TemplateCode", templateCode);request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));try {CommonResponse response = client.getCommonResponse(request);System.out.println(response.getData());return response.getHttpResponse().isSuccess();} catch (ServerException e) {e.printStackTrace();} catch (ClientException e) {e.printStackTrace();}return false;}}到此这篇关于SpringBoot整合阿⾥云短信服务的⽂章就介绍到这了,更多相关SpringBoot阿⾥云短信服务内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
springboot整合spring-kafka实现发送接收消息实例代码
springboot整合spring-kafka实现发送接收消息实例代码前⾔由于我们的新项⽬使⽤的是spring-boot,⽽⼜要同步新项⽬中建的数据到⽼的系统当中.原来已经有⼀部分的同步代码,使⽤的是kafka. 其实只是做数据的同步,我觉得选MQ没必要使⽤kafka.⾸先数据量不⼤,其实搞kafka⼜要搞集群,ZK.只是⽤做⼀些简单数据同步的话,有点⼤材⼩⽤.没办法,咱只是个打⼯的,领导让搞就搞吧.刚开始的时候发现有⼀个spring-integration-kafka,描述中说是基于spring-kafka做了⼀次重写.但是我看了官⽅⽂档.实在是搞的有点头⼤.功能⼀直没实现.⽂档写的也不是很漂亮,也可能是刚起步,有很多的问题.我这⾥只能放弃了,使⽤了spring-kafka.实现⽅法pom.xml⽂件如下<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.linuxsogood.sync</groupId><artifactId>linuxsogood-sync</artifactId><version>1.0.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.0.RELEASE</version></parent><properties><java.version>1.8</java.version><!-- 依赖版本 --><mybatis.version>3.3.1</mybatis.version><mybatis.spring.version>1.2.4</mybatis.spring.version><mapper.version>3.3.6</mapper.version><pagehelper.version>4.1.1</pagehelper.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId><scope>compile</scope></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-kafka</artifactId><version>2.0.1.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-core</artifactId><version>4.3.1.RELEASE</version><scope>compile</scope></dependency>--><dependency><groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId><version>1.1.0.RELEASE</version></dependency><!--<dependency><groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka-test</artifactId><version>1.1.0.RELEASE</version></dependency>--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest-all</artifactId><version>1.3</version><scope>test</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-all</artifactId><version>1.9.5</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>4.2.3.RELEASE</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.11</version></dependency><!--Mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis.spring.version}</version></dependency><!--<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version></dependency>--><!-- Mybatis Generator --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.2</version><scope>compile</scope><optional>true</optional></dependency><!--分页插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>${pagehelper.version}</version></dependency><!--通⽤Mapper--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>${mapper.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.17</version></dependency></dependencies><repositories><repository><id>estone</id><name>Spring Framework Maven Milestone Repository</name><url>https://repo.spring.io/libs-milestone</url></repository></repositories><build><finalName>mybatis_generator</finalName><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.2</version><configuration><verbose>true</verbose><overwrite>true</overwrite></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>org.linuxsogood.sync.Starter</mainClass></configuration></plugin></plugins></build></project>orm层使⽤了MyBatis,⼜使⽤了通⽤Mapper和分页插件.kafka消费端配置import org.linuxsogood.sync.listener.Listener;import org.apache.kafka.clients.consumer.ConsumerConfig;import mon.serialization.StringDeserializer;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.kafka.annotation.EnableKafka;import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.config.KafkaListenerContainerFactory;import org.springframework.kafka.core.ConsumerFactory;import org.springframework.kafka.core.DefaultKafkaConsumerFactory;import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; import java.util.HashMap;import java.util.Map;@Configuration@EnableKafkapublic class KafkaConsumerConfig {@Value("${kafka.broker.address}")private String brokerAddress;@BeanKafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() { ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory());factory.setConcurrency(3);factory.getContainerProperties().setPollTimeout(3000);return factory;}@Beanpublic ConsumerFactory<String, String> consumerFactory() {return new DefaultKafkaConsumerFactory<>(consumerConfigs());}@Beanpublic Map<String, Object> consumerConfigs() {Map<String, Object> propsMap = new HashMap<>();propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, this.brokerAddress);propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100");propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000");propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, "firehome-group");propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");return propsMap;}@Beanpublic Listener listener() {return new Listener();}}⽣产者的配置.import org.apache.kafka.clients.producer.ProducerConfig;import mon.serialization.StringSerializer;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.kafka.annotation.EnableKafka;import org.springframework.kafka.core.DefaultKafkaProducerFactory;import org.springframework.kafka.core.KafkaTemplate;import org.springframework.kafka.core.ProducerFactory;import java.util.HashMap;import java.util.Map;@Configuration@EnableKafkapublic class KafkaProducerConfig {@Value("${kafka.broker.address}")private String brokerAddress;@Beanpublic ProducerFactory<String, String> producerFactory() {return new DefaultKafkaProducerFactory<>(producerConfigs());}@Beanpublic Map<String, Object> producerConfigs() {Map<String, Object> props = new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.brokerAddress);props.put(ProducerConfig.RETRIES_CONFIG, 0);props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);props.put(ProducerConfig.LINGER_MS_CONFIG, 1);props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432);props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);return props;}@Beanpublic KafkaTemplate<String, String> kafkaTemplate() {return new KafkaTemplate<String, String>(producerFactory());}}监听,监听⾥⾯,写的就是业务逻辑了,从kafka⾥⾯得到数据后,具体怎么去处理. 如果需要开启kafka处理消息的⼴播模式,多个监听要监听不同的group,即⽅法上的注解@KafkaListener⾥的group⼀定要不⼀样.如果多个监听⾥的group写的⼀样,就会造成只有⼀个监听能处理其中的消息,另外监听就不能处理消息了.也即是kafka的分布式消息处理⽅式.在同⼀个group⾥的监听,共同处理接收到的消息,会根据⼀定的算法来处理.如果不在⼀个组,但是监听的是同⼀个topic的话,就会形成⼴播模式import com.alibaba.fastjson.JSON;import org.linuxsogood.qilian.enums.CupMessageType;import org.linuxsogood.qilian.kafka.MessageWrapper;import org.linuxsogood.qilian.model.store.Store;import org.linuxsogood.sync.mapper.StoreMapper;import org.linuxsogood.sync.model.StoreExample;import ng3.StringUtils;import org.apache.kafka.clients.consumer.ConsumerRecord;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.kafka.annotation.KafkaListener;import java.util.List;import java.util.Optional;public class Listener {private static final Logger LOGGER = LoggerFactory.getLogger(Listener.class);@Autowiredprivate StoreMapper storeMapper;/*** 监听kafka消息,如果有消息则消费,同步数据到新烽⽕的库* @param record 消息实体bean*/@KafkaListener(topics = "linuxsogood-topic", group = "sync-group")public void listen(ConsumerRecord<?, ?> record) {Optional<?> kafkaMessage = Optional.ofNullable(record.value());if (kafkaMessage.isPresent()) {Object message = kafkaMessage.get();try {MessageWrapper messageWrapper = JSON.parseObject(message.toString(), MessageWrapper.class);CupMessageType type = messageWrapper.getType();//判断消息的数据类型,不同的数据⼊不同的表if (CupMessageType.STORE == type) {proceedStore(messageWrapper);}} catch (Exception e) {LOGGER.error("将接收到的消息保存到数据库时异常, 消息:{}, 异常:{}",message.toString(),e);}}}/*** 消息是店铺类型,店铺消息处理⼊库* @param messageWrapper 从kafka中得到的消息*/private void proceedStore(MessageWrapper messageWrapper) {Object data = messageWrapper.getData();Store cupStore = JSON.parseObject(data.toString(), Store.class);StoreExample storeExample = new StoreExample();String storeName = StringUtils.isBlank(cupStore.getStoreOldName()) ? cupStore.getStoreName() : cupStore.getStoreOldName();storeExample.createCriteria().andStoreNameEqualTo(storeName);List<org.linuxsogood.sync.model.Store> stores = storeMapper.selectByExample(storeExample);org.linuxsogood.sync.model.Store convertStore = new org.linuxsogood.sync.model.Store();org.linuxsogood.sync.model.Store store = convertStore.convert(cupStore);//如果查询不到记录则新增if (stores.size() == 0) {storeMapper.insert(store);} else {store.setStoreId(stores.get(0).getStoreId());storeMapper.updateByPrimaryKey(store);}}}总结以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作能带来⼀定的帮助,如果有疑问⼤家可以留⾔交流,谢谢⼤家对的⽀持。
应用文之Spring框架技术在短信群发平台中的应用
Spring框架技术在短信群发平台中的应用摘要目前基于j2ee的平台开发越来越多被广大开发者所利用,而spring框架为j2ee平台提供了解决包括对象的生命周期、对象之间的依赖关系建立、对象的缓存实现等方面问题的管理技术,因此已有许多基于web应用采用了spring框架。
本文主要介绍了spring框架技术在短信群发平台中的应用。
关键词 spring 技术应用1 spring框架技术介绍spring是一个多层的j2ee系统的框架。
spring作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能。
传统的j2ee开发的程序,应用实现难度大,代码比较多,编译的难度普遍受时间、编译代码的量决定,往往由于部分代码而导致从新编译,编译的质量也不高。
程序开发者兴趣也不浓,j2ee的发展受到了极大的制约。
而基于j2ee系统的spring 框架的推出,提供了更加简单、快速的实现方案,大大减少了代码的编辑量和编译时间,完善了继承性,把大量应用到的方便代码进行封装,与其它代码分离,建立被调用的实例不再由调用者建立,而是由建立,使系统运行占用少量的系统资源,提高效率[1]。
spring 框架是一个分层架构[2],也称容器,基本由七个模块组成。
spring容器用以构造所需要的model。
在此基础之上,提供了aop(aspect-oriented programming,面向层面的编程)的实现,用它来提供非管理环境下申明方式的事务、安全等服务;采用dao (data access object)的方法方便我们进行数据库的开发;利用web mvc(model-view-control)和spring web方便了java web应用的各种框架或与其他web框架进行集成,统一协调工作,七个模块都可以单独存在也可联合使用,可使用到任何j2ee的服务中。
如图 1 所示。
2 在短信群发平台中发送数据入库的应用3 在短信群发平台中号码簿批量导入的应用(2)上传号码簿:系统管理—〉号码簿管理;点击“选择号码簿”选择准备好的号码簿文件,点击按钮上传号码簿文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Spring Integration 配置<?xml version="1.0" encoding="UTF-8"?><beans xmlns=" /schema/beans"xmlns:xsi=" /2001/XMLSchema-instance"xmlns:int=/schema/integration"xmlns:int-jpa=" /schema/integration/jpa"xmlns:int-jms=" /schema/integration/jms"xmlns:context=" /schema/context"xsi:schemaLocation=" /schema/beans/schema/beans/spring-beans.xsd/schema/integration/schema/integration/spring-integration-2.2.xsd:///schema/integration/jms/schema/integration/jms/spring-integration-jms.xsd:///schema/context/schema/context/spring-context.xsd:///schema/integration/schema/integration/spring-integration.xsd:///schema/integration/jpa/schema/integration/jpa/spring-integration-jpa-2.2.xsd"><int-jpa:inbound-channel-adapterauto-startup="true" entity-manager="em"send-timeout="60000" channel="process.channel"expect-single-result="true"jpa-query="SELECT sysdate FROM dual"><int:poller fixed-delay="60000"/></int-jpa:inbound-channel-adapter><int:channel id="process.channel"><int:queue capacity="1"/></int:channel><int:chain input-channel="process.channel"><int-jpa:retrieving-outbound-gateway entity-manager="em" jpa-query="SELECT sp FROM SmsMessage sp Where sp.tatus is null order by sp.requestOn,sp.id"/><int:splitter ref="process.processSplitter" method="split"/><int:service-activator ref="process.smsSenderService"method="send"/><int:poller fixed-delay="5000" receive-timeout="-1"/></int:chain><bean id="process.smsSenderService" class="com.yd.core.service.SmsSenderService"/><bean id="process.processSplitter" class="com.yd.core.service.PaymentProcessSplitter"/> </beans>Job Workerimport org.springframework.context.ApplicationContext;import org.springframework.integration.MessageChannel;import org.springframework.integration.support.MessageBuilder;public class JobWorker implements Runnable {private static final int DEFAULT_WAIT_TIME = 3000;@Overridepublic void run() {while (true) {try {LoggerUtil.getJobLogger().info("JobWorker, Ready for take job run request.");JobRunnerRequest jobRequest = JobManagerService.getJobManager().takeRequest();while (jobRequest == null) {LoggerUtil.getJobLogger().warn("JobWorker, jobRequest is null, will try to get the job requet again.");Thread.sleep(DEFAULT_WAIT_TIME);jobRequest = JobManagerService.getJobManager().takeRequest();}LoggerUtil.getJobLogger().info("JobWorker, Received a job run request.");MessageChannel channel = findChannel(jobRequest.getJobChannelId());if (channel != null) {channel.send(MessageBuilder.withPayload(jobRequest.getJobMessagePayload()).build());LoggerUtil.getJobLogger().info("JobWorker, Completed to sned message to job channel");}}catch (Exception ex) {LoggerUtil.getJobLogger().warn("JobWorker, Completed to sned message to job channel");}}}private MessageChannel findChannel(String jobChannelId) {ApplicationContext context = ApplicationContextProvider.getContext();if (context == null) {LoggerUtil.getJobLogger().error(String.format("JobWorker, Cannot get the application context, to startup job %s", jobChannelId));return null;}Object channel = context.getBean(jobChannelId);if (channel instanceof MessageChannel) {return (MessageChannel) channel;}else {LoggerUtil.getJobLogger().error(String.format("JobWorker, Cannot get the message bean, to startup job %s", jobChannelId));return null;}}}JobManagerServiceimport java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;public final class JobManagerService {private BlockingQueue<JobRunnerRequest> jobRequestQueue = newLinkedBlockingQueue<JobRunnerRequest>();private static volatile JobManagerService jobManagerInstnce;private static Object objSyncLocker = new Object();private JobManagerService() {}private void startupWorker() {new Thread(new JobWorker()).start();}public static JobManagerService getJobManager() {if (jobManagerInstnce == null) {synchronized (objSyncLocker) {if (jobManagerInstnce == null) {jobManagerInstnce = new JobManagerService();jobManagerInstnce.startupWorker();}}}return jobManagerInstnce;}public void addRequest(JobRunnerRequest request) {try {jobRequestQueue.put(request);}catch (InterruptedException e) {LoggerUtil.getJobLogger().warn(e.getMessage(), e);}}public JobRunnerRequest takeRequest() {try {return jobRequestQueue.take();}catch (InterruptedException e) {LoggerUtil.getJobLogger().warn(e.getMessage(), e);return null;}}}ApplicatonContextProviderimport org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class ApplicationContextProvider implements ApplicationContextAware { private static volatile ApplicationContext ctx;public static ApplicationContext getContext() {return ctx;}private static synchronized void setContext(ApplicationContext applicationContext) { ctx = applicationContext;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext){setContext(applicationContext);}}。