Jak zachashowac response by nie zaciągać wszystkiego z każdym requestem?

0

Witam,

Nie mam dostępu do serwera, mam tylko stronę kliencką.
Jak można wysłać np. jeden request by odebrać np. ArrayList z danymi. Chciałbym to pobrać tylko raz (przynajmniej przez jakis okres czasu)

Pożniej będą leciec kolejne requesty, w krótkich odstępach czasu, nie chce pobierac za kazdym razem tej Arraylisty, ani wywoływać klienta wiele razy. Tylko jak to zrobić?

używam springa i jerseya.

0

Wystaw dwie usługi. Jedna wołana na początku, druga potem. Ewentualnie uzależnij odpowiedź od parametru.

0

Niestety, nie mam wpływu na wystawione api i jak wyglada odpowiedz.

1

A ja nie bardzo rozumiem. Pobierasz sobie listę w swojej aplikacji, zapisujesz sobie na boku a potem pobierasz nową kiedy ci potrzebna. Gdzie jest tu jakis problem? o_O

0

a kolejny request skąd ma wiedziec ma wiedziec by sie odwolac do tej już zapisanej listy zamiast pobrac znowu?

0

Wszystko musi się odbyć w locie. Każde kliknięcie usera to kolejny request o dane. Nie mogę tego nigdzie zapisać, w pliku czy w bazie.

0

Ja nadal nie rozumiem. Przecież to chyba ty piszesz tą aplikację? Więc kontrolujesz co sie dzieje jak ktoś w coś klika? Czy ty chcesz zrobić proxy dostępowe dla webserwisu z którego ma nieświadomie korzystać jakaś zupełnie zewnętrzna kliencka aplikacja? To też da sie zrobić. Musiałbyś podmienić w tej aplikacji adres webserwisu na lokalny podstawiony przez ciebie. Ten twój webserwis wystawia taki sam interfejs, ale zapisuje sobie lokalnie te dane i pobiera z prawdziwego webserwisu tylko raz na jakiś czas.

0

Nie wiem, może jest proste rozwiązanie a ja się zapętliłem mysląc o czymś skomplikowanym...

To ma być autocomplete tekstu w w polu search. Czyli każda kolejna literka to leci nowy request. Do tego ściągam dane z resta GET, razem z tym pełno niepotrzebnych danych, gdy potrzebuję tylko nazwy by je wyświetlić w trakcie pisania usera. Mogę wywołać tę listę nazw i nic wiecej, dalej muszę ją obrobić.

Tę listę chcę pobrać raz (tylko w sumie na jak długo?...) i ją filtrować na widok.

W zasadzie to im wiecej szukam to mam wrazenie, ze mniej wiem... nie wiem jak to obsłużyć. Fajnie jakbym miał wpływ na wystawione API, ale zawsze dostaje tylko całość.
Nie wiem jak się do tego zabrać.

0

No ale gdzie jest problem? W ogóle nie forwarduj tych requestów od użytkowników! Po prostu odpal jakiś Scheduler który raz na minutę czy na godzinę czy jak tam chcesz będzie pobierał nowe dane z serwera. Jak je odbierzesz to je sobie obrabiasz odpowiednio a potem cały mechanizm autocomplete robisz sobie lokalnie.
No chyba że po prostu nie umiesz i korzystasz z faktu że serwer odpowiada ci już przerobionymi danymi? W takim razie znów nic trudnego:

  • zrób sobie mapę Map<String, List<String>> gdzie kluczem jest to co wpisal user a wartością jest lista autocomplete z serwera. Kiedy user coś wpisuje to nie wysyłasz od razu requestu do serwera tylko sprawdzasz czy masz listę w mapie, jak masz to zwracasz tą listę. Jak nie masz to pobierasz z serwera i ładujesz do mapy. Co jakiś czas możesz schedulerem czyścić tą mapę żeby pobierać nowe dane i tyle.
0

