方法相同,字符串输入似乎相同,结果不同

时间:2018-12-26 17:59:15

标签: java spring

我正在开发一个具有多租户(对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;
        }

//也成功断开,无法更改为另一个数据库连接

1 个答案:

答案 0 :(得分:0)

查看user.getClient_db();返回什么。我怀疑这是一个空字符串(""

顺便说一句,您正在String中创建一个冗余String dbContext = new String();对象,您只需执行String dbContext = user.getClient_db();

也许问题出在您的REST方法上,我不确定您是否可以有多个有效负载(例如Principal principalUser user。请尝试删除其中一个,看看是否有帮助