Spring MVC中的@RequestParam处理可选参数

luk*_*mir 165 java spring spring-mvc

Spring控制器是否可以处理这两种请求?

1) http://localhost:8080/submit/id/ID123432?logout=true

2) http://localhost:8080/submit/id/ID123432?name=sam&password=543432

如果我定义了这种类型的单个控制器:

 @RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout", required = false) String logout,
                              @RequestParam("name") String username,
                              @RequestParam("password") String password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}
Run Code Online (Sandbox Code Playgroud)

不接受带有"注销"的HTTP请求.

如果我定义两个控制器来分别处理每个请求,Spring会抱怨异常"已经有'Controller'bean方法...已映射".

Sud*_*hul 207

你需要给required = falsename,并password请求参数也是如此.那是因为,当你只提供logout参数时,它实际上是期望的,name并且password它们仍然是强制性的.

当你刚给出时它起作用name,password因为已经给出了因为logout它不是一个强制参数.required = falselogout


dim*_*sli 156

作为Spring 4.1.1向前的一部分,您现在完全支持Java 8 Optional(原始票证),因此在您的示例中,只要您required=false使用Optional 替换3个params注销,名称,密码,两个请求都将通过您的单个映射端点:

@RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout") Optional<String> logout,
                              @RequestParam("name") Optional<String> username,
                              @RequestParam("password") Optional<String> password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}
Run Code Online (Sandbox Code Playgroud)

  • Intellij警告:'Optional <Long>'用作参数'requestedTimelineStart'的类型less ...(Strg + F1)检查信息:报告java.util.Optional <T>,java.util.OptionalDouble,java的任何用法. util.OptionalInt,java.util.OptionalLong或com.google.common.base.Optional作为字段或参数的类型.可选项旨在为库方法返回类型提供有限的机制,其中需要一种明确的方式来表示"无结果".如果类需要Serializable,而java.util.Optional不是,那么使用类型为java.util.Optional的字段也是有问题的. (8认同)
  • @PeMa 这是一个有争议的警告。我个人认为使用“Optional”作为参数而不是“null”检查更清晰。是的,参数本身可以为“null”,但返回的“Optional”值也可以为“null”。特别是在这种情况下,Spring 在将空参数包装在Optional中时在内部处理空参数。 (3认同)
  • @VibhavChaddha你可以使用这样的东西:if(idOfUser.isPresent()){System.out.println("idOfUser:"+ idOfUser.get()); } (2认同)
  • 我相信这应该是 Java 8 的新正确答案。 (2认同)

M. *_*num 38

创建2个处理案例的方法.您可以指示@RequestMapping注释在映射请求时考虑某些参数.这样你就可以很好地将它分成2种方法.

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"logout"})
public String handleLogout(@PathVariable("id") String id, 
        @RequestParam("logout") String logout) { ... }

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"name", "password"})
public String handleLogin(@PathVariable("id") String id, @RequestParam("name") 
        String username, @RequestParam("password") String password, 
        @ModelAttribute("submitModel") SubmitModel model, BindingResult errors) 
        throws LoginException {...}
Run Code Online (Sandbox Code Playgroud)

  • 它将找到最佳匹配,可能会尝试使用`handleLogin`,否则将给出一个异常,指出找不到映射。 (2认同)
  • 请注意,从安全角度来看,注销仅应接受POST请求,因此_should_有2种方法,那么保持其URL相同就没有任何意义。 (2认同)