SpringBoot通知机制的实现方式
作者:Bupt_Lili 发布时间:2022-06-25 04:01:54
1. 快速创建maven管理的SpringBoot项目
1、访问 http://start.spring.io/
2、 选择构建工具Maven Project、
Spring Boot版本1.3.6以及一些工程基本信息点击“Switch to the full version.”java版本选择1.7;
3、点击Generate Project下载项目压缩包
4、解压后
使用eclipse,Import -> Existing Maven Projects -> Next ->选择解压后的文件夹-> Finsh,OK done!
使用IDEA的话,按如下步骤导入项目: File -> New -> Project fron Existing Sourses -> 选择解压后的直接包含pom.xml文件的demo文件夹,OK -> 选第二项Import project from external model, 选maven,Next -> Next -> 勾选左下角Open Project Structure after import, Next -> Next -> Finish -> 选Yes -> OK -> 大功告成!
(记录自己踩过的坑:一定要选直接包含pom.xml的demo文件夹,一开始选择直接解压后的demo文件夹,结果找不到可以导入的maven项目。 )
5、 运行刚导入的项目
访问localhost:8080/hello, 看到页面显示Hello World。
6、 在这个demo的基础上进行开发
2. 通知机制的流程
1、客户端向server订阅通知
订阅信息包括通知类型(notificationTypes)、过滤条件(filteringCriteria)、订阅者地址(subscriberUri)和 managerId。
请求数据以json格式发送,因此在服务端用@RequestBody Map request 来处理请求中的json数据,创建JSONObject 对象,从而根据参数名获取请求中传入的参数值。
服务端代码如下:
@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"); // 通过JSONObject 对象获取请求中传入的参数值
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... 省略了存数据库的操作
response.setHeader("Location", "http://localhost:8083/notifications/0101"); // 通过response.setHeader()方法设置响应头
PrintWriter out = response.getWriter();
String result = "Success to Subscribe a notification! ";
out.write(result);
}
服务端端口设为8083,默认是8080,可以通过在resources 下的application.properties文件里加一条语句server.port=8083 修改为其他端口号。
Postman的接口测试结果如下:
2、服务端将通知发送给客户端
请求信息包括订阅Id(subscriptionId)、通知类型(NotificationType)、发送者Id(producerId)、消息(message)。首先根据subscriptionId 从数据库查找到该订阅的通知类型、过滤条件和订阅者地址,然后判断该通知是否符合订阅条件,符合则将该通知发送给订阅者。
服务端代码如下:
@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... 查询数据库(省略)
// 模拟数据库查询结果
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;
// 建立连接,将通知发送给订阅者
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));
// 开始连接请求
subscribeConnection.connect();
OutputStream out = subscribeConnection.getOutputStream();
// 写入请求的字符串
out.write((jsonObject.toString()).getBytes()); // 发送json数据
out.flush();
out.close();
}catch (IOException e) {
}
if (subscribeConnection.getResponseCode() == 200) { // 若响应码为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. 运行过程及结果
首先,用Postman 向服务端(8083端口)发送通知:
服务端结果如下:
订阅者(8081端口)结果如下:
附上demo源码地址: https://github.com/bupt-lxl/SpringBoot-Notification
来源:https://blog.csdn.net/Bupt_Lili/article/details/80424894


猜你喜欢
- Springboot导出文件,前端下载文件后端代码可以把请求设置为post,我这里是Get @RequestMapping(value =
- 本文实例讲述了Java文件操作工具类fileUtil。分享给大家供大家参考,具体如下:package com.gcloud.common;i
- 1、相差秒public double DiffSeconds(DateTime startTime,DateTime endTime){ &
- 问题:startTime = DateTime.Now;
- 本文实例讲述了JAVA快速排序实现方法。分享给大家供大家参考,具体如下:package com.ethan.sort.java;import
- java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串。它本质上是使用正则表达式去读取不同的数据类型。J
- 观察者模式:对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(被观察)。 以便一个对象的状态发生变化时,所有
- C#申请一个大数组(Use a large array in C#)在C#里,有时候我需要能够申请一个很大的数组、使用之、然后立即释放其占用
- Flutter中的默认导航分成两种,一种是命名的路由,一种是构建路由。一、命名路由传参应用入口处定义路由表class MyApp exten
- 本文实例讲述了Android实现点击AlertDialog上按钮时不关闭对话框的方法。分享给大家供大家参考。具体如下:开发过程中,有时候会有
- 本文实例讲述了Android实现将一个Activity设置成窗口样式的方法。分享给大家供大家参考,具体如下:1.在res/value文件夹下
- 目录配置创建OkHttpClient同步get请求异步get请求同步post请求异步post请求上传文件表单提交下面是官网给出的OKHTTP
- 本文实例讲述了C#实现简单的Login窗口。分享给大家供大家参考。具体实现方法如下:C# 制作登录窗体,登录成功之后正确的做法是关闭(clo
- 项目场景: 新搭了一个springboot 2.3.7.RELASE的框架,在集成mysql,tkMapper,mybatis的过
- 前言终于来到了Maven的插件开发,其实Maven的插件并没有想象的那么难,刚开始讲Maven基础的时候就演示了一下JDK是如何打包的,Ma
- 1>方法一之前在配置 Maven 的 settings.xml 时,都会设置 mirror 节点,例如:<mirrors>
- Java的集合类是一种特别有用的工具,它可以用于存储数量不等的多个对象,并可以实现常用的数据结构,如栈、队列等。Java集合还可以用于板寸具
- 众所周知,android的底部菜单栏太重要,平时项目一般都是需要用到的,但是网上关于这方面的demo做得太丑了,实在惨不忍睹,所以这里便用R
- 本文实例为大家分享了Unity封装延时调用定时器的具体代码,供大家参考,具体内容如下封装一个延时调用定时器类using System.Col
- 需要用到的知识:注解、AOP、ExpiringMap(带有有效期的映射)我们可以自定义注解,把注解添加到我们的接口上。定义一个切面,执行方法