JsonSaveHandler.java
package com.example.websocket8_4.handler;
import com.example.websocket8_4.model.UserData;
import com.example.websocket8_4.model.JsonData;
import com.example.websocket8_4.repository.UserDataRepository;
import com.example.websocket8_4.repository.JsonDataRepository;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Controller
public class JsonSaveHandler implements WebSocketHandler {
@Autowired
private UserDataRepository userDataRepository;
@Autowired
private JsonDataRepository jsonDataRepository;
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.receive()
.map(msg -> msg.getPayloadAsText())
.flatMap(this::saveJsonToDatabase)
.flatMap(result -> session.send(Mono.just(session.textMessage(result))))
.then();
}
private Mono<String> saveJsonToDatabase(String jsonString) {
try {
JsonNode jsonNode = new ObjectMapper().readTree(jsonString);
if (jsonNode.has("name") && jsonNode.has("message")) {
// Логика сохранения в PostgreSQL
String name = jsonNode.get("name").asText();
String message = jsonNode.get("message").asText();
UserData userData = new UserData();
userData.setName(name);
userData.setMessage(message);
return userDataRepository.save(userData)
.map(saved -> "Json Save: Success, ID: " + saved.getId())
.onErrorResume(e -> Mono.just("Json Save: Error: " + e.getMessage()));
} else {
// Логика сохранения в MongoDB
JsonData jsonData = new JsonData();
jsonData.setData(new ObjectMapper().convertValue(jsonNode, Map.class));
return jsonDataRepository.save(jsonData)
.map(saved -> "Json Save: Success, MongoDB ID: " + saved.getId())
.onErrorResume(e -> Mono.just("Json Save: Error: " + e.getMessage()));
}
} catch (Exception e) {
return Mono.just("Json Save: Invalid JSON format: " + e.getMessage());
}
}
}
Краткое описание
Анализ расширенного JsonSaveHandler
Общий обзор
Обработчик теперь поддерживает сохранение данных в две разные базы данных: 1. PostgreSQL - для структурированных данных с полями name и message 2. MongoDB - для произвольных JSON данных
Ключевые компоненты
Зависимости
@Autowired
private UserDataRepository userDataRepository;
@Autowired
private JsonDataRepository jsonDataRepository;
- Два репозитория для разных баз данных
Логика обработки
private Mono<String> saveJsonToDatabase(String jsonString) {
try {
JsonNode jsonNode = new ObjectMapper().readTree(jsonString);
if (jsonNode.has("name") && jsonNode.has("message")) {
// PostgreSQL логика
} else {
// MongoDB логика
}
} catch (Exception e) {
return Mono.just("Json Save: Invalid JSON format: " + e.getMessage());
}
}
Процесс принятия решений
Выбор базы данных
- Если JSON содержит поля "name" и "message":
- Данные сохраняются в PostgreSQL
- Используется структурированная модель UserData
- Для всех остальных JSON:
- Данные сохраняются в MongoDB
- Используется гибкая модель JsonData
Обработка данных
PostgreSQL путь
String name = jsonNode.get("name").asText();
String message = jsonNode.get("message").asText();
UserData userData = new UserData();
userData.setName(name);
userData.setMessage(message);
return userDataRepository.save(userData)
MongoDB путь
JsonData jsonData = new JsonData();
jsonData.setData(new ObjectMapper().convertValue(jsonNode, Map.class));
return jsonDataRepository.save(jsonData)
Обработка ошибок
- Проверка формата JSON
- Обработка ошибок сохранения для обеих баз данных
- Возврат понятных сообщений об ошибках
Особенности реализации
- Реактивный подход (использование Mono)
- Гибкость в выборе хранилища данных
- Автоматическая конвертация JSON в Map для MongoDB
Возможные улучшения
- Добавление логирования
- Реализация транзакционности
- Кэширование частых операций
- Метрики производительности
Требования к окружению
- Настроенное подключение к PostgreSQL
- Настроенное подключение к MongoDB
- Соответствующие зависимости в pom.xml
Дополнительные замечания: 1. Требуется увидеть класс JsonData для полного понимания 2. Нужна информация о JsonDataRepository 3. Возможно, потребуется обновление конфигурации для поддержки MongoDB
Изменения по сравнению с предыдущей версией: 1. Добавлена поддержка MongoDB 2. Реализована логика выбора базы данных 3. Расширена обработка ошибок
Готов к получению следующих файлов, особенно интересны: 1. Класс JsonData 2. Интерфейс JsonDataRepository 3. Обновленная конфигурация с настройками MongoDB
[[1.9. расширение функционала на лету]]