web-dev-qa-db-fra.com

Avec Spring, puis-je créer une variable de chemin optionnelle?

Avec Spring 3.0, puis-je avoir une variable de chemin optionnelle?

Par exemple

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(
        HttpServletRequest req,
        @PathVariable String type,
        @RequestParam("track") String track) {
    return new TestBean();
}

Ici, je voudrais que /json/abc ou /json appelle la même méthode.
Une solution de contournement évidente déclare type en tant que paramètre de requête:

@RequestMapping(value = "/json", method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(
        HttpServletRequest req,
        @RequestParam(value = "type", required = false) String type,
        @RequestParam("track") String track) {
    return new TestBean();
}

puis /json?type=abc&track=aa ou /json?track=rr fonctionnera

167
Shamik

Vous ne pouvez pas avoir de variables de chemin optionnelles, mais vous pouvez avoir deux méthodes de contrôleur appelant le même code de service:

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
        HttpServletRequest req,
        @PathVariable String type,
        @RequestParam("track") String track) {
    return getTestBean(type);
}

@RequestMapping(value = "/json", method = RequestMethod.GET)
public @ResponseBody TestBean testBean(
        HttpServletRequest req,
        @RequestParam("track") String track) {
    return getTestBean();
}
175
earldouglas

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 = {"/json/{type}", "/json" }, method = RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
    @PathVariable Optional<String> type,
    @RequestParam("track") String track) {      
    if (type.isPresent()) {
        //type.get() will return type value
        //corresponds to path "/json/{type}"
    } else {
        //corresponds to path "/json"
    }       
}
96
Aniket Thakur

Ce n'est pas bien connu que vous pouvez également injecter une carte des variables de chemin à l'aide de l'annotation @PathVariable. Je ne sais pas si cette fonctionnalité est disponible dans Spring 3.0 ou si elle a été ajoutée ultérieurement, mais voici un autre moyen de résoudre cet exemple:

@RequestMapping(value={ "/json/{type}", "/json" }, method=RequestMethod.GET)
public @ResponseBody TestBean typedTestBean(
    @PathVariable Map<String, String> pathVariables,
    @RequestParam("track") String track) {

    if (pathVariables.containsKey("type")) {
        return new TestBean(pathVariables.get("type"));
    } else {
        return new TestBean();
    }
}
73
Paul Wardrip

Vous pouvez utiliser un:

@RequestParam(value="somvalue",required=false)

pour les paramètres optionnels plutôt que pathVariable

23
Maleck13

Exemples de Spring 5/Spring Boot 2:

blocage

@GetMapping({"/dto-blocking/{type}", "/dto-blocking"})
public ResponseEntity<Dto> getDtoBlocking(
        @PathVariable(name = "type", required = false) String type) {
    if (StringUtils.isEmpty(type)) {
        type = "default";
    }
    return ResponseEntity.ok().body(dtoBlockingRepo.findByType(type));
}

réactif

@GetMapping({"/dto-reactive/{type}", "/dto-reactive"})
public Mono<ResponseEntity<Dto>> getDtoReactive(
        @PathVariable(name = "type", required = false) String type) {
    if (StringUtils.isEmpty(type)) {
        type = "default";
    }
    return dtoReactiveRepo.findByType(type).map(dto -> ResponseEntity.ok().body(dto));
}
6
wildloop

Vérifiez ceci Printemps 3 WebMVC - Variables de chemin optionnelles . Il montre un article sur la création d'une extension vers AntPathMatcher pour activer des variables de chemin facultatives et pourrait être utile. Tous les crédits à Sebastian Herold pour avoir posté l'article.

3
Uresh Kuruhuri

Exemple simplifié du commentaire de Nicolai Ehmann et de la réponse de wildloop (Spring 4.3.3+), vous pouvez utiliser required = false maintenant:

  @RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET)
  public @ResponseBody TestBean testAjax(@PathVariable(required = false) String type) {
    if (type != null) {
      // ...
    }
    return new TestBean();
  }
2
rogerdpack