如果没有找到@PathVariable可以返回null吗?

发布于 2024-10-27 15:44:10 字数 577 浏览 2 评论 0原文

如果路径变量不在 url 中,是否可以使 @PathVariable 返回 null?否则我需要制作两个处理程序。一个用于 /simple ,另一个用于 /simple/{game} ,但如果没有定义游戏,两者都会执行相同的操作,我会从列表中选择第一个,但是如果有是一个游戏参数定义然后我使用它。

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable("example") String example,
            HttpServletRequest request) {

这就是我尝试打开页面 /simple 时得到的结果:

原因:java.lang.IllegalStateException:在@RequestMapping中找不到@PathVariable [示例]

Is it possible to make the @PathVariable to return null if the path variable is not in the url? Otherwise I need to make two handlers. One for /simple and another for /simple/{game}, but both do the same just if there is no game defined i pick first one from a list however if there is a game param defined then i use it.

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable("example") String example,
            HttpServletRequest request) {

And this is what I get when trying to open page /simple:

Caused by: java.lang.IllegalStateException: Could not find @PathVariable [example] in @RequestMapping

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

哭了丶谁疼 2024-11-03 15:44:10

它们不能是可选的,不是。如果您需要的话,您需要两种方法来处理它们。

这反映了路径变量的本质 - 它们为空并没有真正的意义。 REST 样式的 URL 始终需要完整的 URL 路径。如果您有可选组件,请考虑将其设为请求参数(即使用@RequestParam)。这更适合可选参数。

They cannot be optional, no. If you need that, you need two methods to handle them.

This reflects the nature of path variables - it doesn't really make sense for them to be null. REST-style URLs always need the full URL path. If you have an optional component, consider making it a request parameter instead (i.e. using @RequestParam). This is much better suited to optional arguments.

北陌 2024-11-03 15:44:10

正如其他人已经提到的那样,当您明确提到路径参数时,您不能期望它们为空。但是,您可以执行如下操作作为解决方法 -

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Map<String, String> pathVariablesMap,
            HttpServletRequest request) {
    if (pathVariablesMap.containsKey("game")) {
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}

如果您使用 Spring 4.1 和 Java 8,则可以使用 @RequestParam@PathVariable 中支持的 java.util.Optional Spring MVC 中的 >、@RequestHeader@MatrixVariable

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Optional<String> game,
            HttpServletRequest request) {
    if (game.isPresent()) {
        //game.get()
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}

As others have already mentioned No you cannot expect them to be null when you have explicitly mentioned the path parameters. However you can do something like below as a workaround -

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Map<String, String> pathVariablesMap,
            HttpServletRequest request) {
    if (pathVariablesMap.containsKey("game")) {
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}

If you are using Spring 4.1 and Java 8 you can use java.util.Optional which is supported in @RequestParam, @PathVariable, @RequestHeader and @MatrixVariable in Spring MVC

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable Optional<String> game,
            HttpServletRequest request) {
    if (game.isPresent()) {
        //game.get()
        //corresponds to path "/simple/{game}"
    } else {
        //corresponds to path "/simple"
    }           
}
独孤求败 2024-11-03 15:44:10

你总是可以这样做:

@RequestMapping(value = "/simple", method = RequestMethod.GET)
public ModelAndView gameHandler(HttpServletRequest request) {
    gameHandler2(null, request)
}

@RequestMapping(value = "/simple/{game}", method = RequestMethod.GET)
public ModelAndView gameHandler2(@PathVariable("game") String game,
        HttpServletRequest request) {

You could always just do this:

@RequestMapping(value = "/simple", method = RequestMethod.GET)
public ModelAndView gameHandler(HttpServletRequest request) {
    gameHandler2(null, request)
}

@RequestMapping(value = "/simple/{game}", method = RequestMethod.GET)
public ModelAndView gameHandler2(@PathVariable("game") String game,
        HttpServletRequest request) {
嗳卜坏 2024-11-03 15:44:10
@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value="example",required = false) final String example)

尝试这个方法,它对我有用。

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value="example",required = false) final String example)

Try this approach, it worked for me.

赢得她心 2024-11-03 15:44:10

我刚刚测试了这个,但是通过结合上面的解决方案,我得到了这个:

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value = "game", required = false) String example,
                                HttpServletRequest request) {
    if (example != null) {
        //...
    } else {
        //pick first, ...
    }
}

现在,当您使用“/simple”时,字符串示例将为 null 而不是抛出异常。

简短的解决方案,没有花哨的可选<>或地图>>

I just tested this just now, but by combining the above solution i got this:

@RequestMapping(value = {"/simple", "/simple/{game}"}, method = RequestMethod.GET)
public ModelAndView gameHandler(@PathVariable(value = "game", required = false) String example,
                                HttpServletRequest request) {
    if (example != null) {
        //...
    } else {
        //pick first, ...
    }
}

Now when you use "/simple", String example will be null instead of throwing Exception.

Short solution, no fancy Optional<> or Map<>

花间憩 2024-11-03 15:44:10

我们可以在控制器中编写多个方法,并使用路径变量组合进行显式映射,以排除可选变量(如果使用旧版本的 Spring)

在我的场景中,想要开发一个 API 来获取旧设备的回收价值,其中参数可以是品牌、型号和网络,但是网络是一种选择。

处理此问题的一种选择是使用网络作为请求参数而不是 pathVariable。
例如 /value/LG/g3?network=vodafone 但我不喜欢这种方法。

对我来说,更干净的一个是使用下面的
/refurbValue/LG/g3
/refurbValue/LG/g3/vodafone

   @RequestMapping(value = "/refurbValue/{make}/{model}/{network}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
def getRefurbValueByMakeAndModelAndNetwork(@PathVariable String make, @PathVariable String model, @PathVariable String network ) throws Exception {
    //logic here
}

@RequestMapping(value = "/refurbValue/{make}/{model}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
def getRefurbValueByMakeAndModel(@PathVariable String make, @PathVariable String model) throws Exception {
    //logic here
}

在上面的示例中,两个控制器可以使用相同的服务方法,并且可以完成参数的处理。就我而言,我使用的是 Groovy,因此很容易与可选参数一起使用,例如

Map getRefurbValue(String Brand, String model, String network="")

We can write multiple methods in controllers with explicit mapping with the path variable combination to exclude the optional variables (if using old version of Spring)

In my scenario wanted to develop an API to get recycle value for old device where parameters could be brand, model and network however network is an option one.

One option to handle this was use network as a request parameter instead of pathVariable.
for e.g. /value/LG/g3?network=vodafone however I didn't like this approach.

for me the more cleaner one was to use below
/refurbValue/LG/g3
/refurbValue/LG/g3/vodafone

   @RequestMapping(value = "/refurbValue/{make}/{model}/{network}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
def getRefurbValueByMakeAndModelAndNetwork(@PathVariable String make, @PathVariable String model, @PathVariable String network ) throws Exception {
    //logic here
}

@RequestMapping(value = "/refurbValue/{make}/{model}", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
def getRefurbValueByMakeAndModel(@PathVariable String make, @PathVariable String model) throws Exception {
    //logic here
}

In the above example, both controller can use the same service method and handling of the parameter can be done. In my case I was using Groovy so it was easy to use with optional parameter like

Map getRefurbValue(String brand, String model, String network="")

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文