背景:
由ExtJs7.X grid使用filter插件进行remote过滤的时候,传递了不少filter条件参数,本文基于参数进行解析,并封装为注解。
源码:
1、Ext filter 参数实体相关类:
@Data
public class FilterParam {
protected String operator;
protected String property;
private Object value;
}
@Data
public class FilterArrayRaw extends FilterParam {
private List<String> value;
public FilterArrayRaw() {
}
public FilterArrayRaw(JSONObject jo) {
this.operator = jo.getStr("operator");
this.property = jo.getStr("property");
this.value = jo.getJSONArray("value").toList(String.class);
}
}
@Data
public class FilterNumberRaw extends FilterParam {
private Double value;
public FilterNumberRaw() {
}
public FilterNumberRaw(JSONObject jo) {
this.operator = jo.getStr("operator");
this.property = jo.getStr("property");
this.value = jo.get("value", Double.class);
}
}
@Data
public class FilterStringRaw extends FilterParam {
private String value;
public FilterStringRaw() {
}
public FilterStringRaw(JSONObject jo) {
this.operator = jo.getStr("operator");
this.property = jo.getStr("property");
this.value = jo.get("value", String.class);
}
}
基于ExtJs Filter的主要数据类型进行实体类定义。
2、注解定义,用于解析前端传递的grid filter参数
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface GridFilterParam {
/**
* 参数名称
*
* @return 参数名称
*/
String name() default "";
/**
* 默认无需必传
*
* @return boolean
*/
boolean required() default false;
}
3、注解解析,继承自 HandlerMethodArgumentResolver 类
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import org.codia.admin.annotation.GridFilterParam;
import xxx.xxx.filter.FilterArrayRaw;
import xxx.xxx.filter.FilterNumberRaw;
import xxx.xxx.filter.FilterParam;
import xxx.xxx.filter.FilterStringRaw;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@Component
public class GridFilterResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(GridFilterParam.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//得到 GridFilterParam 注解信息并将其转换成用来记录注解信息的 JSONRequestParamNamedValueInfo 对象
GridFilterParam jsonRequestParam = parameter.getParameterAnnotation(GridFilterParam.class);
JSONRequestParamNamedValueInfo namedValueInfo = new JSONRequestParamNamedValueInfo(jsonRequestParam.name(), jsonRequestParam.required());
if (namedValueInfo.name.isEmpty()) {
namedValueInfo.name = parameter.getParameterName();
if (namedValueInfo.name == null) {
throw new IllegalArgumentException(
"Name for argument type [" + parameter.getNestedParameterType().getName() +
"] not available, and parameter name information not found in class file either.");
}
}
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
//获得对应的 value 的 JSON 字符串
String jsonText = servletRequest.getParameter(namedValueInfo.name);
if (StrUtil.isNotEmpty(jsonText)) {
//得到参数的 Class
// Class clazz = parameter.getParameterType();
//
// //使用 Jackson 将 JSON 字符串转换成我们想要的对象类
// ObjectMapper mapper = new ObjectMapper();
// Object value = mapper.readValue(jsonText, clazz);
JSONArray result = new JSONArray(jsonText);
List<FilterParam> params = new ArrayList<>(result.size());
result.forEach(raw -> {
JSONObject jo = new JSONObject(raw);
String operator = jo.getStr("operator");
if (StrUtil.isNotEmpty(operator)) {
switch (operator) {
case "in":
case "notin": {
//array
params.add(new FilterArrayRaw(jo));
break;
}
case "like": {
//string
params.add(new FilterStringRaw(jo));
break;
}
case "<":
case "<=":
case "==":
case ">":
case ">=":
case "!=":
default: {
//number
params.add(new FilterNumberRaw(jo));
}
}
}
});
return params;
}
return null;
}
private static class JSONRequestParamNamedValueInfo {
private String name;
private boolean required;
public JSONRequestParamNamedValueInfo(String name, boolean required) {
this.name = name;
this.required = required;
}
}
}
利用Spring框架进行参数解析,完成filter参数条件封装。
效果:
参考: ExtJs 7.X grid filter remote 自定义查询字段别名_sword_happy的博客-CSDN博客