Spring i adnotacje a ładowanie wartości z json

0

Cześć

potrzebuję wczytywać plik json jako klasę i walidować to adnotacjami z Springa, mogę się wspomagać refleksją.
Przykład:

    @MyConfiguration
    public class GlobalConfig
    {
        @ConfigurationFile(fileName = "my_config.json")
        public static Config config;

        @ConfigurationClass(desc = "description")
        public static class Config
        {
            @ConfigurationType(required = true)
            public String value1;
            @ConfigurationType(required = true)
            public ConfigClass1 configClass1;   //jakaś tam klasa zagnieżdzona

            public static class ConfigClass1
            {
                @ConfigurationType(required = true)
                public volatile String key;
                @ConfigurationType(required = false)
                public volatile String value;
            }
        } 
        
        //itd
    }
    

przykład pliku my_config.json

{
   "value1":"wartosc",
   "configClass1":[
      {
         "key":"klucz1",
         "value":"wartosc1"
      },
      {
         "key":"klucz2",
         "value":"wartosc2"
      }
   ]
}

Nie jestem za bardzo biegły w adnotacjach Springowych oraz refleksji. Na początku wczytuje jsona dzięki fileName i zaczyna się problem. Jak teraz mogę połączyć "value1":"wartosc" z @ConfigurationType(required = true) public String value1; abym mógł wziąć parametr required oraz typ zmiennej (aby sprawdzić czy "wartość" jest Stringiem albo np. liczbą i rzucić błąd)? Wydaje mi się, że adnotacje nie dają mi dostępu do nazwy zmiennej. Ponadto jak widać może się też trafić tablica więc nawet szukanie po nazwie nie jest sposobem idealnym. Brak mi pomysłu jak ugryźć ten temat. Jakieś pomysły?

Dzięki.

2

Najpierw napisz, dlaczego chcesz to robić, co chcesz osiągnąć. Te adnotacje są Twoje czy z jakiejś biblioteki? Po co Ci one?

Na wczytanie konfiguracji w Springu są inne sposoby (płaskie pliki properties lub yamle).

Względnie można użyć Jacksona/Gsona, a chyba najbardziej hardkorowo AVRO :)

0

Właśnie miałem dopisać do glównego postu, że to są jakieś moje wymyślone adnotacje, ale chyba nie mogę już edytować.

Cel jest taki, aby powstały pliki *.json, które siedziały by w jakimś folderze, a jakiś scheduler co X sekund by je wczytywał i podmieniał wartości, które mogą się dynamicznie zmieniać i w aplikacji byłyby jakieś wartości typu GlobalConfiguration.emailConfiguration.title . Z tego co wiem różne propertiesy tego nie umożliwiają. Są one określone na starcie aplikacji, a ja potrzebuję je zmieniać podczas działania programu.

Może są do tego narzędzia, a ja nie wiem jakie?

2

No widzisz, od razu inna rozmowa :) https://www.baeldung.com/netflix-archaius-spring-cloud-integration

PS. To co chciałeś zrobić nie zadziała tak długo jak nie przeładujesz kontekstu Springa.

1

Jeszcze sobie pomyślałem, że to co chcesz zrobić może być całkiem krzywe - scheduler podmienia wartości propertiesów. Dodatkowe pytania: po co jest ten scheduler i dlaczego nie możesz użyć bazy do przechowywania tych wartości? Wtedy mógłbyś zrobić snapshoty, mieć historie zmian itd

0

Załóżmy, że na tym etapie baza odpada.
Scheduler po prostu ładuje konfiguracje z plików co powiedzmy 10 sekund. Tak wiem, jest to trochę sięrmiężne rozwiązanie, ale załóżmy, że na razie rozpatrujemy taki przypadek jak podałem.

Dodatkowo nie rozumiem, czemu takie rozwiązanie wymagałoby przeładowania kontekstu springowego.

0

Załóżmy, że na tym etapie baza odpada.
Scheduler po prostu ładuje konfiguracje z plików co powiedzmy 10 sekund. Tak wiem, jest to trochę sięrmiężne rozwiązanie, ale załóżmy, że na razie rozpatrujemy taki przypadek jak podałem.

Coraz bardziej mi to śmierdzi :) Napisz, co chcesz zrobić, po co ten scheduler. Jaką wartość on ma zmieniać, co biznesowo się znajduje w tych polach?

Dodatkowo nie rozumiem, czemu takie rozwiązanie wymagałoby przeładowania kontekstu springowego.

Spring stawia kontekst na podstawie konfiguracji początkowej, tj. tworzy beany. Zmieniasz konfigurację. W jaki sposób bean ma się dowiedzieć o tym, że zmieniła się wartość w pliku?

0
Charles_Ray napisał(a):

Spring stawia kontekst na podstawie konfiguracji początkowej, tj. tworzy beany. Zmieniasz konfigurację. W jaki sposób bean ma się dowiedzieć o tym, że zmieniła się wartość w pliku?

Klasa jest statyczna i można się do niej odwoływać globalnie: GlobalConfiguration.email.emailTitle gdzie email jest public static Email email; i zawiera w sobie pole emailTitle. Moja klasa konfiguracyjna nie jest beanem springowym.

Edit
Dodam tylko, że te pola są wykorzystywane nie przez springa, nie ustawiają one portów dla bazy itp więc imo przeładowywanie kontekstu springa mija się z celem. Wyobraź sobie sytuacje, że wysyłamy emaila co godzine i chcemy móc zmienić tytuł runtime.

1
Undersent napisał(a):
Charles_Ray napisał(a):

Spring stawia kontekst na podstawie konfiguracji początkowej, tj. tworzy beany. Zmieniasz konfigurację. W jaki sposób bean ma się dowiedzieć o tym, że zmieniła się wartość w pliku?

Klasa jest statyczna i można się do niej odwoływać globalnie: GlobalConfiguration.email.emailTitle gdzie email jest public static Email email; i zawiera w sobie pole emailTitle. Moja klasa konfiguracyjna nie jest beanem springowym.

To niepotrzebnie mieszasz w to Springa. To co potrzebujesz to:

  1. Znaleźć scheduler który będzie czytać plik co 10 minut
  2. Znaleźć dobrą bibliotekę do parsowania. Jeśli json to Gson lub Jackson. Ale jeśli chodzi o format pliku bardziej na topie jest YAML, chociaż ja najbardziej lubię HOCON
  3. Przerobić tą klasę statyczną na prosty singleton (nie jest to ładne, ale proste)
  4. Co dziesięć minut parsować plik i sparsowany obiekt wpisywać do singletona

Nie jest to rozwiązanie najlepsze na świecie, ale zadziała

0

Dokładnie to co mówisz. Chyba nie ogarnąłem, że jest taka funkcja https://www.tutorialspoint.com/java/lang/class_getfield.htm, która pozwoli mi dostać nazwę pola i zmapować walidacje przez adnotacje a wartości w JSONiei (nie wiem czy napisałem to zrozumiale) . Może niefortunnie się wyraziłem i umieściłem w tytule Springa.

Dzięki.

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