Vavr + Jackson deserializacja multimap

Vavr + Jackson deserializacja multimap
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Wie ktoś jak zdeserializować multimape vavrovą?
Mam taki kod:

Kopiuj
    private fun typeReference() = object : ParameterizedTypeReference<HashMultimap<String, String>>() {}

Kopiuj
    val response = restTemplate.exchange("http://localhost:${port}/user", HttpMethod.POST, HttpEntity(newUser), typeReference())

Dostaje:

Kopiuj
Type definition error: [simple type, class io.vavr.collection.HashMultimap]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `io.vavr.collection.HashMultimap` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
DQ
  • Rejestracja:prawie 10 lat
  • Ostatnio:7 miesięcy
  • Postów:141
1

Nie znam się ale wypowiem się:

To wygląda obiecująco: https://github.com/vavr-io/vavr-jackson/blob/master/README.md

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@DisQ: oczywiście że mam już to dodane. Ale niestety dla Multimapy nie działa :(


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
jarekr000000
Pytanie - gdzie ty masz to dodane?
Charles_Ray
Moduł zarejestrowałeś?
S9
Wiem że Spring Boot sam rejestruje te moduły w zależnościach ale nawet w jak. Configuration nadpisałem object mappera to nic nie dało
DQ
Tutaj https://stackoverflow.com/questions/46285615/serializer-deserializer-for-vavr-objects/46429886#46429886 jest napisane, że niektóre adnotacje (nie wiemy jak to u Ciebie wygląda) mogą nadpisywać konfiguracje - może coś w tym kierunku?
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
1

Nie mam pojęcia:
Wyizoluj przypadek - zrób test z gołym vavr-jackson (jak tu):

https://github.com/vavr-io/vavr-jackson/blob/master/src/test/java/io/vavr/jackson/datatype/multimap/HashMultimapTest.java

Będzie wiadomo co dalej.


jeden i pół terabajta powinno wystarczyć każdemu
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Ciekawe:
Jak mam to:

Kopiuj
 @Bean
 fun module() : Module {
        return VavrModule()
 }

Oraz

Kopiuj
    val response = restTemplate.postForEntity("http://localhost:${port}/user", newUser, String::class.java)

To mam prawidłowo serializowaną mape:

Kopiuj
{"username":["This username is already taken!"],"email":["This email is already taken!"]}

Spróbuję jakoś wyizolować przypadek, choć przyznam że nie wiem czy aż tak warto kopać się z koniem biorąc pod uwagę że tej multimapy potrzebuje tylko do testów.
Ale na pewno wyizolije później przypadek od Spring Boota i sprawdze czy tam działa
Ale skoro serializuje to powinno deserializowac :d

edit: sprawdzę czy nie trzeba skonfigurować jeszcze resttemplate :D


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 3x, ostatnio: scibi92
danek
  • Rejestracja:ponad 10 lat
  • Ostatnio:7 miesięcy
  • Lokalizacja:Poznań
  • Postów:797
0

Jeśli różne moduły to zobacz czy dobrze pakiety widzi.

Rest template raczej nie trzeba dodatkowo konfigurować, jedynie modelMappera mu podać dobrego


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
S9
Co masz na myśli pisząc o pakietach?
danek
miałem kiedyś problem taki, że w innych modułach klasy siedziały w innych pakietach niż w głównym (chodzi o to, że jak to złożysz to do jednego jara jak one są względem siebie) i autokonfiguracje springa się gubiły
S9
Ja mam jeden jar
KK
  • Rejestracja:prawie 17 lat
  • Ostatnio:17 dni
0

Ogólnie to takie coś:

Kopiuj
 @Bean
    fun vavrModule(): VavrModule {
        return VavrModule()
    }

działa dużo lepiej niż takie coś:

Kopiuj
	@Bean
	public ObjectMapper jacksonBuilder() {
		ObjectMapper mapper = new ObjectMapper();
		return mapper.registerModule(new VavrModule());
	}

ten drugi sposób tak jakby nadpisywał jakieś defaultowe konfiguracje spring boota, przez co sypie tym wyjątkiem deserializacji i wymaga dodania @JsonCreator i @JsonProperty w konstruktorze.


S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@kkojot: już mam tak poprawione. Serializacja działa świetnie, gorzej odwrotnie


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@jarekr000000: ucieszysz się, to wina Szpringa, normalnie to działa:

Kopiuj

    val mapper = objectMapper()
    val multiMap = HashMultimap.withSet<String>().of("one", "1", "two", "2")
    val json = mapper.writeValueAsString(multiMap)!!
    println(json)
    val deserializedMap = mapper.readValue<Multimap<String, String>>(json)
    println(deserializedMap)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
jarekr000000
Nie, no szok. A teraz znajdź zwałkę i im napraw :-)
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
2

@jarekr000000 @Charles_Ray @danek możecie być ciekawi, nie wiem czemu tego nie ogarnąłem ale błąd jest przez to że używam TestRestTemplate :D
Zwykły RestTemplate "działa" (oczywiście rzuca wyjątkiem zamiast wrócić responseentity z body jak by logika nakazywała) ;)
No cóż ale zawaliłem ja, trzeba było przeczytać dokumentacje :(

If you need customizations (for example to adding additional message converters) use a RestTemplateBuilder @Bean.

Ale to też chyba niezbyt precyzyjnie opisane, logika nakazywałaby raczej że TestRestTemplate powinno mieć te konwertery z aplikacji, a tu tylko powinniśmy dodawac konwertery swoich klas.

Swoją drogą to ciekawe - czemu TestRestTemplate od początku działał poprawnie dla data class Kotlinowych? Może bugiem jest to że nie zarejestrował beanu z konfiguracją Vavra?


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 4x, ostatnio: scibi92
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 4 godziny
  • Postów:1880
1

No nie do końca, bo tak naprawdę, żeby być 100% czystym powinieneś mieć RestTemplate per serwer - API specyfikuje np. format daty, zapisu pieniędzy itd, każdy może sobie zwracać format jaki chce. Do tego inne ustawienia timeoutów mogą być sensowne.

TestRestTemplate jest klientem zasobów wystawianych przez Ciebie i dla mnie to logiczne, że powinno się go konfigurować niezależnie.

A czemu coś działało, a tamto nie, to tylko debugerka Springa chyba prawdę powie - to akurat logiczne być nie musi i pewnie potrafi się zmieniać razem z wersja Springa :p


”Engineering is easy. People are hard.” Bill Coughran
edytowany 3x, ostatnio: Charles_Ray
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

No nie do końca, bo tak naprawdę, żeby być 100% czystym powinieneś mieć RestTemplate per serwer - API specyfikuje np. format daty, zapisu pieniędzy itd, każdy może sobie zwracać format jaki chce. Do tego inne ustawienia timeoutów mogą być sensowne.

Co do zasady masz rację, mi chodziło o moduły Jacksonowe do obsługi (de)serializacji. Zwykły RestTemplaty współdzielą globalnie zarejestrowane moduły, więc widze tu niekonsekwencję troche


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.