1.9.1. дополнение к расширению
Чтобы улучшить ваш JsonSaveHandler
, мы можем сделать его более гибким при обработке входящих данных. Вместо того, чтобы жестко полагаться только на наличие полей name
и message
, мы можем анализировать любые другие переданные поля и определять, нужно ли сохранять данные только в PostgreSQL, MongoDB или в обе базы данных. Вот что можно сделать:
1. Анализ содержимого JSON и сохранение в нужную базу
Мы можем реализовать логику проверки содержимого JSON и сохранять объект в MongoDB, если он содержит дополнительные поля, не предусмотренные в PostgreSQL. Если объект содержит только те поля, которые соответствуют структуре PostgreSQL (name
и message
), он будет сохранен только в PostgreSQL.
2. Логика: определение подходящего хранилища
- Если JSON содержит только поля
name
иmessage
, он будет сохранен в PostgreSQL. - Если JSON содержит дополнительные поля, то данные будут сохранены в MongoDB.
- Если JSON содержит
name
,message
и другие поля, то данные могут быть сохранены в обе базы.
Пример улучшенного JsonSaveHandler
:
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.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 {
// Парсинг JSON строки
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
boolean hasName = jsonNode.has("name");
boolean hasMessage = jsonNode.has("message");
boolean hasAdditionalFields = hasOtherFields(jsonNode);
// Логика сохранения
if (hasName && hasMessage && !hasAdditionalFields) {
// Сохраняем только в PostgreSQL
return saveToPostgres(jsonNode);
} else if (hasAdditionalFields && (!hasName || !hasMessage)) {
// Сохраняем только в MongoDB
return saveToMongo(jsonNode);
} else if (hasName && hasMessage && hasAdditionalFields) {
// Сохраняем в обе базы данных
return saveToPostgres(jsonNode)
.then(saveToMongo(jsonNode));
} else {
return Mono.just("Json Save: Error: JSON does not contain valid fields for saving.");
}
} catch (Exception e) {
return Mono.just("Json Save: Invalid JSON format: " + e.getMessage());
}
}
// Метод для проверки на дополнительные поля (помимо name и message)
private boolean hasOtherFields(JsonNode jsonNode) {
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
if (!fieldName.equals("name") && !fieldName.equals("message")) {
return true;
}
}
return false;
}
// Метод для сохранения в PostgreSQL
private Mono<String> saveToPostgres(JsonNode jsonNode) {
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 -> "PostgreSQL Save: Success, ID: " + saved.getId())
.onErrorResume(e -> Mono.just("PostgreSQL Save: Error: " + e.getMessage()));
}
// Метод для сохранения в MongoDB
private Mono<String> saveToMongo(JsonNode jsonNode) {
Map<String, Object> jsonDataMap = new ObjectMapper().convertValue(jsonNode, Map.class);
JsonData jsonData = new JsonData();
jsonData.setData(jsonDataMap);
return jsonDataRepository.save(jsonData)
.map(saved -> "MongoDB Save: Success, MongoDB ID: " + saved.getId())
.onErrorResume(e -> Mono.just("MongoDB Save: Error: " + e.getMessage()));
}
}
Описание изменений:
- Метод
hasOtherFields()
: -
Проверяет, есть ли в JSON другие поля, помимо
name
иmessage
. Если есть — объект сохраняется в MongoDB. -
Метод
saveToPostgres()
: -
Сохраняет объект только в PostgreSQL, если в JSON есть только поля
name
иmessage
. -
Метод
saveToMongo()
: -
Сохраняет весь объект в MongoDB, если есть дополнительные поля.
-
Основная логика сохранения:
- Если в JSON только
name
иmessage
, объект сохраняется только в PostgreSQL. - Если есть другие поля, то объект сохраняется в MongoDB.
- Если в JSON есть и
name
, иmessage
, и дополнительные поля, объект сохраняется в обе базы данных.
Вывод:
Теперь приложение может динамически определять, куда сохранить данные в зависимости от структуры JSON. Такой подход делает приложение более гибким и универсальным для различных сценариев.