一、mybatis--拦截器--Interceptor
1、应用场景:对特定SQL语句-赋值权限操作。
例如:对于有自定义注解权限的查询。做限制
2、自定义MyDataInterceptor 实现Interceptor接口
3、添加@Intercepts注解。标识该类为拦截类。
4、自定义注解
5、代码
原理:利用反射得到类和注解。给符合特定注解的方法。修改原SQL。构建新SQL
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MyDataInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement statement = (MappedStatement) args[0];
System.out.println("进入拦截");
Method method = invocation.getMethod();
System.out.println("方法为" + method.getName());
String id = statement.getId();
String substring = id.substring(0, id.lastIndexOf("."));
String substring1 = id.substring(id.lastIndexOf(".") + 1);
Class<?> aClass = Class.forName(substring);
boolean flag = false;
Method[] declaredMethods = aClass.getDeclaredMethods();
String myAnnotation = null;
for (Method declaredMethod : declaredMethods) {
Annotation[] declaredAnnotations = declaredMethod.getDeclaredAnnotations();
for (Annotation declaredAnnotation : declaredAnnotations) {
System.out.println(declaredAnnotation.annotationType().getTypeName());
//TODO 可以做到数据库配置。也可以写枚举类
if ("com.mybatisplus.config.MyAnnotation".equals(declaredAnnotation.annotationType().getTypeName())) {
MyAnnotation annotation = declaredMethod.getAnnotation(MyAnnotation.class);
StatusEnum[] statusEnums = annotation.value();
for (StatusEnum statusEnum : statusEnums) {
System.out.println(statusEnum.getAce());
}
flag = true;
}
System.out.println("注解为" + declaredAnnotation.annotationType().getSimpleName());
myAnnotation = declaredAnnotation.annotationType().getSimpleName();
}
}
Annotation[] annotations = method.getDeclaredAnnotations();
//MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
ParameterMap parameterMap = statement.getParameterMap();
SqlSource sqlSource = statement.getSqlSource();
BoundSql boundSql = statement.getBoundSql(args[1]);
String sql = boundSql.getSql();
if (flag) {
sql = sql + " and 1=0";
} else {
return invocation.proceed();
}
BoundSql boundSqlnew = new BoundSql(statement.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
BoundSqlSqlSource source = new BoundSqlSqlSource(boundSqlnew);
MappedStatement statement1 = newMappedStatement(statement, source);
Object[] queryArgs = invocation.getArgs();
queryArgs[0] = statement1;
Object target = invocation.getTarget();
return invocation.proceed();
}
/**
* 定义一个内部辅助类,作用是包装 SQL
*/
static class BoundSqlSqlSource implements SqlSource {
private final BoundSql boundSql;
public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}
@Override
public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}
private static MappedStatement newMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
/**
* Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType
*/
MappedStatement.Builder mst = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
mst.resource(ms.getResource());
mst.fetchSize(ms.getFetchSize());
mst.statementType(ms.getStatementType());
mst.keyGenerator(ms.getKeyGenerator());
if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
mst.keyProperty(ms.getKeyProperties()[0]);
}
mst.timeout(ms.getTimeout());
mst.parameterMap(ms.getParameterMap());
mst.resultMaps(ms.getResultMaps());
mst.resultSetType(ms.getResultSetType());
mst.cache(ms.getCache());
mst.flushCacheRequired(ms.isFlushCacheRequired());
mst.useCache(ms.isUseCache());
return mst.build();
}
//DbType.MYSQL
}
二、webMvc拦截器
1、应用场景登录拦截或者访问拦截。
2、自定义拦截类MyHandlerInterceptor实现HandlerInterceptor接口
3、自定义mvc配置类MyMvcConfig(添加@Configuration)实现WebMvcConfigurer接口。并实现
addInterceptors方法
4、代码:
原理:还是对原生的HttpServletRequest,HttpServletResponse进行处理
@Component
public class MyHandlerInterceptor implements HandlerInterceptor {
/**
* 前置处理器
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("我是前置处理器");
return true;
}
/**
* 执行器
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("我是业务后置处理器");
}
/**
* 后置处理器
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("我是后置处理器");
}
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Resource
private MyHandlerInterceptor interceptor;
/**
* 添加自定义拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("拦截所有");
registry.addInterceptor(interceptor).addPathPatterns("/*");
}
}
三、过滤器