Spring使用计算机名而不是提供的用户名来访问jdbc数据库
Posted
技术标签:
【中文标题】Spring使用计算机名而不是提供的用户名来访问jdbc数据库【英文标题】:Spring use Computer name instead of supplied username for jdbc database access 【发布时间】:2020-02-14 11:17:56 【问题描述】:阅读 Pro Spring 5,一个显示 Spring JDBC 正在使用 mysql DB 的示例。我使用本书的源代码。这是代码
@Configuration
@PropertySource("classpath:db/jdbc2.properties")
@ComponentScan(basePackages = "com.apress.prospring5.ch6")
public class AppConfig
private static Logger logger = LoggerFactory.getLogger(AppConfig.class);
@Value("$driverClassName")
private String driverClassName;
@Value("$url")
private String url;
@Value("$username")
private String username;
@Value("$password")
private String password;
@Bean(destroyMethod = "close")
public DataSource dataSource()
try
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
catch (Exception e)
logger.error("DBCP DataSource bean cannot be created!", e);
return null;
jdbc2.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/musicdb?useSSL=true
username=prospring5
password=prospring5
测试
public class AnnotationJdbcTest
private GenericApplicationContext ctx;
private SingerDao singerDao;
@Before
public void setUp()
ctx = new AnnotationConfigApplicationContext(AppConfig.class);
singerDao = ctx.getBean(SingerDao.class);
assertNotNull(singerDao);
@Test
public void testFindAll()
List<Singer> singers = singerDao.findAll();
assertTrue(singers.size() == 3);
listSingers(singers);
ctx.close();
我的 MySQL 实例已经有用户 prospring5 以及创建和填充的架构
当我尝试运行 AnnotationJdbcTest 时,我得到了这个异常:
Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'Mehdi'@'localhost' (using password: YES))
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'Mehdi'@'localhost' (using password: YES))
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:612)
如您所见,该项目使用我的计算机名称“Mehdi”,而不是 .properties 文件中的名称“prospring5”。这是为什么?以及如何解决?
您可以自己下载源代码并从这里运行它:https://github.com/Apress/pro-spring-5 该项目是:第6章/spring-jdbc-annotations
编辑: 我按照@STaefi 的建议打印了值,这是输出:
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/musicdb?useSSL=false
Mehdi
prospring5
代码
@Bean()
public DataSource dataSource()
try
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
System.out.println(driverClassName);
dataSource.setUrl(url);
System.out.println(url);
dataSource.setUsername(username);
System.out.println(username);
dataSource.setPassword(password);
System.out.println(password);
return dataSource;
首先我尝试在初始化时设置这些值,但这并不好。但是在我使用username = "prospring5"; dataSource.setUsername(username);
之后它起作用了。那么这是什么意思。为什么Spring无法像成功加载url和密码一样加载用户名。
【问题讨论】:
早期的猜测,也许它在查找和加载您的属性文件时遇到了问题。您可以对用户名和密码进行硬编码以查看是否可以解决问题吗?您还可以记录应该从属性文件中读取的属性,以查看为它们加载的内容。 尝试将属性文件的路径更改为 @PropertySource("classpath:**/db/jdbc2.properties")。 @STaefi 我犯了同样的错误。我该怎么做你所说的日志记录? @lazy.coder 无法解析配置类 [com.apress.prospring5.ch6.config.AppConfig];嵌套异常是 java.io.FileNotFoundException: 类路径资源 [**/db/jdbc2.properties] 无法打开,因为它不存在,现在找不到属性文件。 这可能会帮助你***.com/questions/20353402。理想情况下,您的用户无法访问您的数据库。此外,如果您在本地系统中运行,您可以关闭 useSSL=flase。 【参考方案1】:请您尝试将默认值设为:
@Value("$driverClassName:com.mysql.cj.jdbc.Driver")
private String driverClassName;
@Value("$url:jdbc:mysql://localhost:3306/musicdb?useSSL=true")
private String url;
@Value("$username:prospring5")
private String username;
@Value("$password:prospring5")
private String password;
并删除顶部的@PropertySource("classpath:db/jdbc2.properties")。如果这可行,那么您可以再次尝试使用 propertySource
【讨论】:
就像@usertest 所说,只需将用户名和密码更改为其他名称,它就可以工作 是的,我是用户测试,同样的人问这个问题。谢谢。【参考方案2】:所以我通过简单地在 .propreties 文件中使用不同的字符串标识符解决了这个问题。我将其更改为 one=prospring5
并且有效。显然,使用名为“用户名”的属性将加载除您的计算机名称之外的任何内容。我不知道 Spring 是否提供了属性名称的禁止值列表。如果他们不这样做,他们当然应该考虑。
【讨论】:
禁止有点强;您遇到了一个使用非常模糊的属性名称的情况,该属性名称恰好已经由 Spring 组件设置。这就是为什么建议使用上下文驱动的属性名称,例如“musicdb.username”。 保留怎么样?我知道 MySQL 有很多 dev.mysql.com/doc/refman/8.0/en/keywords.html 。另外,我没有想到 Pro Spring 5 的书作者的名字。你自己检查源代码。 我的意思是避免使用模棱两可或通用的名称,我并不是在争论术语。顺便说一下,这对于您自己定义的 bean 的名称来说是双倍的。我已经被 Spring 升级咬了至少三次,我不得不解决重复的 bean 名称。这伤害了很多 bean 恰好在一个到处使用的共享库中。以上是关于Spring使用计算机名而不是提供的用户名来访问jdbc数据库的主要内容,如果未能解决你的问题,请参考以下文章
使用基于主机名而不是 IP 地址的自签名证书保护 Python WebSocket
NSStringFromSelector 返回变量名而不是变量值