用Spring我可以做一个可选的路径变量吗?

在Spring 3.0中,我可以有一个可选的路径变量吗?

例如

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(
HttpServletRequest req,
@PathVariable String type,
@RequestParam("track") String track) {
return new TestBean();
}
这里我希望/json/abc/json调用相同的方法。< br / > 一个明显的解决方法是将type声明为请求参数:

@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();
}

然后/json?type=abc&track=aa/json?track=rr将工作

188957 次浏览

你不能有可选的路径变量,但你可以有两个控制器方法调用相同的服务代码:

@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();
}

你可以使用a:

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

用于可选参数而不是pathVariable

检查这个Spring 3 WebMVC -可选路径变量。它展示了一篇对AntPathMatcher进行扩展以启用可选路径变量的文章,可能会有帮助。所有的功劳都归于塞巴斯蒂安·赫罗尔德,因为它发布了这篇文章。

您还可以使用@PathVariable注释注入路径变量的Map,这一点并不广为人知。我不确定这个特性在Spring 3.0中是否可用,或者它是后来添加的,但这里有另一种解决示例的方法:

@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();
}
}
$.ajax({
type : 'GET',
url : '${pageContext.request.contextPath}/order/lastOrder',
data : {partyId : partyId, orderId :orderId},
success : function(data, textStatus, jqXHR) });


@RequestMapping(value = "/lastOrder", method=RequestMethod.GET)
public @ResponseBody OrderBean lastOrderDetail(@RequestParam(value="partyId") Long partyId,@RequestParam(value="orderId",required=false) Long orderId,Model m ) {}

如果你正在使用Spring 4.1和Java 8,你可以使用java.util.Optional,它在Spring MVC -中的@RequestParam@PathVariable@RequestHeader@MatrixVariable中得到支持

@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"
}
}

Spring 5 / Spring Boot 2示例:

阻塞

@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));
}

Nicolai Ehmann的注释和wildloop的回答的简化示例(适用于Spring 4.3.3+),基本上你现在可以使用required = false:

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

以下是直接来自baeldung参考页面的答案:- https://www.baeldung.com/spring-optional-path-variables < / p >

谢谢Paul Wardrip 在我的例子中,我使用required.

@RequestMapping(value={ "/calificacion-usuario/{idUsuario}/{annio}/{mes}", "/calificacion-usuario/{idUsuario}" }, method=RequestMethod.GET)
public List<Calificacion> getCalificacionByUsuario(@PathVariable String idUsuario
, @PathVariable(required = false) Integer annio
, @PathVariable(required = false) Integer mes) throws Exception {
return repositoryCalificacion.findCalificacionByName(idUsuario, annio, mes);
}