SpringBoot通知機(jī)制的實(shí)現(xiàn)方式
1. 快速創(chuàng)建maven管理的SpringBoot項(xiàng)目
1、訪問(wèn) http://start.spring.io/
2、 選擇構(gòu)建工具M(jìn)aven Project、
Spring Boot版本1.3.6以及一些工程基本信息點(diǎn)擊“Switch to the full version.”java版本選擇1.7;
3、點(diǎn)擊Generate Project下載項(xiàng)目壓縮包
4、解壓后
使用eclipse,Import -> Existing Maven Projects -> Next ->選擇解壓后的文件夾-> Finsh,OK done!
使用IDEA的話,按如下步驟導(dǎo)入項(xiàng)目: File -> New -> Project fron Existing Sourses -> 選擇解壓后的直接包含pom.xml文件的demo文件夾,OK -> 選第二項(xiàng)Import project from external model, 選maven,Next -> Next -> 勾選左下角Open Project Structure after import, Next -> Next -> Finish -> 選Yes -> OK -> 大功告成!
(記錄自己踩過(guò)的坑:一定要選直接包含pom.xml的demo文件夾,一開(kāi)始選擇直接解壓后的demo文件夾,結(jié)果找不到可以導(dǎo)入的maven項(xiàng)目。 )

5、 運(yùn)行剛導(dǎo)入的項(xiàng)目
訪問(wèn)localhost:8080/hello, 看到頁(yè)面顯示Hello World。
6、 在這個(gè)demo的基礎(chǔ)上進(jìn)行開(kāi)發(fā)
2. 通知機(jī)制的流程
1、客戶端向server訂閱通知
訂閱信息包括通知類(lèi)型(notificationTypes)、過(guò)濾條件(filteringCriteria)、訂閱者地址(subscriberUri)和 managerId。
請(qǐng)求數(shù)據(jù)以json格式發(fā)送,因此在服務(wù)端用@RequestBody Map request 來(lái)處理請(qǐng)求中的json數(shù)據(jù),創(chuàng)建JSONObject 對(duì)象,從而根據(jù)參數(shù)名獲取請(qǐng)求中傳入的參數(shù)值。
服務(wù)端代碼如下:
@RequestMapping("/notifications")
public void subscribeNotification(@RequestBody Map request, HttpServletResponse response)
throws ServletException, IOException, JSONException {
System.out.println("Enter localhost:8083/notifications. " );
JSONObject jsonObject = new JSONObject(request);
String subscriptionId = (String) jsonObject.get("subscriptionId"); // 通過(guò)JSONObject 對(duì)象獲取請(qǐng)求中傳入的參數(shù)值
String notificationType = (String) jsonObject.get("notificationType");
String filteringCriteria = (String) jsonObject.get("filteringCriteria");
String managerId = (String) jsonObject.get("managerId");
System.out.println("subscriptionId=" + subscriptionId + ", notificationType=" + notificationType + ", filteringCriteria=" + filteringCriteria + ", managerId=" + managerId );
// some code... 省略了存數(shù)據(jù)庫(kù)的操作
response.setHeader("Location", "http://localhost:8083/notifications/0101"); // 通過(guò)response.setHeader()方法設(shè)置響應(yīng)頭
PrintWriter out = response.getWriter();
String result = "Success to Subscribe a notification! ";
out.write(result);
}
服務(wù)端端口設(shè)為8083,默認(rèn)是8080,可以通過(guò)在resources 下的application.properties文件里加一條語(yǔ)句server.port=8083 修改為其他端口號(hào)。
Postman的接口測(cè)試結(jié)果如下:

