Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以使用JDBC在postgresql登录流的启动消息中传递应用程序名称?_Java_Postgresql_Jdbc - Fatal编程技术网

Java 是否可以使用JDBC在postgresql登录流的启动消息中传递应用程序名称?

Java 是否可以使用JDBC在postgresql登录流的启动消息中传递应用程序名称?,java,postgresql,jdbc,Java,Postgresql,Jdbc,我正在开发一个解析器,它可以嗅探网络流量并解析PostgreSQL(服务器版本9.6.11)的消息。 我需要能够在登录流中传递application_name参数(在它返回身份验证成功之前) 这意味着我不能依赖“设置应用程序名称”等 这在JDBC中是可能的吗?例如,使用ODBC可以通过设置libpq参数:application\u name=myapp。启动消息()将包含用户名和数据库旁边的参数 我正在使用Wireshark进行验证 我试着在这里阅读一些建议,但是所有的解决方案都依赖于在登录完成

我正在开发一个解析器,它可以嗅探网络流量并解析PostgreSQL(服务器版本9.6.11)的消息。 我需要能够在登录流中传递application_name参数(在它返回身份验证成功之前) 这意味着我不能依赖“设置应用程序名称”等

这在JDBC中是可能的吗?例如,使用ODBC可以通过设置libpq参数:
application\u name=myapp
。启动消息()将包含用户名和数据库旁边的参数

我正在使用Wireshark进行验证

我试着在这里阅读一些建议,但是所有的解决方案都依赖于在登录完成后设置应用程序名

我还尝试通过DBeaver的连接设置->驱动程序属性->应用程序名,得到了相同的结果

Properties=newproperties();
props.setProperty(“用户”,用户);
props.setProperty(“密码”,password);
props.setProperty(“ssl”、“true”);
props.setProperty(“sslmode”、“disable”);
props.setProperty(“应用程序名”、“我的应用程序”);
try(Connection-Connection=DriverManager.getConnection(“jdbc:postgresql://”+host+
“:5432/”+db,道具){
println(“JavaJDBCPostgreSQL示例”);
Class.forName(“org.postgresql.Driver”);
System.out.println(“连接到PostgreSQL数据库!”);
语句Statement=connection.createStatement();
} 
或者这个,

Properties=newproperties();
props.setProperty(“用户”,用户);
props.setProperty(“密码”,password);
props.setProperty(“ssl”、“true”);
props.setProperty(“sslmode”、“disable”);
try(Connection-Connection=DriverManager.getConnection(“jdbc:postgresql://”+host+
“:5432/”+db+“?应用程序(名称=我的应用程序”,道具)){
println(“JavaJDBCPostgreSQL示例”);
Class.forName(“org.postgresql.Driver”);
System.out.println(“连接到PostgreSQL数据库!”);
语句Statement=connection.createStatement();
}
我正在寻找一种复制ODBC行为的方法

这与我们的问题不同。 我想问的是,在登录协议完成之前是否可以传递这个参数。 当我使用Wireshark查看消息时,我可以清楚地看到,使用JDBC传递此参数的所有方法都被分解为以下消息序列:

  • 登录请求
  • 登录成功
  • 设置应用程序名称=我的应用程序
  • 在ODBC中,它是这样的:

  • 登录请求(包含参数应用程序名称)
  • 登录成功
  • 在源代码中

    具体从第311行开始:

    private List<String[]> getParametersForStartup(String user, String database, Properties info) {
        List<String[]> paramList = new ArrayList<String[]>();
        paramList.add(new String[]{"user", user});
        paramList.add(new String[]{"database", database});
        paramList.add(new String[]{"client_encoding", "UTF8"});
        paramList.add(new String[]{"DateStyle", "ISO"});
        paramList.add(new String[]{"TimeZone", createPostgresTimeZone()});
    
        Version assumeVersion = ServerVersion.from(PGProperty.ASSUME_MIN_SERVER_VERSION.get(info));
    
        if (assumeVersion.getVersionNum() >= ServerVersion.v9_0.getVersionNum()) {
          // User is explicitly telling us this is a 9.0+ server so set properties here:
          paramList.add(new String[]{"extra_float_digits", "3"});
          String appName = PGProperty.APPLICATION_NAME.get(info);
          if (appName != null) {
            paramList.add(new String[]{"application_name", appName});
          }
        } else {
          // User has not explicitly told us that this is a 9.0+ server so stick to old default:
          paramList.add(new String[]{"extra_float_digits", "2"});
        }
    
    
    主要变化:

    props.setProperty(PGProperty.ASSUME_MIN_SERVER_VERSION.getName(),"9.6.11");
    

    ?ApplicationName=URL中的我的应用程序
    (不是
    应用程序名称
    )。您的JDBC驱动程序版本是什么?根据Postgres JDBC来源,属性名称是
    ApplicationName
    。您可以尝试使用
    PgProperty.APPLICATION\u NAME.getName()
    获取正确的名称。或者使用postgres中的一个实现,而不是
    DriverManager
    。您可以在
    BaseDataSource
    上使用
    setApplicationName
    来设置应用程序名称。@a_horse_和_no_名称在我的第一个示例中,我已经尝试了ApplicationName,但我还是尝试了您建议的方法,仍然存在相同的问题。登录完成后设置complete@M.Deinum我尝试了您的建议,并将PGPoolingDataSource(尽管它已被弃用)与setApplicationName()一起使用-仍然是相同的如果它在身份验证完成后设置它,那么除了在提交改进请求之外,没有其他方法了。然而,据我从pgjdbc源代码中可以看出,它已经在身份验证之前的StartupPacket期间设置了它。确保您使用的是最新的驱动程序。
    props.setProperty(PGProperty.ASSUME_MIN_SERVER_VERSION.getName(),"9.6.11");