例子:分页例子(注意会有隐藏的坑(也就是set方法调用顺序))
HotelOrderInfoReq 中 set方法调用顺序
```
@RequestMapping(value = "/purchaser/list")
@ResponseBody
public JsonResult purchaserList(HotelOrderInfoReq qry)
HotelOrderInfoReq:继承自 PageParameter
HotelOrderInfoReq 定义如下:
@Data
public class HotelOrderInfoReq extends PageParameter {
PageParameter定义如下:
public class PageParameter implements Serializable{
private int start;
private int limit = 20;
private int page = 1;
private int pageSize ;
public void setPage(int page) {
this.page = page;
this.start = (this.page - 1) * this.limit;
}
public void setPageSize(int pageSize){
this.pageSize = pageSize;
this.limit = pageSize;
}
}
```
当 page = 2,pageSize = 10
预期 start= 10
实际: start = 20((2-1)*20)
分析原因:
spring 的 WebUtils在构造请求的对象 HotelOrderInfoReq 的时候 会先获取请求的参数并把参数封装到TreeMap中,源码如下:
public static Map<String, Object> getParametersStartingWith(ServletRequest request, @Nullable String prefix) {
Assert.notNull(request, "Request must not be null");
Enumeration<String> paramNames = request.getParameterNames();
Map<String, Object> params = new TreeMap();
if (prefix == null) {
prefix = "";
}
while(paramNames != null && paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
if (prefix.isEmpty() || paramName.startsWith(prefix)) {
String unprefixed = paramName.substring(prefix.length());
String[] values = request.getParameterValues(paramName);
if (values != null && values.length != 0) {
if (values.length > 1) {
params.put(unprefixed, values);
} else {
params.put(unprefixed, values[0]);
}
}
}
}
return params;
}
也就是会把请求参数按照 属性名字典序排序,在遍历调用 set的方法
page 排在 pageSize 前面,因此先调用 setPage方法
得到 start = (2 - 1 )* 20
在调用 setPageSize ,因此造成了分页错误
总结如下:
springmvc中web层对象 实例化中 属性初始化顺序 是按照属性名字典序排序顺序初始化