java - 相同的方法,看似相同的String字符串输入,不同的结果
问题描述
我正在开发一个具有多租户的应用程序(java/spring 的新手),试图用不同的用户连接到不同的数据库。对 java.lang.String 类有一些奇怪的经历
将字符串字符串用作@PathVariable 时,它正在工作 - 方法(路径变量)。如果我以硬编码的方式定义参数,而不使用 PathVariables,它正在工作 - 方法(“字符串”)。
但是当我尝试用我的代码定义一个字符串字符串,而不使用 PathVariables 时,它不起作用 - 根据用户数据从 db 获取一个字符串,并使用方法(字符串)的结果来更改 db 连接。
我也添加了一些日志信息,但仍然,这一切似乎都是一样的,但仍然无法完成这项工作。它是否与代码执行顺序、控制器生命周期、变量类型有关?
tenantContext
public class TenantContext {
private static ThreadLocal<String> currentTenant = new ThreadLocal<>();
public static void setCurrentTenant(String tenant) {
currentTenant.set(tenant);
}
public static String getCurrentTenant() {
return currentTenant.get();
}
public static void clear() {
currentTenant.set(null);
}
}
* PROBLEMATIC SOLUTION **********************************************
@GetMapping("/koms-list/name-containing")
public List<Kom> komsListByNameContaining(
Principal principal,
User user,
@RequestParam("targetKomName") String targetKomName
)
{
user = userRepository.findByUsername(principal.getName());
String dbContext = new String();
dbContext = user.getClient_db();
TenantContext.setCurrentTenant(dbContext);//NOT WORKING
TenantContext.setCurrentTenant("whatever");// THIS WORKS
Logger logger = LoggerFactory.getLogger(Logger.class.getName());
logger.info("Client db name based on Principal > " + user.getClient_db());
logger.info("Client db name variable-data type > " + user.getClient_db().getClass().getName());
logger.info("Active users name based on Principal > " + principal.getName());
logger.info("TenantContext variable data type > " + dbContext.getClass().getName());
logger.info("TenantContext variable value > " + dbContext);
logger.info("Target kom to find > " + targetKomName);
List<Kom> result = komRepository.findByNevContaining(targetKomName);
return result;
* WORKING SOLUTION **************************************************
@GetMapping("/koms-list/selected-client/{client}/selected-partner/{sif}")
public List<Kom> komListBySif(
@PathVariable (value = "sif") Long sif,
@PathVariable (value = "client") String client
)
{
TenantContext.setCurrentTenant(client);// THIS WORKS AS WELL
List<Kom> kom = (List<Kom>) komRepository.findBySif(sif);
return kom;
}
我希望 String dbContext = user.getClient_db() 字符串可以用作 Pathvariable String 客户端。但他们没有得出相同的结果。我在这里错过了一些基本的java东西吗?
* 更多代码 *
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class MultitenantDataSource extends AbstractRoutingDataSource {
@Override
public Object determineCurrentLookupKey() {
return TenantContext.getCurrentTenant();
}
}
这是通过根据用户数据从不同的文件/文件夹加载 application.properties 来更改数据库连接的正确方法吗?
* 更新 *
/**
* SECOND CONTROLLER
* get selected KOM by sif
*
* */
@CrossOrigin(origins = "http://localhost:3000/partners")
@GetMapping("/koms-list/selected-client/{client}/selected-partner/{sif}")
public List<Kom> komListBySif(
@PathVariable (value = "sif") Long sif,
@PathVariable (value = "client") String client
)
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
User user = userRepository.findByUsername(currentPrincipalName);
String context = user.getClient_db();
context = Normalizer.normalize(context, Form.NFD);
Logger logger = LoggerFactory.getLogger(Logger.class.getName());
logger.info("Client db name based on pathVariable > " + client);
logger.info("TenantContext variable data type based on context > " + context.getClass().getName());
//TenantContext tenantContext = new TenantContext();
//TenantContext.setCurrentTenant(client);
TenantContext.setCurrentTenant(client);
List<Kom> kom = (List<Kom>) komRepository.findBySif(sif);
return kom;
}
// 也成功断开,无法切换到另一个数据库连接
解决方案
看看有什么user.getClient_db();
回报。我怀疑这是一个空字符串 ( ""
)
顺便说一句,您正在创建一个冗余String
对象,String dbContext = new String();
您可以简单地做String dbContext = user.getClient_db();
也许问题出在您的 REST 方法上,我不确定您是否可以拥有多个有效负载(例如Principal principal
和User user
。尝试删除一个,看看是否有帮助
推荐阅读
- python - 尝试在一行上打印多行字符串(字符串存储为变量)
- c# - 如何将此文件流从 API 转换为 PDF 或 XML 文件?
- android - Android 线图中的 Firestore 文档值
- php - 离子应用程序中的错误“预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段。”
- oracle - 在 oracle 中如何进行 PK
- r - 将上限应用于数据框,同时忽略非数字值
- c# - 以编程方式从散点图趋势线中提取斜率和截距
- python - 用于时间序列分类的 TensorFlow 数据集 API
- ios - Watson Assistant 和 Swift
- python - GitLab CI:如何从控制台模拟用户输入