繁体   English   中英

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

[英]@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+)

您还需要为namepassword请求参数提供required = false 这是因为,当您仅提供logout参数时,它实际上需要namepassword ,因为它们仍然是“隐式”强制的。

当您只提供namepassword时它就起作用了,因为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM