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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4904092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:18:38  来源:igfitidea点击:

With Spring can I make an optional path variable?

springrest

提问by Shamik

With Spring 3.0, can I have an optional path variable?

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

For example

例如

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

Here I would like /json/abcor /jsonto call the same method.
One obvious workaround declare typeas a request parameter:

这里我想/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();
}

and then /json?type=abc&track=aaor /json?track=rrwill work

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

回答by earldouglas

You can't have optional path variables, but you can have two controller methods which call the same service code:

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

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

回答by Aniket Thakur

If you are using Spring 4.1 and Java 8 you can use java.util.Optionalwhich is supported in @RequestParam, @PathVariable, @RequestHeaderand @MatrixVariablein Spring MVC -

如果您在使用Spring 4.1和Java 8,你可以使用java.util.Optional它支持@RequestParam@PathVariable@RequestHeader@MatrixVariableSpring 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"
    }       
}

回答by Paul Wardrip

It's not well known that you can also inject a Map of the path variables using the @PathVariable annotation. I'm not sure if this feature is available in Spring 3.0 or if it was added later, but here is another way to solve the example:

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

回答by Maleck13

You could use a :

你可以使用一个:

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

for optional params rather than a pathVariable

用于可选参数而不是 pathVariable

回答by kinjelom

Spring 5 / Spring Boot 2 examples:

Spring 5 / Spring Boot 2 示例:

blocking

阻塞

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

reactive

反应性

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

回答by rogerdpack

Simplified example of Nicolai Ehmann's comment and wildloop's answer (Spring 4.3.3+), you can use required = falsenow:

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

回答by Uresh Kuruhuri

Check this Spring 3 WebMVC - Optional Path Variables. It shows an article of making an extension to AntPathMatcher to enable optional path variables and might be of help. All credits to Sebastian Heroldfor posting the article.

检查这个Spring 3 WebMVC-Optional Path Variables。它显示了对 AntPathMatcher 进行扩展以启用可选路径变量的文章,可能会有所帮助。所有学分塞巴斯蒂安·赫罗尔德张贴的文章。

回答by Ankush Mundada

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