在Spring中,如果在方法参数列表中使用@RequestParam标注多个参数,会让映射方法的可读性大大降低。
如果映射请求的参数只有一两个的话,使用@RequestParam会非常直观,但是如果参数列表越来越长,就很容易晕菜。
解决方案:
可以直接使用ParameterObject模式来处理【注:ParameterObject就是把参数组装成对象】。
如果要传参对数据库操作,则参数对应数据库中的某些字段,此时表对应的entity对象可以直接作为ParameterObject。
其他情况下则可以使用一个POJO来包装这些参数,这个POJO本身没有要求额外的注解,但是POJO本身必须包含和请求参数完全匹配的字段,标准的setter/getter,和一个无参的构造器:
class ProductCriteria { private String query; private int offset; private int limit; ProductCriteria() { } public String getQuery() { return query; } public void setQuery(String query) { this.query = query; } // other getters/setters } @GetMapping List<Product> searchProducts(ProductCriteria productCriteria) { return productRepository.search(productCriteria); }
在POJO中对请求参数进行校验
虽然上面的案例已经可以正常使用,但是我们知道,使用@RequestParam注解,不仅仅只是为了绑定请求参数,一个非常重要的功能是,我们可以对绑定的参数请求验证,比如参数是否必要,如果请求中缺少该参数,则我们的服务端可以拒绝该请求。
想为我们的POJO中的字段添加验证规则。如果想模仿@RequestParam(required = false)的表现,可以使用@NotNull注解在对应的字段上即可。
在更多的情况下,我们一般使用@NotBlank多于@NotNull,因为@NotBlank考虑了空字符串的情况。
final class ProductCriteria { @NotBlank private String query; @Min(0) private int offset; @Min(1) private int limi; // ... }
这里务必注意一点:
仅仅只是在对象的字段上添加验证注解是不够的。
一定要在controller的方法参数里诶包中,在POJO对应的参数前加上@Valid注解。该注解会让Spring在绑定参数前执行校验动作。
@GetMapping List<Product> searchProducts(@Valid ProductCriteria productCriteria) { // ... }
@RequestParam注解的另一个非常有用的功能就是设置参数的默认值。
如果我们使用POJO的方式来绑定参数,只需要在定义参数的时候设置好字段的默认值就行了。如果请求中没有该参数,Spring不会把参数的默认值覆盖为null的。