最近换了新工作,改bug作为熟悉业务及代码的快速途径,是每个新人都要经历的
代码不难,难的是业务不熟,很多地方不知道为什么要这么写。当然,时间久了就好了
这次要找的bug是排序问题,前端请求接口,按某个字段排序后,返回的结果总是很怪异,数据最多的那个总是与排序要求相反。
比如升序排序,他会跑到最后一页的最后一条
降序排序会跑到第一条
捋代码发现他的排序逻辑如下:
请求参数:orderBy=validCount&sortType=desc¤tPage=1
//controller封装参数调用service的查询
//service查询出全部,进行排序后,根据分页参数进行逻辑分页
Collections.sort(listIntelSourceListVos);
return new Pager<>(currentPage, pageSize, listIntelSourceListVos);
这个list中存放的类定义如下:
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class IntelSourceListVo extends ComparableImpl<IntelSourceListVo> {
private int sourceId;
private String sourceName;
private int sourceType;
private String intelType;
private String intelUri;
private long validCount;
private long totalCount;
private String createtime;
private String lastEnteringTime;
private int status;
private int weight;
private Integer isStart;
}
它实现的comparableImpl为一个自定义的排序类,实现这个排序类的类可以根据类中的sortType来进行排序,orderBy进行升序与降序的控制。其中用到了一些简单的反射。
package cn.threatbook.tim.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
@Setter
@Getter
@NoArgsConstructor
public class ComparableImpl<T> implements Comparable<T> {
@JsonIgnore
String sortType;
@JsonIgnore
String orderBy;
@Override
public int compareTo(T that) {
if (orderBy == null) {
return 0;
}
int order = -1;
if ("desc".equals(sortType)) {
order = 1;
}
try {
Class clazz = that.getClass();
Field field = clazz.getDeclaredField(orderBy);
field.setAccessible(true);
Object thisValue = field.get(this);
Object thatValue = field.get(that);
String valueType = field.getType().toString();
if (valueType.endsWith("String")) {
String thisValueStr = (String) thisValue;
String thatValueStr = (String) thatValue;
if (StringUtils.isEmpty(thisValueStr)
&& StringUtils.isEmpty(thatValueStr)) {
return 0;
} else if (StringUtils.isEmpty(thisValueStr)) {
return order;
} else if (StringUtils.isEmpty(thatValueStr)) {
return -order;
}
return -thisValueStr.compareTo(thatValueStr) * order;
} else if (valueType.endsWith("long") || valueType.endsWith("Long")) {
//bug出现处
long thisValueLong = (long) thisValue;
long thatValueStr = (long) thatValue;//这随意的变量命名....
return (int) (thatValueStr - thisValueLong) * order;
} else if (valueType.endsWith("int") || valueType.endsWith("Integer")) {
int thisValueLong = (int) thisValue;
int thatValueStr = (int) thatValue;
return (thatValueStr - thisValueLong) * order;
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
由于请求参数orderBy=validCount&sortType=desc¤tPage=1 中指定了的排序字段是validCount
且该实体类的validCount字段为long类型,可知排序肯定在long类型比较的代码块中进行。
断点debug到long类型进行比较的部分 发现了该bug产生的原因。主要原因是当两个值进行相减后
比如2822920460-1 结果依旧大于Integer.MAX_VALUE ,在进行int强转后,返回的结果不准确。
public static void main(String[] args) {
long l = -2822920460L;
System.out.println((int) l);
l = 2822920460L;
System.out.println((int) l);
}
输出的结果为:
可以看到符号正好是相反的。
将代码进行修改后 完成。
今天又修好了一个bug 也少了几根头发