springboot+mybatis拦截器不生效问题分析
【springboot+mybatis拦截器不生效问题分析】一、环境信息
SpringBoot:2.3.6.RELEASE
Mybatis-plus:3.3.1
二、碰到问题
今天因业务系统功能需要,使用mybatis的拦截器对ORACLE的数据库会话进行用户当前语言环境设置(NLS_LANGUAGE),碰到拦截器代码不生效的问题,特此记录下来,方便将来查阅。
三、代码如下:
1、在Mybatis的@Configuration相关代码添加如下代码(自动注入到拦截器链):
/**
* 更改会话状态
*
* @return
*/
@Bean
public AlterSessionInterceptor alterSessionInterceptor() {
return new AlterSessionInterceptor();
}
2、拦截器代码(拦截StatementHandler的prepare方法,取到Connection执行ALTER SESSION的语句):
/**
- 更改会话解析器
*- @since 2021/7/14
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class AlterSessionInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
Connection connection = (Connection) args[0];
if ("Oracle".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) {
Statement statement = null;
try {
statement = connection.createStatement();
String locale = RequestHelper.getCurrentLocale();
if ("en_GB".equalsIgnoreCase(locale)) {
statement.execute("ALTER SESSION SET NLS_LANGUAGE='AMERICAN'");
} else {
statement.execute("ALTER SESSION SET NLS_LANGUAGE='SIMPLIFIED CHINESE'");
}
} finally {
statement.close();
}
}
return invocation.proceed();
}
}
在运行调试时发现代码无法执行到拦截逻辑,经过参考分页插件代码,发现需要重载以下方法(代码默认是只要实现intercept这个接口,但是实际上需要多加以下插件的处理逻辑才可以,才会启用Plugin的Proxy):
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
}
return target;
}
最终拦截器代码如下:
/**
- 更改会话解析器
*- @since 2021/7/14
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class AlterSessionInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
Connection connection = (Connection) args[0];
if ("Oracle".equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) {
Statement statement = null;
try {
statement = connection.createStatement();
String locale = RequestHelper.getCurrentLocale();
if ("en_GB".equalsIgnoreCase(locale)) {
statement.execute("ALTER SESSION SET NLS_LANGUAGE='AMERICAN'");
} else {
statement.execute("ALTER SESSION SET NLS_LANGUAGE='SIMPLIFIED CHINESE'");
}
} finally {
statement.close();
}
}
return invocation.proceed();
}@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
}
return target;
}@Override
public void setProperties(Properties properties) {
// to do nothing
}
}
推荐阅读
- 微信域名防封|微信域名防封 微信域名拦截检测技术
- 小说域名怎么才能在微信中正常访问而不被微信拦截(366tool免费提供小说防封方案)
- 解决mybatis拦截器无法注入spring|解决mybatis拦截器无法注入spring bean的问题
- SSM项目使用拦截器实现登录验证功能
- nuxt 路由拦截
- Android|Android 拦截TextView中超链接点击事件
- Layout拦截点击事件
- 【CSS Weekly #486】CSS中 :has() 选择器不仅仅是一个“父选择器”
- Springboot+Mybatis+redis实现二级缓存
- 系统数据隔离|根据mybatis 拦截器实现项目业务数据隔离