sql语句模糊查询单引号问题,及jquery方法扩展,struts2拦截器

    xiaoxiao2022-06-30  105

    在sql语句中使用单引号模糊查询可能报错,例如:查询的单引号与%%两端的单引号匹配了形成断句,从而导致查询失败。所以要将单引号转义,变成两个单引号 '' 就行了。 SELECT * from ft_providers WHERE last_name like '%'%'; //报错 SELECT * from ft_providers WHERE last_name like '%''%'; //正确 那么在前端或者java里面就要将查询字符串进行替换,java里面比较简单,有replaceAll( )方法。但是js中没有,则可以用正则表达式来全局替换。 var account = $("#query_account").val().replace(new RegExp("'","gm"),"''"); //将单引号变成两个单引号,防止数据库模糊查询出错 g:表示全局匹配 m表示执行多行匹配 我们也可以编写String对象的原型方法,来添加一个replaceAll()方法: String.prototype.replaceAll = function(s1,s2){ return this.replace(new RegExp(s1,"gm"),s2); } str.replaceAll("'","''"); //使用自定义替换全局 在js语句中,当很多页面很多模糊查询的条件时,都要运用上面的方法进行一遍替换操作,很麻烦。 function queryDataInfo(){ $('#datagrid').datagrid('load',{ 'vo.account': $("#query_account").val().replaceAll("'","''"), 'vo.storeId': $("#query_storeId").val().replaceAll("'","''"), 'vo.isAble': $("#query_isAble").combobox('getValue') }); $("#query_dialog").dialog('close'); } 既然都是通过val()方法取值然后替换,则干脆扩展val()方法直接全部替换: 可能出现问题: 当取值中确实有单引号,而我们并不需要去进行模糊查询操作,则可能获取的值与传递的值不一致。所有这样扩展只能用于本例中用于模糊查询,一般form表单也不用一个一个取值去传递,所以这权当是一次学习扩展方法,以后有想满足自己什么功能自己再修改就是了。 //一定要写在这里面,不然会报错 $(function(){ /** * 修改Jquery的val() 方法,进行全局替换' 为'' * 用于在sql模糊查询中,一个单引号会对sql语句造成影响,两个单引号则形成转义作用 * @param options * @returns */ (function ($) { //形成一个闭包 var originalVal = $.fn.val; //获取原val方法 $.fn.val = function(value) { if (arguments.length >= 1) { //判断是否传入参数,来判断是赋值还是取值 return originalVal.call(this, value); //赋值的话则执行原方法 } var r = originalVal.call(this); //执行原方法 return r.replace(new RegExp("'","gm"),"''"); //扩展:一个单引号变成两个单引号 }; })(jQuery); }); 上面是将Jquery原型val方法处理了,但是难免会在某些地方出现不可预知的问题。怎么办?其实这种,逻辑更愿意放在后台代码处理,而不是前台。所以查阅了相关资料,可以利用拦截器或者过滤器来处理字段。 我们来简单区分一下这两者的区别:       过滤器:能过滤所有的请求, 依赖与servlet容器,基于回调函数,不能获取值。       拦截器 : 只拦截Action请求,基于java的反射机制,能够获取值栈的值。能够多次调用。      所以,要满足我们的需求,需要处理参数值,所以使用拦截器再好不过了。而过滤器则不能实现功能。如下为参数值方法拦截器实现,并在方法中处理单引号为双单引号。 import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; /** * 查询值拦截器 * 用于sql语句模糊查询时,关于单引号查询进而在此转义 * @author aggerChen * */ public class QueryValueInterceptor extends MethodFilterInterceptor { @SuppressWarnings("rawtypes") @Override protected String doIntercept(ActionInvocation invocation) throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); //获取请求 String type = request.getHeader("X-Requested-With"); //获取请求头 if(type == null) return invocation.invoke(); //type为null则表示非ajax请求。本项目查询方式都是ajax请求的,所以在此来排除一些其他的请求,比如表单 Map<String,String[]> map = request.getParameterMap(); //获取请求中所有的参数map Iterator it = map.entrySet().iterator(); //迭代 while (it.hasNext()) { Entry entry = (Entry) it.next(); String key = (String) entry.getKey(); String[] values = (String[]) entry.getValue(); if(key.indexOf("vo.")!=-1){ //判断是否是对象传参,vo.xxx 则为查询请求 if(!"".equals(values[0])){ values[0] = values[0].replaceAll("'", "''"); //将一个单引号处理为两个单引号 } } } return invocation.invoke(); } } 在struts.xml中配置拦截器。此示例只展示过滤器相关配置。 将默认拦截器设置为loginAndroleInterceptor拦截器栈,此栈中先进入roleInterceptor拦截器,再引入loginStack拦截器栈。loginStack栈中先经过登录拦截器,在经过本例自定义的查询条件拦截器,最后经过struts默认拦截器。 struts默认拦截器一定是在自定义拦截器最后再经过的。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 引入默认拦截器 --> <include file="struts-default.xml" /> <package name="base-packege" extends="struts-default"> <interceptors> <!-- 登陆拦截器 --> <interceptor name="loginInterceptor" class="com.fortis.cms.interceptor.LoginInterceptor"></interceptor> <!-- 角色拦截器 --> <interceptor name="roleInterceptor" class="com.fortis.cms.interceptor.RoleInterceptor"></interceptor> <!-- 查询条件值拦截器 本例自定义拦截器--> <interceptor name="queryValueInterceptor" class="com.fortis.cms.interceptor.QueryValueInterceptor"></interceptor> <!--登录拦截器栈 --> <interceptor-stack name="loginStack"> <interceptor-ref name="loginInterceptor"> <param name="excludeMethods">login,notNeedRoleForwardLogin</param> </interceptor-ref> <interceptor-ref name="queryValueInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> <!--登录和角色拦截器栈 --> <interceptor-stack name="loginAndroleInterceptor"> <interceptor-ref name="roleInterceptor"> <param name="excludeMethods">login,notNeedRole*,queryMenuTree</param> </interceptor-ref> <interceptor-ref name="loginStack" /> </interceptor-stack> </interceptors> <!--设置默认拦截器栈 --> <default-interceptor-ref name="loginAndroleInterceptor"></default-interceptor-ref> </package> </struts> 总结:这是在项目中遇到的问题,这也是我解决的思路历程,暂时没报错了,不过其他地方调用val()有没有问题还没有一一去验证,权当是一次联系重写方法了。拦截器处理的话,应该是不会出错了。
    转载请注明原文地址: https://ju.6miu.com/read-1126284.html

    最新回复(0)