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