【问题标题】:SQLException: The connection string contains a badly formed name or valueSQLException:连接字符串包含格式错误的名称或值
【发布时间】:2018-12-10 10:22:52
【问题描述】:

我尝试连接到 MS SQL Server 暂存环境,但它显示

SQLException: The connection string contains a badly formed name or value

在哪里,我的密码包含{}

如何正确转义字符? 我的 JDBC 网址:

jdbc:sqlserver://localhost;databaseName=WHOPQDTB_test;integratedSecurity=false;user=WHOPQDTB_user;password='ahsdgahgsd';

我尝试使用不同的密码登录,它显示异常:

用户“WHOPQDTB_user”登录失败。

请帮忙。提前致谢。

【问题讨论】:

  • 您能告诉我们您尝试的实际网址吗?如果您不想向我们显示真实密码,请给我们一个可以使用的代理。您现在显示的内容应该会失败,但不是因为 JDBC URL。
  • 这可能会变得很难看。您可能需要将括号中的转义字符更改为其他字符。
  • 我无法为此请求其他用户或密码。这是一个漫长的过程。我在网上搜索如何转义字符,但没有找到解决方案。兄弟有什么想法吗?
  • 这就是问题所在。要逃脱,您可以使用{blah blah blah}。但是,我不知道如果密码本身包含{},这将如何/是否有效。我的建议是告诉你的用户不要创建这样的密码。
  • 是的,密码本身在特定索引中包含 { 和 }。还有其他建议吗?

标签: java sql-server automated-tests


【解决方案1】:

Microsoft Docs - Building the Connection URL

连接 URL 中的转义值

由于包含空格、分号和引号等特殊字符,您可能必须转义连接 URL 值的某些部分。如果这些字符括在大括号中,则 JDBC 驱动程序支持对它们进行转义。例如,{;} 转义分号。

转义值可以包含特殊字符(尤其是“=”、“;”、“[]”和空格),但不能包含大括号。必须转义并包含大括号的值应添加到属性集合中。

因此更改密码或将用户/密码另存为单独的变量并将其添加到连接中。

String dbURL = "jdbc:sqlserver://localhost\\sqlexpress";
String user = "sa";
String pass = "secret";
conn = DriverManager.getConnection(dbURL, user, pass);

如果您想使用属性集合,您可以在此处找到属性名称:

Microsoft Docs - Setting the Connection Properties

java2s - Create Connection With Properties 有一个很好的 java 示例。它适用于 MySQL 服务器,但您只需更改属性名称。 (来自上面的链接页面)

tl;博士 潜入源头

SourceCode - DriverManager.java

使用.getConnection(String url, String user, String password) 将创建一个Properties 条目。

@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));
}

mssql-jdbc 代码

MSSQL-JDBC - SQLServerDriver.java

public java.sql.Connection connect(String Url, Properties suppliedProperties)
用途:

// Merge connectProperties (from URL) and supplied properties from user.
Properties connectProperties = parseAndMergeProperties(Url, suppliedProperties);

从给定的 connectionUrl 中获取(额外的)属性:

private Properties parseAndMergeProperties(String Url, Properties suppliedProperties)

正在使用:

Properties connectProperties = Util.parseUrl(Url, drLogger);

MSSQL- Util.java 是破坏者。

    if (ch == ';') {...}
case inEscapedValueStart: 
    if (ch == '}') {...}
case inEscapedValueEnd: 
    if (ch == ';') {...}

绕过此案例切换并直接进入“SQLServerConnection.java”的唯一方法是提供正确的属性集合

MSSQL-JDBC - SQLServerConnection.java

函数Connection connect(Properties propsIn, SQLServerPooledConnection pooledConnection)
分别Connection connectInternal(Properties propsIn, SQLServerPooledConnection pooledConnection):

sPropKey = SQLServerDriverStringProperty.PASSWORD.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
    sPropValue = SQLServerDriverStringProperty.PASSWORD.getDefaultValue();
    activeConnectionProperties.setProperty(sPropKey, sPropValue);
}

【讨论】:

  • 是的,他无法转义连接字符串中的密码。但他可以将其用作财产。 (就像 MS 所说:“必须转义并包含大括号的值应该添加到属性集合中。”)
  • 向我展示这种解决方法有效的证据,我很乐意投票。 :-)
  • 是的,它通过使用属性工作,但这是原始 JDBC 库。我需要使用其他一些提供这种功能的库。请推荐一个好的 JDBC 库,如 ormlite、jooq 或其他。
  • JDBC 是 Java 应用程序和数据库之间的连接。 jooq 或 ormlite 在后台使用 JDBC。 JOOG - getting started
  • Spring JDBC 模板是否提供属性功能?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多