Czy jest możliwe, aby puste wartości RequestParam używały wartości defaultValue?

120

jeśli mam mapowanie żądań podobne do następującego:

@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody
public void test(@RequestParam(value = "i", defaultValue = "10") int i) {
}

A następnie zadzwoń do tej prośby z:

http://example.com/test?i=

Otrzymuję komunikat o błędzie

Nie udało się przekonwertować wartości typu „java.lang.String” na typ „int”; zagnieżdżony wyjątek to java.lang.NumberFormatException: Dla ciągu wejściowego: "" '

Mogę rozwiązać ten problem, powstrzymując klienta javascript przed wysyłaniem pustych parametrów lub akceptując wartości ciągów i analizując je tylko wtedy, gdy nie okaże się, że są puste.

AKTUALIZACJA : Późniejsze wersje wiosny implementują teraz pierwotnie pożądane zachowanie.

Właśnie przetestowałem to na wiosnę 4.3.5 i stwierdziłem, że to zachowanie w rzeczywistości zmieni wartość null na wartość domyślną bez podnoszenia a NumberFormatException, zatem; moje oryginalne mapowanie działa teraz dobrze.

Nie jestem pewien, w której wersji wiosny dokonano tej zmiany zachowania.

Brett Ryan
źródło
z pewnością parametr byłby typem Integer, aby zgłosić ten wyjątek?
laher
3
Nie jestem ekspertem od sprężyn, ale czy wartość domyślna jest używana, gdy jej nie ustawisz? tzn. czy Twoja prośba to example.com/test ? jak używasz example.com/test?i=, wtedy i jest obecne i ustawione na „”, więc wartość domyślna nie jest używana
user902383
Dzięki amir75, przypadkowo dostarczony Stringtyp. user902383, to jest poprawne, chociaż dla wartości całkowitej wolałbym, aby wartość null / pusta używała zamiast tego defaultValue.
Brett Ryan,

Odpowiedzi:

175

Możesz zmienić typ @RequestParam na Integer i sprawić, że nie będzie to wymagane. Pozwoliłoby to na pomyślne wykonanie żądania, ale byłoby wówczas nieważne. Możesz jawnie ustawić wartość domyślną w metodzie kontrolera:

@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody
public void test(@RequestParam(value = "i", required=false) Integer i) {
    if(i == null) {
        i = 10;
    }
    // ...
}

Usunąłem wartość defaultValue z powyższego przykładu, ale możesz chcieć ją uwzględnić, jeśli spodziewasz się otrzymywać żądania, w których nie jest ona w ogóle ustawiona:

http://example.com/test
Matt
źródło
6
Tylko aktualizacja tego, ostatnie wersje sprężyny w rzeczywistości nie wymagają już sprawdzenia zerowego, ponieważ żądane zachowanie zostało uwzględnione w sprężynie, że puste wartości spowodują użycie wartości domyślnej.
Brett Ryan
3
Przestarzałe odpowiedzi, najlepsze rozwiązanie pochodzi z @AppLend
Jose Pose S
101

Możesz zachować typ pierwotny, ustawiając wartość domyślną, w twoim przypadku wystarczy dodać właściwość „required = false” :

@RequestParam(value = "i", required = false, defaultValue = "10") int i

PS Ta strona z dokumentacji Springa może być przydatna: Typ adnotacji RequestParam

AppLend
źródło
1
Dzięki, ale przegapiłeś sens mojego pytania, które jest w tytule. Poprosiłem o możliwość dostarczania pustych parametrów, /test?i=a ponieważ ijest puste, mają wartość domyślną.
Brett Ryan,
5
W każdym razie, kiedy defaultValuepodano, required == falsepośrednio
Timur Milovanov
4
Jeśli parametr jest podany, ale jest pusty defaultValue, nie obowiązuje.
Brett Ryan
12

Możesz ustawić RequestParam, używając ogólnej klasy Integer zamiast int, rozwiąże to twój problem.

   @RequestParam(value= "i", defaultValue = "20") Integer i
Anand Tagore
źródło
1

Możesz też zrobić coś takiego -

 @RequestParam(value= "i", defaultValue = "20") Optional<Integer> i
Tisha
źródło
3
Jeśli masz wartość defaultValue, nie ma potrzeby, aby była to opcja opcjonalna.
Kevin M