Głupi, zmęczony i niedoświadczony jestem, więc nie bij prosze za debilne pytania ;) Dziękuję za pomoc i cierpliwość.

  • nie mam pojęcia o frontendzie z którym komunikuję się przez resta, w zasadzie to czy nie możnaby pobrać całej Kolekcji a mechanizm autocomplete zrobić na frontendzie? czy to źle?
  • dla pewności, Scheduler czyli np. ScheduledThreadPoolExecutor czy @Scheduled springowe?
  • "potem cały mechanizm autocomplete robisz sobie lokalnie" - czy tu masz na myśli np. zapis do bazy itp. ? ogolnie to wiele rzeczy chciałbym zrobić inaczej ale mam dość spore ograniczenia
  • Odnośnie tej Mapy... serwer nic mi nie przerabia, zawsze dostaje całość i musze to obrobić. Ale w zasadzie jak te informacje w tej mapie mają być przechowywane? One będą ginąć a to przy restarcie, utracie sesji a to przy innych okazjach? Czy może mam pobrać dane do tej mapy jakoś niezależnie i tam wsadzić? czy jak?
0
  1. Ja nadal nie wiem co ty z tego serwera dostajesz i co z tym robisz. Opcje są dwie. Albo dostajesz np. listę wszystkich loginów a frontend się martwi jak ten autocomplete wyświetlić, albo dostajesz z serwera tylko loginy pasujące do wzorca który wpisał użytkownik. W przypadku pierwszym pobrałbym to raz na jakiś czas a wystawił własny serwis "lokalny" i sprawił że frontend odpytuje ten twój serwis a nie ten zdalny. A wtedy ty po stronie serwera martwisz się kiedy aktualizować dane. W sytuacji drugiej prościej będzie zrobić taką mapę o jakiej pisałem. Wtedy też musisz przepiąć zapytania do resta z frontendu na swój lokalny serwis.
  2. Bez znaczenia, to drugie jest tylko nakładką na to pierwsze.
  3. Ale jaki znów zapis do bazy? o_O Co ty chcesz w bazie zapisywać?
  4. No ja bym te dane pobral niezależnie, nie per sesja czy użytkownik tylko globalnie. Niech ta mapa będzie dostępna z jakiegoś singletonu w wersji tylko do odczytu po prostu. A że sie straci przy restarcie serwera? Ot życie, zresztą i tak te dane będziesz pobierał raz na jakiś czas żeby były aktualne, więc tu problemu nie widzę.
0
  1. Mam jeden jedyny request GET, który zwraca mi całą listę encji/dto z czego mnie w tym przypadku interesują tyko nazwy. (Jakby nie mogli mi wysłać samych nazw...)
  2. Tak, ale chciałem mieć pewność, że na pewno o tym mowa
    3 i 4. heh to w sumie było powiązane, by mieć pewność odnośnie wyobrażenia jak ma to działać

Wydaje się jednak dość mało trywialne dla początkującego , wolałbym się douczyć niż implementować to na pałę :/

Dzięki za wskazówki. A jeszcze będzie trzeba obsłużyć te 'searche" huh

0

A jeszcze jedno pytanko o tę mapę, bo znalazłem coś takiego:

public static final ConcurrentMap<String, List<String>> MAP = new ConcurrentHashMap<String, List<String>>();

Czy przechowywanie w czymś takim powinno załatwić sprawę?

Z góry dzięki.

1

Ja generalnie preferuje używanie singletonowych beanów zarządzanych przez jakis kontener IoC zamiast stosowanie statycznych zmiennych, ale nie wiem jak wygląda u ciebie reszta projektu. Jeśli chodzi o samą mapę to moim zdaniem nie potrzebujesz tu żadnej synchronizacji. Przecież modyfikacje tej mapy (poprzez podmianę na nową) są robione tylko z jednego jedynego miejsca a sama podmiana jest atomowa. Wszyscy pozostali tylko z mapy czytają więc nigdy nie następuje tu próba jednoczesnej modyfikacji. Więc dlaczego potrzebujesz niby żeby to było coś więcej niż najzwyklejsza mapa?

0

zrób sobie mapę Map<String, List<String>> gdzie kluczem jest to co wpisal user a wartością jest lista autocomplete z serwera. Kiedy user coś wpisuje to nie wysyłasz od razu requestu do serwera tylko sprawdzasz czy masz listę w mapie, jak masz to zwracasz tą listę. Jak nie masz to pobierasz z serwera i ładujesz do mapy. Co jakiś czas możesz schedulerem czyścić tą mapę żeby pobierać nowe dane i tyle.

Nie ! niech użyje **Multimap ** 'y z guavuni - niech świat będzie piękniejszy

https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html

Nie czytałem wątku - leniwy jestem - ale jeżeli faktycznie masz to potem czyścić za pomocą jakiegoś schedulera, a bean przechowujący taką parę jest singletonem do którego dostęp mają wszyscy - to użycie concurrenct hash mapy jest OK - bo 1.) masz Thread safe - lepiej mieć niż nie mieć 2.) narzuć na wydajność jest naprawdę niewielki (ta klasa to akurat pie@rzony masterpiece)

