web-dev-qa-db-fra.com

@PathVariable peut-il retourner null s'il n'est pas trouvé?

Est-il possible de faire le @PathVariable pour retourner null si la variable path n'est pas dans l'url? Sinon, je dois faire deux gestionnaires. Un pour /simple et un autre pour /simple/{game}, mais les deux font la même chose juste s'il n'y a pas de jeu défini, je choisis le premier dans une liste mais s'il y a un paramètre de jeu défini, je l'utilise.

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable("example") String example,
            HttpServletRequest request) {

Et voici ce que j'obtiens en essayant d'ouvrir la page /simple:

Causé par: Java.lang.IllegalStateException: impossible de trouver @PathVariable [exemple] dans @RequestMapping

28
Rihards

Ils ne peuvent pas être facultatifs, non. Si vous en avez besoin, vous avez besoin de deux méthodes pour les gérer.

Cela reflète la nature des variables de chemin - cela n'a pas vraiment de sens qu'elles soient nulles. Les URL de style REST ont toujours besoin du chemin URL complet. Si vous avez un composant facultatif, envisagez d'en faire un paramètre de requête à la place (c'est-à-dire en utilisant @RequestParam). C'est beaucoup mieux adapté aux arguments optionnels.

31
skaffman

Comme d'autres l'ont déjà mentionné, vous ne pouvez pas vous attendre à ce qu'ils soient nuls lorsque vous avez explicitement mentionné les paramètres du chemin. Cependant, vous pouvez faire quelque chose comme ci-dessous comme solution de contournement -

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Map<String, String> pathVariablesMap,
            HttpServletRequest request) {
    if (pathVariablesMap.containsKey("game")) {
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}

Si vous utilisez Spring 4.1 et Java 8, vous pouvez utiliser Java.util.Optional qui est pris en charge dans @RequestParam, @PathVariable, @RequestHeader et @MatrixVariable au printemps MVC

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Optional<String> game,
            HttpServletRequest request) {
    if (game.isPresent()) {
        //game.get()
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}
27
Aniket Thakur

Vous pouvez toujours faire ceci:

@RequestMapping(value = "/simple", method = RequestMethod.GET)
public ModelAndView gameHandler(HttpServletRequest request) {
    gameHandler2(null, request)
}

@RequestMapping(value = "/simple/{game}", method = RequestMethod.GET)
public ModelAndView gameHandler2(@PathVariable("game") String game,
        HttpServletRequest request) {
19
Shawn K.
@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value="example",required = false) final String example)

Essayez cette approche, cela a fonctionné pour moi.

1
user10222941

Je viens de tester cela tout à l'heure, mais en combinant la solution ci-dessus, j'ai obtenu ceci:

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value = "game", required = false) String example,
                                HttpServletRequest request) {
    if (example != null) {
        //...
    } else {
        //pick first, ...
    }
}

Maintenant, lorsque vous utilisez "/ simple", l'exemple String sera nul au lieu de lancer Exception.

Solution courte, pas de fantaisie Facultatif <> ou carte <>

0
Thanh Nguyen