使用Spring,我可以创建一个可选的路径变量吗?

时间:2011-02-04 23:58:11

标签: spring rest

使用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调用相同的方法。
一个明显的解决方法是将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将起作用

10 个答案:

答案 0 :(得分:170)

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

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

答案 1 :(得分:92)

如果您使用的是Spring 4.1和Java 8,则可以使用Spring java.util.Optional@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"
    }       
}

答案 2 :(得分:73)

众所周知,您还可以使用@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();
    }
}

答案 3 :(得分:23)

您可以使用:

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

表示可选参数而不是pathVariable

答案 4 :(得分:5)

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

答案 5 :(得分:2)

检查Spring 3 WebMVC - Optional Path Variables。它显示了一个对AntPathMatcher进行扩展以启用可选路径变量的文章,可能会有所帮助。 Sebastian Herold发布文章的所有信用。

答案 6 :(得分:1)

这是直接来自baeldung参考页的答案:- https://www.baeldung.com/spring-optional-path-variables

答案 7 :(得分:0)

Nicolai Ehmann的评论和wildloop的答案的简化示例(春季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();
  }

答案 8 :(得分:0)

感谢保罗沃德里普 在我的情况下,我使用 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);
}

答案 9 :(得分:-4)

$.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 ) {}