2、服務(wù)端將通知發(fā)送給客戶端
請(qǐng)求信息包括訂閱Id(subscriptionId)、通知類(lèi)型(NotificationType)、發(fā)送者Id(producerId)、消息(message)。首先根據(jù)subscriptionId 從數(shù)據(jù)庫(kù)查找到該訂閱的通知類(lèi)型、過(guò)濾條件和訂閱者地址,然后判斷該通知是否符合訂閱條件,符合則將該通知發(fā)送給訂閱者。
服務(wù)端代碼如下:
@RequestMapping("/sendNotification")
public void sendNotification(@RequestBody Map request, HttpServletResponse response)
throws ServletException, IOException, JSONException {
System.out.println("request:" + request);
JSONObject jsonObject = new JSONObject(request);
System.out.println("jsonObject:" + jsonObject);
String subscriptionId = (String) jsonObject.get("subscriptionId");
String notificationType = (String) jsonObject.get("notificationType");
String producerId = (String) jsonObject.get("producerId");
String alarmType = (String) jsonObject.getJSONObject("message").get("alarmType");
System.out.println("subscriptionId=" + subscriptionId + ", notificationType=" + notificationType + ", producerId=" + producerId + ", alarmType=" + alarmType );
// some code... 查詢數(shù)據(jù)庫(kù)(省略)
// 模擬數(shù)據(jù)庫(kù)查詢結(jié)果
String getNotificationType = "";
String getAlarmType = "";
String getsubscriberUri = "";
if(subscriptionId.equals("http://localhost:8081/notifications/0101")){
getNotificationType = "alarm";
getAlarmType = "01";
getsubscriberUri = "http://localhost:8081/notifications/001";
}
if(subscriptionId.equals("http://localhost:8081/notifications/0102")){
getNotificationType = "alarm";
getAlarmType = "02";
getsubscriberUri = "http://localhost:8082/notifications/001";
}
// 判斷該通知是否符合訂閱條件
String subscribeURL = "";
if(notificationType.equals(getNotificationType) && alarmType.equals(getAlarmType)){
subscribeURL = getsubscriberUri;
} else return;
// 建立連接,將通知發(fā)送給訂閱者
HttpURLConnection subscribeConnection = null;
StringBuffer responseBuffer = new StringBuffer();
try{
URL getsubscribeURL = new URL(subscribeURL);
subscribeConnection = (HttpURLConnection) getsubscribeURL.openConnection(); // 建立連接
subscribeConnection.setDoOutput(true);
subscribeConnection.setDoInput(true);
subscribeConnection.setRequestMethod("POST");
subscribeConnection.setRequestProperty("Accept-Charset", "utf-8");
subscribeConnection.setRequestProperty("Content-Type", "application/json");
subscribeConnection.setRequestProperty("Charset", "UTF-8");
byte[] data = (jsonObject.toString()).getBytes();
subscribeConnection.setRequestProperty("Content-Length", String.valueOf(data.length));
// 開(kāi)始連接請(qǐng)求
subscribeConnection.connect();
OutputStream out = subscribeConnection.getOutputStream();
// 寫(xiě)入請(qǐng)求的字符串
out.write((jsonObject.toString()).getBytes()); // 發(fā)送json數(shù)據(jù)
out.flush();
out.close();
}catch (IOException e) {
}
if (subscribeConnection.getResponseCode() == 200) { // 若響應(yīng)碼為200,則通知訂閱成功
System.out.println("Success to send the notification." );
String readLine;
BufferedReader responseReader = new BufferedReader(new InputStreamReader(
subscribeConnection.getInputStream(), "utf-8"));
while ((readLine = responseReader.readLine()) != null) {
responseBuffer.append(readLine);
}
System.out.println("Http Response:" + responseBuffer);
subscribeConnection.disconnect();
PrintWriter out = response.getWriter();
out.write(responseBuffer.toString());
}else return;
}
訂閱者(8081端口)接收通知,代碼如下:
@RequestMapping("/notifications/001")
public void receiveNotification(@RequestBody Map request, HttpServletResponse response)
throws ServletException, IOException{
System.out.println("Receive a new notification." );
System.out.println("request:" + request);
PrintWriter out = response.getWriter();
String result = "Success to Subscribe a notification! ";
out.write(result);
}
3. 運(yùn)行過(guò)程及結(jié)果
首先,用Postman 向服務(wù)端(8083端口)發(fā)送通知:

服務(wù)端結(jié)果如下:

訂閱者(8081端口)結(jié)果如下:

附上demo源碼地址: https://github.com/bupt-lxl/SpringBoot-Notification
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot默認(rèn)包掃描機(jī)制與默認(rèn)配置文件詳解
- SpringBoot默認(rèn)包掃描機(jī)制及@ComponentScan指定掃描路徑詳解
- SpringBoot整合RabbitMQ實(shí)現(xiàn)消息確認(rèn)機(jī)制
- SpringBoot整合spring-retry實(shí)現(xiàn)接口請(qǐng)求重試機(jī)制及注意事項(xiàng)
- SpringBoot + WebSocket 實(shí)現(xiàn)答題對(duì)戰(zhàn)匹配機(jī)制案例詳解
- SpringBoot全局異常處理機(jī)制和配置攔截器方式
- Springboot核心機(jī)制詳細(xì)介紹
相關(guān)文章
Spring中的后置處理器BeanPostProcessor詳解
這篇文章主要介紹了Spring中的后置處理器BeanPostProcessor詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
如何通過(guò)一個(gè)注解實(shí)現(xiàn)MyBatis字段加解密
用戶隱私很重要,因此很多公司開(kāi)始做數(shù)據(jù)加減密改造,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一個(gè)注解實(shí)現(xiàn)MyBatis字段加解密的相關(guān)資料,需要的朋友可以參考下2022-02-02
SpringSecurity中@PermitAll與@PreAuthorize的實(shí)現(xiàn)
@PermitAll和@PreAuthorize都是處理安全性的強(qiáng)大工具,本文主要介紹了SpringSecurity中@PermitAll與@PreAuthorize的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07
SpringBoot測(cè)試類(lèi)注入Bean失敗的原因及分析
SpringBoot 2.2版本前后測(cè)試類(lèi)有所變化,2.2版本之后使用JUnit 5,導(dǎo)入注解@SpringBootTest和@Test來(lái)自junit.jupiter.api包;而2.2版本之前使用JUnit 4,需要額外導(dǎo)入@RunWith注解來(lái)自junit.runner包,無(wú)論哪個(gè)版本,都需確保測(cè)試類(lèi)和啟動(dòng)類(lèi)的包名一致2024-09-09
MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解
這篇文章主要介紹了MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
IDEA搭建dubbo項(xiàng)目的過(guò)程及存在的問(wèn)題
這篇文章主要介紹了IDEA搭建dubbo項(xiàng)目及存在的問(wèn)題小結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Springboot重寫(xiě)addInterceptors()方法配置攔截器實(shí)例
這篇文章主要介紹了Springboot重寫(xiě)addInterceptors()方法配置攔截器實(shí)例,spring?boot拋棄了復(fù)雜的xml配置,我們可以自定義配置類(lèi)(標(biāo)注@Configuration注解的類(lèi))來(lái)實(shí)現(xiàn)WebMvcConfigurer接口,并重寫(xiě)addInterceptors()方法來(lái)配置攔截器,需要的朋友可以參考下2023-09-09

