Ist es möglich, dass leere RequestParam-Werte den defaultValue verwenden?

120

Wenn ich eine Anforderungszuordnung habe, die der folgenden ähnelt:

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

Und dann rufen Sie diese Anfrage mit:

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

Ich erhalte die Fehlermeldung

Fehler beim Konvertieren des Werts vom Typ 'java.lang.String' in den Typ 'int'; verschachtelte Ausnahme ist java.lang.NumberFormatException: Für Eingabezeichenfolge: "" '

Ich kann dies lösen, indem ich entweder den Javascript-Client daran hindere, leere Parameter zu senden, oder indem ich Zeichenfolgenwerte akzeptiere und nur analysiere, wenn sie nicht leer sind.

UPDATE : Spätere Versionen von Spring implementieren jetzt das ursprünglich gewünschte Verhalten.

Ich habe dies gerade im Frühjahr 4.3.5 getestet und festgestellt, dass das Verhalten nun tatsächlich den Nullwert in den Standardwert umwandelt, ohne a zu erhöhen NumberFormatException. Mein ursprüngliches Mapping funktioniert jetzt einwandfrei.

Ich bin nicht sicher, in welcher Version des Frühlings diese Verhaltensänderung vorgenommen wurde.

Brett Ryan
quelle
Sicherlich wäre der Parameter ein Integer-Typ, um diese Ausnahme auszulösen.
Laher
3
Ich bin kein Frühlingsexperte, aber wird der Standardwert verwendet, wenn Sie ihn nicht einstellen? dh ob Ihre Anfrage example.com/test lautet ?
Wenn
Danke amir75, versehentlich gelieferter StringTyp. user902383, das ist richtig, obwohl ich für einen ganzzahligen Wert bevorzugen würde, dass ein null / leerer Wert stattdessen den defaultValue verwendet.
Brett Ryan

Antworten:

175

Sie können den @ RequestParam-Typ in eine Ganzzahl ändern und ihn nicht erforderlich machen. Dies würde es Ihrer Anfrage ermöglichen, erfolgreich zu sein, aber dann wäre sie null. Sie können ihn in der Controller-Methode explizit auf Ihren Standardwert setzen:

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

Ich habe den defaultValue aus dem obigen Beispiel entfernt, aber Sie können ihn einschließen, wenn Sie erwarten, Anforderungen zu erhalten, bei denen er überhaupt nicht festgelegt ist:

http://example.com/test
Matt
quelle
6
Nur ein Update dazu, neuere Versionen von Spring erfordern tatsächlich keine Nullprüfung mehr, da das gewünschte Verhalten in Spring enthalten ist, dass leere Werte dazu führen, dass der Standardwert verwendet wird.
Brett Ryan
3
Veraltete Antworten, die beste Lösung ist von @AppLend
Jose Pose S
101

Sie können den primitiven Typ beibehalten, indem Sie den Standardwert festlegen. In Ihrem Fall fügen Sie einfach die Eigenschaft "required = false" hinzu :

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

PS Diese Seite aus der Spring-Dokumentation kann hilfreich sein: Anmerkungstyp RequestParam

AppLend
quelle
1
Vielen Dank, aber Sie haben den Punkt meiner Frage im Titel verpasst. Ich habe nach der Möglichkeit gefragt, leere Parameter anzugeben, /test?i=und da ileer ist, habe ich den Standardwert.
Brett Ryan
5
Wie auch immer, wann defaultValuewurde required == falseimplizit zur Verfügung gestellt
Timur Milovanov
4
Wenn der Parameter angegeben wird, aber leer ist, defaultValuewird er nicht wirksam.
Brett Ryan
12

Sie können RequestParam festlegen, indem Sie die generische Klasse Integer anstelle von int verwenden. Dadurch wird Ihr Problem behoben.

   @RequestParam(value= "i", defaultValue = "20") Integer i
Anand Tagore
quelle
1

Sie können auch so etwas tun -

 @RequestParam(value= "i", defaultValue = "20") Optional<Integer> i
Tisha
quelle
3
Wenn Sie einen Standardwert haben, müssen Sie diesen nicht als optional festlegen.
Kevin M
1

Dies wurde 2013 als Fehler angesehen: https://jira.spring.io/browse/SPR-10180

und wurde mit Version 3.2.2 behoben. Danach sollte in keiner Version ein Problem auftreten, und Ihr Code sollte einwandfrei funktionieren.

eis
quelle