btw. zamiast tego schedulera, może lepiej przy jakiejkolwiek modyfikacji, nie wiem, tabel czy danych związanych z tym cachem, invalidować go (czy tam jego kawałek z userem)

0

A no tak, masz rację. Pytam bo kiedyś się naczytałem jak to trzeba synchronizowac Singletona itp...

A co do IoC to np. powyższą mapę, czy jakąkolwiek starczy np. oznaczyć @Singleton z jerseya czy nie tędy droga?

Mam trochę wątpliwości jak wywoływać tego Schedulera, np. z loginem? czy jak to zrobic 'niezaleznie' ?

WIELKIE dzięki i sorry, że męczę.

0
  1. Używasz Springa wiec ja bym klasę z tą mapą oznaczył jako @Named albo @Service a wstrzykiwał przez @Inject albo @Autowire.
  2. Nie bardzo rozumiem. Nic nie masz wywoływać. Masz odpalic taska w schedulerze i tyle. On sie sam będzie potem wywoływał. Znów skoro to Spring to możesz użyć @Scheduled http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html Czyli schedulujesz metodę która raz na godzinę pobierze nowe wartości z serwera i podmieni mapę z tym twoim beanie.

tak btw to zrobiłbym w sumie unmodifiable list w tej mapie, tak dla pewności ;)

0

Ale właśnie ta mapa nie musi być synchronizowana w Twoim przypadku @Shalom czyli

Czyli schedulujesz metodę która raz na godzinę pobierze nowe wartości z serwera i podmieni mapę z tym twoim beanie.

Ale dlaczego niby chcesz traktować listę wyników zaciągniętą godzine temu tak samo jak listę zaciągniętą 3minuty temu - panie, to jest performance issue, i to takie że w Sparcie, pojechaliby po premii ;D;D;D;D

Dlatego, wywalać i invalidować wynik, powinno się dla jednego klucza w mapie (albo po ludzku, Multimapie (http://docs.guava-libraries.go[...]e/common/collect/Multimap.html) ) - i w takim przypadku, synchronizacja jest konieczna.

0

@Shalom

  1. aha, ok. Po prostu zastanawiałem się czy są już jakieś cuda, że starczy obiekt zaznaczyć jakąs adnostacja i bedzie dzialac ;)
  2. Dobra rozumiem... myslalem, ze to dziala raczej tak, ze n. odpala sie z konkretna akcją i nie odpali sie dopoki nie minie jakis okres czasu czy cos w tym rodzaju.

Dzięki, chłopaki.

0

Tam nie ma żadnej magi - dając @Scheduled czy @Async mówisz springowi żeby proxował metodę i wrzucał to jakiegoś executora. np: @Scheduled trafi do ScheduledExecutorService

0

Ok, juz wiem o co mi chodzilo z tym logowaniem...

ten request o ktorym pisalem da sie wyslac dopiero po zalogowaniu usera, dla konkretngo uzytkownika.

Czy mozecie mnie jeszcze nakierowac jak mozna to zrobic?
Mam Spring Security. Sprawdzanie SecurityContextHolder i jaka kto ma rolę raczej nie brzmi fajnie.

Znalazlem SchedulingConfigurer i zastanawiam się czy mozna to jakos wykorzystac?

0

A w jaki sposób niby webservice waliduje czy ktoś się zalogował? Czy to ty sobie lokalnie sprawdzasz? Bo jeśli tylko ty lokalnie to nie widzę w ogóle problemu.
Jeśli webservice jakoś to sprawdza, to możesz zrobić sobie tą mapę per użytkownik jako beana ze scope ustawionym na session.

0

Widzę, że napisaliscie juz w komentarzu wczesniej ;)

Sorry za nieprezyzyjnosc, ale krok po kroku wychodzi co i jak.

Wiec, moge wyciagnac przestrzen nazw dla konkretnego Usera...

W sumie mozna sciagnac wszystko dla kazdego usera i trzymac to w mapie.

Ale brzmi to dosc hardcorowo, bo tego nie bedzie az tak malo.

0

ten webservice to sprawdza i po tamtej stronie są trzymane dane userów i hasel.

Ale juz mi podpowiedzieliscie z czym kombinowac.

Dzięki.

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