Spring - obsługa wielu użytkowników jednocześnie

0

Cześć,
mam aplikacje napisana w Spring Boot + frontend w JS, w uproszczeniu polega na tym że użytkownik przez stronę wgrywa plik PDF, przesyłany jest on do części serwerowej, zapisywany w folderze tymczasowym /temporaryFile/, wydobywane są z niego wszystkie wyrazy, dodawane do Setu i wystawiane na endpoint przez metodę w @RestController. Potem z przeglądarki idzie ajaxem GET na ten endpoint, wyświetla się użytkownikowi zbiór wyrazów, wybiera on część z nich i zostają przesłane z powrotem POSTem na inny endpoint do Springa. Na podstawie otrzymanych wyrazów program przerabia odpowiednio wcześniej wgrany plik i wystawia link do nowego. Po pobraniu pliki tymczasowe są kasowane, a Set jest czyszczony.
Wszystko działa ale chciałbym by z aplikacji mogło korzystać wielu użytkowników na raz. W tej chwili np. jak użytkownik A wgra plik X, to użytkownik B po wejściu na stronę ma również dostęp do endpointu z wyrazami z pliku X.
Jednak nie chcę wprowadzać funkcjonalności rejestracji i logowania na stronie.
Myślałem by wygenerować losowy UUID, zapisać go w sessionStorage, wgrany plik przechowywać w folderze /temporaryFiles/xx/, gdzie xx to wygenerowany UUID, RESTowe endpointy przerobić na takie z @PathVariable("uuid"), a @Scope klas z warstwy logiki biznesowej zmienić na Prototype, tak aby każde wywołanie metody tworzyło nową instancję. Znając UUID część frontendowa wiedziałby pod które endpointy się zwracać. Dodatkowo jakieś zabezpieczenie przez atakiem bruteforce by nikt nie próbował uzyskać dostępu do pliku/zbioru wyrazów innego użytkownika, np maks 50 żądań na godzinę z danego IP i po przekroczeniu blokada na kilka dni.
Jakieś sugestie?

1

Nie czaje tylko użycia @Prototype w tym miejscu :)

0

Wydawało mi się że z adnotacją @Scope("prototype") na klasie z logiką aplikacji można by było trzymać zmienne na poziomie klasy, tak aby za każdym razem gdy wywołana jest metoda z kontrolera tworzyła się nowa osobna instancja klasy, zmienne nie byłyby dzielone między różnymi "użytkownikami"/żądaniami i można by było uzyskać do nich jakoś dostęp.
Ale w sumie nie potrzebne takie kombinowanie bo mogę trzymać zmienne na poziomie metody, stworzyć np. statyczną mapę Map<UUID,Set<Word>> i tam zapisywać oraz trzymać wyliczony przez metodę Set wyrazów dla każdego użytkownika.

0

Jak będziesz trzymać to w pamięci, to po restarcie aplikacji stracisz dane. Dlaczego nie zrzucić tego do jakiegoś Mongo?

0
Albin123 napisał(a):

Ale w sumie nie potrzebne takie kombinowanie bo mogę trzymać zmienne na poziomie metody, stworzyć np. statyczną mapę Map<UUID,Set<Word>> i tam zapisywać oraz trzymać wyliczony przez metodę Set wyrazów dla każdego użytkownika.

Wtedy będziesz musiał synchronizować dostęp do tej mapy, użyj spring security, ten problem został już rozwiązany

0

Po kolei - widzę tutaj cztery endpointy.

  1. Upload PDFa.
  2. Pobieranie wyrazów
  3. Edycja PDFa.
  4. Pobranie i czyszczenie PDFa.

mam aplikacje napisana w Spring Boot + frontend w JS, w uproszczeniu polega na tym że użytkownik przez stronę wgrywa plik PDF, przesyłany jest on do części serwerowej, zapisywany w folderze tymczasowym /temporaryFile/, wydobywane są z niego wszystkie wyrazy, dodawane do Setu i wystawiane na endpoint przez metodę w @RestController. Potem z przeglądarki idzie ajaxem GET na ten endpoint, wyświetla się użytkownikowi zbiór wyrazów, wybiera on część z nich i zostają przesłane z powrotem POSTem na inny endpoint do Springa. Na podstawie otrzymanych wyrazów program przerabia odpowiednio wcześniej wgrany plik i wystawia link do nowego. Po pobraniu pliki tymczasowe są kasowane, a Set jest czyszczony.

Myślałem by wygenerować losowy UUID, zapisać go w sessionStorage, wgrany plik przechowywać w folderze /temporaryFiles/xx/, gdzie xx to wygenerowany UUID, RESTowe endpointy przerobić na takie z @PathVariable("uuid"), a @Scope klas z warstwy logiki biznesowej zmienić na Prototype, tak aby każde wywołanie metody tworzyło nową instancję. Znając UUID część frontendowa wiedziałby pod które endpointy się zwracać.

Nie widzę tutaj żadnej potrzeby żeby tworzyć stanową warstwę biznesową. Zamiast bawić się w stanowość logiki biznesowej lepiej po prostu wydzielić to, co masz zapamiętać do jakiegoś cache'a i tam trzymać te Sety plus pliki lub powiązanie uuid-plik. Jeśli nie chcesz tego zapisywać na dysku to po prostu rozważ jakiś in-memory cache z opcją czyszczenia po kluczu. Ba, w twoim przypadku pewnie zwykła HashMapa powinna wystarczyć - chyba, że naprawdę spodziewasz się wielkich ilości użytkowników.

1 użytkowników online, w tym zalogowanych: 0, gości: 1