一、背景
在做管理后臺頁面查詢皂甘,我們經(jīng)常會遇到多條件查詢的情況玻驻,而且每個(gè)條件字段,對應(yīng)的value值類型也可能不同偿枕, 可能是整型璧瞬,也可能是字符串類型,也可能是null渐夸。 總結(jié)下查詢傳入后端接口的值有 null, "", undefined嗤锉,正常的數(shù)字,正常的字符串捺萌。常規(guī)的做法档冬,會在每個(gè)查詢接口的入口處(正式做業(yè)務(wù)邏輯前)做參數(shù)校驗(yàn)膘茎,只接收預(yù)期的值。這樣實(shí)現(xiàn)起來酷誓,會發(fā)現(xiàn)一堆的if else披坏,如果查詢接口多的話,會看起來非常的臃腫盐数。
二棒拂、如何優(yōu)雅實(shí)現(xiàn)處理
我們知道對客戶端請求過濾有兩種方式,如下:
過濾器Filter: 類級別玫氢,粒度較粗
攔截器intecepter: 方法級別帚屉, 粒度較細(xì)
由于針對的是所有類接口,選用過濾器進(jìn)行粗粒度參數(shù)過濾即可漾峡。Filter可以過濾想要它過濾的每一個(gè)請求攻旦,在這請求中有HttpServletRequest、HttpServletResponse生逸, 我們知道服務(wù)器取得客戶端發(fā)送的參數(shù)都是通過HttpServletRequest來獲取的牢屋。 但遺憾的是HttpServletRequest沒有提供對應(yīng)的setParameter方法,允許修改客戶端發(fā)送過來的值槽袄。因此我們需要自定義HttpServletRequestWrapper來包裝一下當(dāng)前HttpServletRequest請求烙无, 自定義HttpServletRequestWrapper的提供可修改客戶端值的setParameter方法。
/**
*
*自定義HttpServletRequestWrapper
*/
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;
public class MyHttpServletRequestWapper extends HttpServletRequestWrapper {
/**
* 用于存儲請求參數(shù)
*/
private Map<String , String[]> params = new HashMap<String, String[]>();
/**
* 包裝一下當(dāng)前請求
* @param request
* @throws IllegalArgumentException if the request is null
*/
public MyHttpServletRequestWapper(HttpServletRequest request) {
super(request);
// 把請求參數(shù)添加到我們自己的map當(dāng)中
this.params.putAll(request.getParameterMap());
}
/**
* 添加參數(shù)到map中
* @param name
* @param value
*/
public void setParameter(String name, Object value) {
if (value != null) {
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}
/**
* 重寫getParameter遍尺,代表參數(shù)從當(dāng)前類中的map獲取
* @param name
* @return
*/
@Override
public String getParameter(String name) {
String[]values = params.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* 重寫getParameterValues方法截酷,從當(dāng)前類的 map中取值
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
}
/**
*
* 不合法參數(shù)過濾器
*/
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class InvalidParamFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(InvalidParamFilter.class)
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
/**
* 參數(shù)預(yù)處理
* @param request
* @param response
* @param chain
* @throws IOException
* @throws ServletException
*/
@SuppressWarnings("unchecked")
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//包裝一下請求
MyHttpServletRequestWapper requestWrapper = new MyHttpServletRequestWapper(
(HttpServletRequest) request);
//獲取原始請求參數(shù)
Map<String, String[]> paramterMap = requestWrapper.getParameterMap();
//預(yù)處理原始請求參數(shù)
for(Map.Entry<String, String[]> entry : paramterMap.entrySet()){
String[] values = entry.getValue();
//1、只處理單個(gè)參數(shù)
if(values.length !=1){
continue;
}
if(Objects.isNull(values[0]) || StringUtils.isBlank(values[0]) || values[0].equals("undefined")) {
//2乾戏、把處理后的參數(shù)放回去迂苛, null、""歧蕉、undefined等輸入?yún)?shù)值統(tǒng)一轉(zhuǎn)換為字符串"0"
requestWrapper.setParameter(entry.getKey(), "0");
}
}
// 3灾部、放行,把我們的requestWrapper放到方法當(dāng)中
chain.doFilter(requestWrapper, response);
}
@Override
public void destroy() {}
}