Załóżmy, że mam stronę z listą obiektów w tabeli i muszę umieścić formularz w celu filtrowania tabeli. Filtr jest wysyłany jako Ajax GET na taki adres URL: http://foo.com/system/controller/action?page=1&prop1=x&prop2=y&prop3=z
I zamiast mieć wiele parametrów na moim kontrolerze, takich jak:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "prop1", required = false) String prop1,
@RequestParam(value = "prop2", required = false) String prop2,
@RequestParam(value = "prop3", required = false) String prop3) { ... }
Załóżmy, że mam MyObject jako:
public class MyObject {
private String prop1;
private String prop2;
private String prop3;
//Getters and setters
...
}
Chcę zrobić coś takiego:
@RequestMapping(value = "/action")
public @ResponseBody List<MyObject> myAction(
@RequestParam(value = "page", required = false) int page,
@RequestParam(value = "myObject", required = false) MyObject myObject,) { ... }
Czy to możliwe? Jak mogę to zrobić?
java
spring-mvc
renanleandrof
źródło
źródło
@ModelAttribute
, Spring MVC Przykład obsługi formularzy . Wystarczy google „ Obsługa formularzy Spring MVC ”, a otrzymasz mnóstwo samouczków / przykładów. Ale pamiętaj, aby użyć nowoczesnego sposobu obsługi formularzy, tj. Spring v2.5 +@ModelAttribute
na wiosnę MVCOdpowiedzi:
Możesz to absolutnie zrobić, po prostu usuń
@RequestParam
adnotację, Spring czysto powiąże parametry żądania z instancją klasy:źródło
MyObject
tego w podobny sposób, jak w przypadku @RequestParam?MyObject
parametr akceptacji zapytania w przypadku węża i odwzorować go na członka przypadku wielbłądaMyObject
. Na przykład,?book_id=4
należy zmapować zbookId
członkiemMyObject
?Dodaję od siebie krótki przykład.
Klasa DTO:
Żądanie mapowania wewnątrz klasy kontrolera:
Pytanie:
Wynik:
Mam nadzieję, że to pomoże :)
AKTUALIZACJA / KOTLIN
Ponieważ obecnie dużo pracuję z Kotlinem, jeśli ktoś chce zdefiniować podobne DTO, klasa w Kotlinie powinna mieć następującą postać:
Z taką
data
klasą jak ta:sprężyna (testowana podczas rozruchu) zwraca następujący błąd dla żądania wymienionego w odpowiedzi:
Klasa danych będzie działać tylko w przypadku następującego formularza parametrów zapytania:
Bądź tego świadomy!
źródło
Mam bardzo podobny problem. W rzeczywistości problem jest głębszy, jak myślałem. Używam jquery,
$.post
która używaContent-Type:application/x-www-form-urlencoded; charset=UTF-8
domyślnie. Niestety oparłem na tym swój system i kiedy potrzebowałem złożonego obiektu,@RequestParam
nie mogłem tego po prostu zrealizować.W moim przypadku próbuję wysłać preferencje użytkownika za pomocą czegoś takiego;
Po stronie klienta rzeczywiste surowe dane wysyłane do serwera to;
parsowane jako;
a po stronie serwera jest;
Próbowałem
@ModelAttribute
, dodałem setter / getters, konstruktory ze wszystkimi możliwościami,UserPreferences
ale bez szansy, ponieważ rozpoznał wysłane dane jako 5 parametrów, ale w rzeczywistości metoda mapowana ma tylko 2 parametry. Próbowałem również rozwiązania Biju, jednak zdarza się, że wiosna tworzy obiekt UserPreferences z domyślnym konstruktorem i nie wypełnia danych.Rozwiązałem problem, wysyłając ciąg JSon preferencji po stronie klienta i traktując go jak ciąg po stronie serwera;
klient:
serwer:
w skrócie, zrobiłem konwersję ręcznie w metodzie REST. Moim zdaniem powodem, dla którego wiosna nie rozpoznaje przesłanych danych, jest typ zawartości.
źródło
@RequestMapping(method = POST, path = "/settings/{projectId}") public void settings(@PathVariable String projectId, @RequestBody ProjectSettings settings)
Ponieważ pod każdym postem pojawia się pytanie, jak ustawić pola obowiązkowe, napisałem mały przykład, jak ustawić pola zgodnie z wymaganiami:
źródło
Chociaż odpowiedzi, które odnoszą się do
@ModelAttribute
,@RequestParam
,@PathParam
i tacy są ważne, istnieje małe haczyka wpadłem. Wynikowym parametrem metody jest proxy, które Spring otacza DTO. Jeśli więc spróbujesz użyć go w kontekście wymagającym własnego typu niestandardowego, możesz uzyskać nieoczekiwane wyniki.Następujące elementy nie będą działać:
W moim przypadku próba użycia go w powiązaniu z Jacksonem zakończyła się
com.fasterxml.jackson.databind.exc.InvalidDefinitionException
.Musisz utworzyć nowy obiekt z dto.
źródło
Tak, możesz to zrobić w prosty sposób. Zobacz poniżej kod linii.
URL - http: // localhost: 8080 / get / request / multiple / param / by / map? Name = 'abc' & id = '123'
źródło
Zaakceptowana odpowiedź działa jak urok, ale jeśli obiekt ma listę obiektów, nie będzie działał zgodnie z oczekiwaniami, więc oto moje rozwiązanie po pewnym kopaniu.
Postępując zgodnie z tą radą wątku , oto jak to zrobiłem.
Nie jest najlepszy do debugowania interfejsu API za pomocą listonosza, ale działa zgodnie z oczekiwaniami.
A tutaj SearchFilterDTO i FilterDTO
źródło