Java+Selenium如何避免sendKeys硬编码,从SQL Server取数填充
解决方案:从SQL Server取数填充Selenium输入框(基于Apache Commons DbUtils)
前置依赖准备
确保项目引入以下核心依赖(Maven示例):
<!-- SQL Server JDBC驱动 --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>12.4.1.jre11</version> </dependency> <!-- Apache Commons DbUtils --> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> </dependency> <!-- Selenium Java --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.15.0</version> </dependency>
数据库操作工具类(解决可变参数/连接问题)
封装DbUtils的查询逻辑,自动处理连接关闭,避免硬编码连接参数:
import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.MapListHandler; import java.sql.Connection; import java.sql.DriverManager; import java.util.List; import java.util.Map; public class DBHelper { // 建议将连接参数移至配置文件(如properties/yaml) private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDB;encrypt=true;trustServerCertificate=true"; private static final String DB_USER = "sa"; private static final String DB_PWD = "YourPassword"; public static List<Map<String, Object>> fetchData(String sql, Object... params) { Connection conn = null; try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD); QueryRunner runner = new QueryRunner(); // MapListHandler返回多行结果,每行以字段名为key存储数据 return runner.query(conn, sql, new MapListHandler(), params); } catch (Exception e) { throw new RuntimeException("数据库查询失败", e); } finally { DbUtils.close(conn); // DbUtils自动处理连接关闭,无需手动try-catch } } }
核心问题解决
1. sendKeys参数类型不兼容处理
Selenium的sendKeys()仅接受CharSequence类型,需将DbUtils返回的Object安全转换为String,避免空指针或类型转换异常:
// 工具方法:安全转换Object为String,null返回空字符串 private static String safeToString(Object obj) { return obj == null ? "" : obj.toString().trim(); }
2. 多结果集循环处理逻辑
针对两种常见场景实现循环填充:
场景A:单表单填充多个字段(用单行数据)
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.List; import java.util.Map; public class SingleFormFill { public static void main(String[] args) { WebDriver driver = new ChromeDriver(); driver.get("https://your-form-url.com"); // 执行带参数的SQL(解决DbUtils可变参数问题:直接传对应类型参数即可) String sql = "SELECT username, email, phone FROM users WHERE id = ?"; List<Map<String, Object>> dataList = DBHelper.fetchData(sql, 1); if (!dataList.isEmpty()) { Map<String, Object> userData = dataList.get(0); // 填充输入框,用safeToString处理类型转换 driver.findElement(By.id("username")).sendKeys(safeToString(userData.get("username"))); driver.findElement(By.id("email")).sendKeys(safeToString(userData.get("email"))); driver.findElement(By.id("phone")).sendKeys(safeToString(userData.get("phone"))); } // 提交表单等后续操作 // driver.findElement(By.id("submit-btn")).click(); driver.quit(); } }
场景B:批量处理多行数据(循环提交表单)
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.List; import java.util.Map; public class BatchFormSubmit { public static void main(String[] args) { WebDriver driver = new ChromeDriver(); driver.get("https://your-form-url.com"); // 查询多行待处理数据 String sql = "SELECT username, email, phone FROM users WHERE status = 'active'"; List<Map<String, Object>> dataList = DBHelper.fetchData(sql); for (Map<String, Object> userData : dataList) { // 清空输入框(避免残留数据) driver.findElement(By.id("username")).clear(); driver.findElement(By.id("email")).clear(); driver.findElement(By.id("phone")).clear(); // 填充当前行数据 driver.findElement(By.id("username")).sendKeys(safeToString(userData.get("username"))); driver.findElement(By.id("email")).sendKeys(safeToString(userData.get("email"))); driver.findElement(By.id("phone")).sendKeys(safeToString(userData.get("phone"))); // 提交表单 driver.findElement(By.id("submit-btn")).click(); // 回到表单页面准备下一次填充 driver.navigate().back(); } driver.quit(); } }
常见错误排查
- 可变参数类型不匹配:DbUtils的
query方法接受Object...可变参数,直接传入对应类型(如int、String)即可,Java会自动装箱,无需强制转换数组。 - sendKeys参数异常:必须将DbUtils返回的Object转换为String,使用
safeToString方法处理null值,避免ClassCastException或NullPointerException。 - 多结果集遍历异常:通过
List<Map<String, Object>>接收所有行,用for-each循环遍历,确保每行数据对应一次表单操作。
内容的提问来源于stack exchange,提问作者JustToKnow
相关产品推荐
相关产品推荐

