当我们在使用mybatis做模糊查询时,有两个特殊符号需要注意:
%(百分号):相当于任意多个字符;
_(下划线):相当于任意的单个字符;
解决方案就是将特殊符号加转义字符
public static String escapeChar(String string) {
if (StringUtils.isNotBlank(string)) {
string = string.replaceAll("_", "/_");
string = string.replaceAll("%", "/%");
}
return string.trim();
}
将传进来的参数做替换。
这里表示我们转义字符是/,也可以自定义其它符号,匹配上即可。
现在虽然解决的查询问题,但是每个方法我们都要都要根据不同的字段做相应处理,要是方法或者字段多的话就非常麻烦,所以我想着用过滤器来解决问题,在传进来的参数和字段做匹配后自动转义。
自定义ParameterRequestWrapper继承HttpServletRequestWrapper,获取请求参数和做参数替换。
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<>();
public ParameterRequestWrapper(HttpServletRequest request) {
// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
super(request);
//将参数表,赋予给当前的Map以便于持有request中的参数
this.params.putAll(request.getParameterMap());
}
public ParameterRequestWrapper(HttpServletRequest request, Map<String, Object> extendParams) {
this(request);
addAllParameters(extendParams);
}
public Map<String, String[]> getParameterMap() {
return params;
}
public Enumeration getParameterNames() {
Vector l = new Vector(params.keySet());
return l.elements();
}
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
public String[] getParameterValues(String name) {
return params.get(name);
}
public void addAllParameters(Map<String, Object> otherParams) {
for (Map.Entry<String, Object> entry : otherParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}
public void addParameter(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)});
}
}
}
public void removeParameter(String name) {
if (params.get(name) != null) {
params.remove(name);
}
}
}
自定义过滤器SpecialSymbolsFilter 继承 OncePerRequestFilter
@Component
@WebFilter(filterName = "handleFilter", urlPatterns = "/*")
public class SpecialSymbolsFilter extends OncePerRequestFilter {
/**
* 特殊符号
*/
private static final String[] SPECIAL_SYMBOLS = {"%", "_"};
/**
* 过滤的字段
*/
private static final String[] FILTER_FIELDS = {"name","equipName","stationName"};
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
ParameterRequestWrapper parameterRequestWrapper = new ParameterRequestWrapper(request);
for (String filterField : FILTER_FIELDS) {
for (String specialSymbol : SPECIAL_SYMBOLS) {
String parameter = parameterRequestWrapper.getParameter(filterField);
if (StringUtils.isNotNull(parameter)) {
if (parameter.contains(specialSymbol)) {
parameterRequestWrapper.addParameter(filterField, escapeChar(parameter));
}
}
}
}
filterChain.doFilter(parameterRequestWrapper, response);
}
public static String escapeChar(String string) {
if (StringUtils.isNotBlank(string)) {
string = string.replaceAll("_", "/_");
string = string.replaceAll("%", "/%");
}
return string.trim();
}
}