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
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();
}
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"
}
}
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();
}
}
Vous pouvez utiliser un:
@RequestParam(value="somvalue",required=false)
pour les paramètres optionnels plutôt que pathVariable
@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));
}
@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));
}
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.
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();
}