[英]@RequestParam in Spring MVC handling optional parameters
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 {...}
不接受带有“注销”的 HTTP 请求。
如果我定义两个控制器来分别处理每个请求,Spring 会抱怨“已经有'控制器' bean 方法......映射”。
在 Java 8 和 Spring 5 之前(但也适用于 Java 8+ 和 Spring 5+)
您还需要为name
和password
请求参数提供required = false
。 这是因为,当您仅提供logout
参数时,它实际上需要name
和password
,因为它们仍然是“隐式”强制的。
当您只提供name
和password
时它就起作用了,因为logout
不是强制性参数,这要归功于logout
已经给出了required = false
。
Java 8 和 Spring 5(及更高版本)的更新
从 Java 8 开始,您现在可以使用Optional类来使参数成为可选参数。
@RequestMapping (value = "/path", method = RequestMethod.GET)
public String handleRequest(@RequestParam("paramName") Optional<String> variableName) {
String paramValue = variableName.orElse("");
// use the paramValue
}
作为Spring 4.1.1
的一部分,您现在可以完全支持 Java 8 Optional
( original ticket ),因此在您的示例中,只要您将required=false
替换为 Optional 以进行 3 参数注销,两个请求都将通过您的单个映射端点,姓名、密码:
@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 {...}
创建 2 个处理案例的方法。 您可以指示@RequestMapping
注释在映射请求时考虑某些参数。 这样你就可以很好地把它分成两种方法。
@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 {...}
如果有人正在寻找使用Pojo
映射可选参数,也可以像下面这样进行。
@RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,
produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
LoginRequest loginRequest,
@ModelAttribute("submitModel") SubmitModel model,
BindingResult errors) throws LoginException {...}
@Data
@NoArgsConstructor
//@AllArgsConstructor - Don't use this
public class LoginRequest {
private Optional<String> logout = Optional.empty();
private Optional<String> username = Optional.empty();
private Optional<String> password = Optional.empty();
}
注意:不要在POJO
上使用@AllArgsConstructor
,否则它会将字段初始化为空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.