All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kasinf.framework.rest.web.method.SearchableMethodArgumentResolver Maven / Gradle / Ivy

The newest version!
package com.kasinf.framework.rest.web.method;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.kasinf.framework.core.util.JsonUtils;
import com.kasinf.framework.rest.annotation.SearchableDefaults;
import com.kasinf.framework.rest.config.SearchableConfiguration;
import com.kasinf.framework.rest.support.SearchOperator;
import com.kasinf.framework.rest.support.Searchable;
import com.kasinf.framework.rest.support.filter.FilterSos;
import com.kasinf.framework.rest.support.filter.SearchFilter;
import com.kasinf.framework.rest.support.filter.SearchFilterHelper;
import com.kasinf.framework.rest.util.ProjectionUtils;
import com.kasinf.framework.rest.web.util.SearchableBeanUtils;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author lkhsh
 * 查询参数解析器
 * 

* 1.1、默认查询字符串 * search.baseInfo.realname_like=zhang * search.age_lt=12 * 排序及分页请参考 {@link PageableMethodArgumentResolver} *

* 1.2、分组查询字串,构造以下json数据 */ public class SearchableMethodArgumentResolver extends BaseMethodArgumentResolver { private final PageableMethodArgumentResolver pageableMethodArgumentResolver; private final String SEARCH_PREFIX; private final String BASE_PATH; public SearchableMethodArgumentResolver(PageableMethodArgumentResolver pageableMethodArgumentResolver, SearchableConfiguration config) { this.pageableMethodArgumentResolver = pageableMethodArgumentResolver; this.SEARCH_PREFIX = config.getSearchParamName(); this.BASE_PATH = config.getBaseUri().toString(); } @Override public boolean supportsParameter(MethodParameter parameter) { return Searchable.class.isAssignableFrom(parameter.getParameterType()); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Map searchableMap = getPrefixParameterMap(SEARCH_PREFIX, webRequest, true); boolean notCustomSearchFilter = searchableMap.size() == 0; SearchableDefaults searchDefaults = getSearchableDefaults(parameter); boolean needMergeDefault = searchDefaults != null && searchDefaults.merge(); Searchable searchable = Searchable.of(); // 获取投影名称 String projectionName = webRequest.getParameter("projection"); if (StrUtil.isNotEmpty(projectionName)) { String requestUri = ((ServletWebRequest) webRequest).getRequest().getRequestURI(); String contentPath = webRequest.getContextPath(); String mapping = requestUri.replace(contentPath + BASE_PATH + "/", ""); Class projection = ProjectionUtils.getProjectionType(SearchableBeanUtils.getEntity(mapping), projectionName); if (projection != null) { searchable.setProjection(projection); } } //自定义覆盖默认 if (needMergeDefault || notCustomSearchFilter) { defaultSearchable(searchable, searchDefaults); } // 若带查询条件,组装条件 if (!notCustomSearchFilter) { boolean isComplex = searchableMap.containsKey("filterSos"); // 启用了复杂查询,需要转换JSON至实体对象 if (!isComplex) { // 字符串形式查询 for (String name : searchableMap.keySet()) { List mapValues = filterSearchValues(searchableMap.get(name)); if (mapValues.size() == 1) { // 处理日期格式的 if (name.endsWith("*date")) { name = name.replace("*date", ""); try { Date date = DateUtil.parseDate(mapValues.get(0)); searchable.addParam(name, date); continue; } catch (DateException ignore) { } } else if (name.endsWith("datetime")) { name = name.replace("*datetime", ""); try { Date date = DateUtil.parseDateTime(mapValues.get(0)); searchable.addParam(name, date); continue; } catch (DateException ignore) { } } searchable.addParam(name, mapValues.get(0)); } else { searchable.addParam(name, mapValues); } } } else if (searchableMap.get("filterSos")[0] != null) { List filterSosList = JsonUtils.nativeRead(searchableMap.get("filterSos")[0], new TypeReference>() { }); if (filterSosList != null) { Map filedType = null; if (searchableMap.containsKey("tableFilterType")) { filedType = JsonUtils.toMap(searchableMap.get("tableFilterType")[0], String.class, String.class); } SearchFilter searchFilter = changeFilterToSearchable(filterSosList, filedType); searchable.addFilter(searchFilter); } } } Pageable pageable = (Pageable) pageableMethodArgumentResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); //默认分页及排序 if (searchDefaults == null) { searchable.setPage(pageable); } //needPage=true 分页及排序 if (searchDefaults != null && searchDefaults.needPage()) { searchable.setPage(pageable); } //needPage=false needSort=true 不要分页,但排序 if (searchDefaults != null && !searchDefaults.needPage() && searchDefaults.needSort()) { searchable.addSort(Objects.requireNonNull(pageable).getSort()); } return searchable; } /** * 转换前台传过来的组合查询条件 * * @param filterSos 查询条件 * @param filedType 需要进行转换的字段 * @return 内部使用的查询条件 */ private SearchFilter changeFilterToSearchable(List filterSos, Map filedType) { SearchFilter searchFilter = null; for (FilterSos filter : filterSos) { SearchFilter condition; if (CollectionUtil.isNotEmpty(filter.getChildren())) { condition = changeFilterToSearchable(filter.getChildren(), filedType); } else { // 若没有进行分组,则生成查询条件,需要对value做类型的转换,主要是时间类型 Object value = filter.getValue(); // if (filedType != null && filedType.containsKey(filter.getField())) { // // 进行值的类型转换 // String valStr = filedType.get(filter.getField()); // value = getValue(value, filter.getType(), valStr); // } condition = SearchFilterHelper.newCondition(filter.getField(), filter.getType(), value); } if (searchFilter == null) { searchFilter = condition; } else { if ("and".equals(filter.getPrefix())) { searchFilter = SearchFilterHelper.and(searchFilter, condition); } else if ("or".equals(filter.getPrefix())) { searchFilter = SearchFilterHelper.or(searchFilter, condition); } } } return searchFilter; } /** * 转换date类型的值 * * @param value 接收到的日期字符串 * @param type: 操作类型 * @param format:格式化字符串 */ private Object getValue(Object value, SearchOperator type, String format) { // 暂时不需要类型转换的操作 return value; } private SearchableDefaults getSearchableDefaults(MethodParameter parameter) { //首先从参数上找 SearchableDefaults searchDefaults = parameter.getParameterAnnotation(SearchableDefaults.class); //找不到从方法上找 if (searchDefaults == null) { searchDefaults = parameter.getMethodAnnotation(SearchableDefaults.class); } return searchDefaults; } private void defaultSearchable(Searchable searchable, SearchableDefaults searchableDefaults) { if (searchableDefaults != null) { for (String searchParam : searchableDefaults.value()) { String[] searchPair = searchParam.split("="); String paramName = searchPair[0]; String paramValue = searchPair[1]; if (paramName.endsWith("in")) { searchable.addParam(paramName, paramValue.split(",")); } else { searchable.addParam(paramName, paramValue); } } // 没有传入projection参数,那么取默认的 if (!searchable.hasProjection()) { Class projection = searchableDefaults.projection(); searchable.setProjection(projection); } } } private List filterSearchValues(String[] values) { return Stream.of(values) .filter(StrUtil::isNotEmpty) .collect(Collectors.toList()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy