我正在开发一个具有多租户(对Java / spring来说是新的)的应用程序,试图通过不同的用户连接到不同的数据库。使用java.lang.String类有一些奇怪的经验
当使用String字符串作为@PathVariable时,它可以正常工作-method(pathvariable)。 如果我在不使用PathVariables的情况下以硬编码方式定义参数,则它可以正常工作-method(“ string”)。
但是当我尝试用我的代码定义一个String字符串,而不使用PathVariables时,它不起作用-根据用户数据从db获取一个字符串,并将结果与method(string)一起使用以更改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;
}
//也成功断开,无法更改为另一个数据库连接
答案 0 :(得分:0)
查看user.getClient_db();
返回什么。我怀疑这是一个空字符串(""
)
顺便说一句,您正在String
中创建一个冗余String dbContext = new String();
对象,您只需执行String dbContext = user.getClient_db();
也许问题出在您的REST方法上,我不确定您是否可以有多个有效负载(例如Principal principal
和User user
。请尝试删除其中一个,看看是否有帮助