Commit a2916fa4 authored by jianhaijun's avatar jianhaijun

生产者以请求的方式触发,调整了测试文件

parent 2ddbda2b
# API 接口文档
# API 接口文档
## 基础信息
- **基础URL**: `http://localhost:8080`
- **认证方式**: JWT Token (Header: `Authorization: Bearer <token>`)
- **说明**: 标有 🔓 的接口无需认证,标有 🔒 的接口需要登录认证
---
## 一、认证接口
### 1.1 发送验证码 (AuthController)
- **URL**: `POST /api/auth/send-code`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"phoneNumber": "手机号"
}
```
- **响应成功**:
```json
{
"success": true,
"message": "验证码发送成功",
"code": "123456"
}
```
- **响应失败**:
```json
{
"success": false,
"message": "发送过于频繁,请稍后再试"
}
```
---
### 1.2 验证码登录 (AuthController)
- **URL**: `POST /api/auth/login`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"phoneNumber": "手机号",
"code": "验证码"
}
```
- **响应成功**:
```json
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiJ9...",
"phoneNumber": "13800138000",
"message": "登录成功"
}
```
- **响应失败**:
```json
{
"success": false,
"message": "验证码错误或已过期"
}
```
---
## 二、登录接口 (旧版)
### 2.1 发送验证码
- **URL**: `POST /login/sendCode`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"phone": "手机号"
}
```
- **响应**:
```json
{
"code": 200,
"data": "000000",
"message": "success"
}
```
### 2.2 手机号+验证码登录
- **URL**: `POST /login/login`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"phone": "手机号",
"code": "验证码"
}
```
- **响应成功**:
```json
{
"code": 200,
"data": "token字符串",
"message": "success"
}
```
- **响应失败**: `"手机或验证码错误!"``"登录失败!"`
### 2.3 验证Token
- **URL**: `POST /login/getToken`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"phone": "手机号",
"token": "token值"
}
```
- **响应成功**:
```json
{
"code": 200,
"data": "token值",
"message": "success"
}
```
- **响应失败**:
```json
{
"code": 400,
"message": "获取token失败,跳转到登录页面"
}
```
---
## 三、用户接口
### 3.1 测试接口
- **URL**: `GET /users/demo`
- **认证**: 🔓 无需认证
- **参数**:
- `name` (必填): 用户名
- `age` (可选): 年龄
- **示例**: `GET /users/demo?name=张三&age=25`
- **响应**: `"测试通过"`
### 3.2 添加用户
- **URL**: `POST /users/addUser`
- **认证**: 🔓 无需认证
- **请求体**:
```json
{
"name": "用户名",
"age": 25,
"email": "user@example.com"
}
```
- **响应**: `true``false`
### 3.3 查询所有用户
- **URL**: `POST /users/findAllUser`
- **认证**: 🔓 无需认证
- **响应**:
```json
{
"code": 200,
"data": "用户数据...",
"message": "success"
}
```
---
## 四、受保护接口
### 4.1 获取用户信息
- **URL**: `GET /api/protected/user-info`
- **认证**: 🔒 需要JWT Token
- **请求头**: `Authorization: Bearer <token>`
- **响应**:
```json
{
"message": "这是受保护的用户信息接口",
"data": "用户详细信息..."
}
```
### 4.2 获取仪表盘数据
- **URL**: `GET /api/protected/dashboard`
- **认证**: 🔒 需要JWT Token
- **请求头**: `Authorization: Bearer <token>`
- **响应**:
```json
{
"message": "这是受保护的仪表盘接口",
"data": "统计数据..."
}
```
---
## 五、Kafka接口
### 5.1 生产消息到 test-topic
- **URL**: `POST /kafka/producter-topic`
- **认证**: 🔓 无需认证
- **请求体**: 任意字符串(手机号)
- **响应**: `"请求成功:test-topic"`
### 5.2 生产消息到 test-topic1
- **URL**: `POST /kafka/producter-topic1`
- **认证**: 🔓 无需认证
- **请求体**: 任意字符串(手机号)
- **响应**: `"请求成功:test-topic1"`
---
## 六、WebSocket接口
### 6.1 连接方式 (SockJS)
- **URL**: `ws://localhost:8080/ws`
- **认证**: 🔓 无需认证
- **说明**: 使用 SockJS 协议,需引入 STOMP 客户端
### 6.2 连接方式 (Native WebSocket)
- **URL**: `ws://localhost:8080/ws-native`
- **认证**: 🔓 无需认证
- **说明**: 原生 WebSocket 连接
### 6.3 STOMP 订阅主题
- **订阅地址**: `/topic/test-topic`
- **订阅地址**: `/topic/test-topic1`
**订阅示例 (STOMP)**:
```
CONNECT
accept-version:1.2
host:localhost
^@
SUBSCRIBE
id:sub-0
destination:/topic/test-topic
^@
```
**接收消息格式**:
```json
"Hello, Kafka!"
```
---
## 七、测试页面
### Kafka 测试页面
- **URL**: `http://localhost:8080/kafka-test.html`
- **说明**: 提供 WebSocket 连接和消息订阅的图形化测试界面
---
## 接口安全配置
| 接口路径 | 认证要求 |
|---------|---------|
| `/api/auth/**` | 🔓 无需认证 |
| `/api/public/**` | 🔓 无需认证 |
| `/login/**` | 🔓 无需认证 |
| `/users/**` | 🔓 无需认证 |
| `/ws/**` | 🔓 无需认证 |
| `/ws-native/**` | 🔓 无需认证 |
| `/topic/**` | 🔓 无需认证 |
| `/queue/**` | 🔓 无需认证 |
| `/kafka/**` | 🔓 无需认证 |
| `/kafka-test.html` | 🔓 无需认证 |
| `/api/protected/**` | 🔒 需要JWT认证 |
| 其他接口 | 🔒 需要JWT认证 |
\ No newline at end of file
......@@ -57,6 +57,7 @@ public class SecurityConfig {
.requestMatchers("/queue/**").permitAll()
.requestMatchers("/kafka-test.html").permitAll()
.requestMatchers("/kafka/producter-topic").permitAll()
.requestMatchers("/kafka/producter-topic1").permitAll()
// .requestMatchers("/**").permitAll()
// .requestMatchers("/login/**").permitAll()
......
......@@ -21,7 +21,7 @@ public class kafkaController {
* 触发生产消息,给kafka发送消息
*/
@PostMapping("/producter-topic")
public void productertopic(@RequestBody String phone) {
public Object productertopic(@RequestBody String phone) {
// 配置生产者属性
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
......@@ -53,5 +53,41 @@ public class kafkaController {
// 分支1
// 分支2
}
return "请求成功:"+TOPIC_NAME ;
}
/**
* 触发生产消息,给kafka发送消息
*/
@PostMapping("/producter-topic1")
public Object productertopicfor(@RequestBody String phone) {
// 配置Kafka生产者属性
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.RETRIES_CONFIG, 4);
// 创建生产者实例
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// 发送消息到主题
String topic = "test-topic1";
for (int i = 0; i < 10; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key" + i, "value" + i);
producer.send(record, (metadata, exception) -> {
if (exception != null) {
exception.printStackTrace();
} else {
System.out.println("Sent message to topic " + metadata.topic() +
", partition " + metadata.partition() +
", offset " + metadata.offset());
}
});
}
// 关闭生产者
producer.close();
return "请求成功:"+topic ;
}
}
\ No newline at end of file
package com.example.demo.kafka;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
public class KafkaProducerExample {
public static void main(String[] args) {
// 配置Kafka生产者属性
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
// 创建生产者实例
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// 发送消息到主题
String topic = "test-topic1";
for (int i = 0; i < 10; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key" + i, "value" + i);
producer.send(record, (metadata, exception) -> {
if (exception != null) {
exception.printStackTrace();
} else {
System.out.println("Sent message to topic " + metadata.topic() +
", partition " + metadata.partition() +
", offset " + metadata.offset());
}
});
}
// 关闭生产者
producer.close();
}
}
......@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
public class KafkaWebSocketListener {
private static final String TOPIC_NAME = "test-topic";
private static final String TOPIC_NAMEA = "test-topic1";
@Autowired
private SimpMessagingTemplate messagingTemplate;
......@@ -18,6 +18,11 @@ public class KafkaWebSocketListener {
System.out.println("Received from Kafka: " + message);
messagingTemplate.convertAndSend("/topic/" + TOPIC_NAME, message);
}
@KafkaListener(topics = "test-topic1", groupId = "websocket-group")
public void listen1(String message) {
System.out.println("Received from Kafka: " + message);
messagingTemplate.convertAndSend("/topic/" + TOPIC_NAMEA, message);
}
}
\ No newline at end of file
package com.example.demo.kafka;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
@Component
public class KafkaWebSocketListener1 {
private static final String TOPIC_NAME = "test-topic1";
@Autowired
private SimpMessagingTemplate messagingTemplate;
@KafkaListener(topics = TOPIC_NAME, groupId = "websocket-group")
public void listen(String message) {
System.out.println("Received from Kafka: " + message);
messagingTemplate.convertAndSend("/topic/" + TOPIC_NAME, message);
}
}
\ No newline at end of file
//package com.example.demo.kafka;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.kafka.annotation.KafkaListener;
//import org.springframework.messaging.simp.SimpMessagingTemplate;
//import org.springframework.stereotype.Component;
//
//@Component
//public class KafkaWebSocketListener1 {
//
// private static final String TOPIC_NAME = "test-topic1";
//
// @Autowired
// private SimpMessagingTemplate messagingTemplate;
//
// @KafkaListener(topics = TOPIC_NAME, groupId = "websocket-group")
// public void listen(String message) {
// System.out.println("Received from Kafka: " + message);
// messagingTemplate.convertAndSend("/topic/" + TOPIC_NAME, message);
// }
//}
\ No newline at end of file
package com.example.my_test;
import com.example.demo.controller.AuthController;
import com.example.demo.entityMapper.Users;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
......@@ -12,5 +14,6 @@ public class TestDriver {
public static void main(String[] args) {
System.out.println(userMapper.findAll());
}
}
......@@ -69,7 +69,7 @@
// 使用原生 WebSocket
log('创建 WebSocket 连接...');
ws = new WebSocket('ws://localhost:8080/ws-other');
ws = new WebSocket('ws://localhost:8080/ws-native');
ws.onopen = function() {
log('WebSocket 打开');
......@@ -89,11 +89,11 @@
document.getElementById('status').className = 'connected';
// 订阅主题
var subFrame = 'SUBSCRIBE\nid:sub-1\ndestination:/topic/test-topic1\n\n\x00';
var subFrame = 'SUBSCRIBE\nid:sub-1\ndestination:/topic/test-topic\n\n\x00';
ws.send(subFrame);
log('发送 SUBSCRIBE 帧');
addMessage('系统', '已订阅 /topic/test-topic1');
addMessage('系统', '已订阅 /topic/test-topic');
} else if (frame.command === 'MESSAGE') {
log('收到消息: ' + frame.body);
addMessage('Kafka', frame.body);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment