【MyBatis】防止sql注入
前言
关于sql注入的解释这里不再赘述。 在MyBatis中防止的sql注入主要分为两种: 第一种就是MyBatis提供了两种支持动态 sql 的语法 #{} 和 ${},其中${} 是简单的字符串替换,而 #{} 在预处理时,会把参数部分用一个占位符 ? 代替,可以有效的防止sql的注入,面试的时候经常会问到,这里也不再详细赘述; 第二种是排序防止sql注入,实现方案如下
SQL注入过滤器
以下是sql注入过滤器,当判断出是非法字符时则抛出到自定义的异常类BusinessException中
public class SQLFilter { /** * SQL注入过滤 * * @param sql 待验证字符串 */ public static String filterInject(String sql) { if (StringUtils.isBlank(sql)) { return null; } //去掉|"|;|字符 sql = sql.replace("", "") .replace(""", "") .replace(";", "") .replace("\", "") .toLowerCase(); //非法字符 final String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"}; //判断是否包含非法字符 for (String keyword : keywords) { if (sql.indexOf(keyword) > 0) { throw new BusinessException("SQL包含非法字符"); } } return sql; } }
分页工具类
这里我们使用的是PageHelper组件实现分页,需要在pom中引用jar包【com.github.pagehelper】
public class PageUtils { public static void initPaging(Map<String, Object> params) { //分页参数 Object pageNumObj = params.get("page"); Object pageSizeObj = params.get("limit"); Object sortNameObj = params.get("sortName"); Object sortOrderObj = params.get("sortOrder"); //默认分页数为1 int pageNum = pageNumObj != null ? Integer.parseInt(pageNumObj.toString()) : 1; //默认每页大小为10 int pageSize = pageSizeObj != null ? Integer.parseInt(pageSizeObj.toString()) : 10; String orderBy = ""; if (sortNameObj != null && sortOrderObj != null) { orderBy = sortNameObj.toString() + " " + sortOrderObj.toString(); } PageHelper.startPage(pageNum, pageSize, SQLFilter.filterInject(orderBy)); } public static Map<String, Object> filterParams(Map<String, Object> params) { Object sortNameObj = params.get("sortName"); Object sortOrderObj = params.get("sortOrder"); String orderBy = ""; if (sortNameObj != null && sortOrderObj != null) { orderBy = sortNameObj.toString() + " " + sortOrderObj.toString(); } params.put("orderBy",SQLFilter.filterInject(orderBy)); return params; } }
分页公共参数实体
@Data public abstract class Query { // 初始分页页码 private Integer page = 1; // 初始分页条数 private Integer limit = 10; // 初始排序字段; sortName = "id" private String sortName; // 初始排序方式; sortOrder = "asc" private String sortOrder; }
实现分页
实现方法中,【SysUserQuery 】中是我的业务逻辑中的查询参数,但是继承了分页公共参数实体,这里就不列出来了;
分页工具类中的方法由Map接收,由于我这里传的是实体,所以多出来一步实体转成Map操作;
@Override public Result queryPage(SysUserQuery sysUserQuery) { Map<String, Object> params = JSON.parseObject(JSON.toJSONString(sysUserQuery), Map.class); // 分页 PageUtils.initPaging(params); // 查询数据 List<SysUserVo> list = sysUserMapper.selectListByQuery(sysUserQuery); PageInfo page = new PageInfo(list); return new Result(page); }
至此结束。
上一篇:
Java架构师技术进阶路线图
下一篇:
如何实现一个可靠的 UDP