To convert a Cucumber DataTable into Java objects, choose the conversion that matches the table: accept a supported collection directly for simple data, register an explicit @DataTableType for domain objects, or use default data-table transformers to delegate shared mapping to an object mapper such as Jackson. A Gherkin table is passed to a step as its final argument; it does not automatically become an arbitrary Java class just because its headers resemble field names.
Choose a mapping approach
| Approach | Best fit | Where conversion rules live |
|---|---|---|
| Direct collection conversion | A supported simple shape, such as a one-column list or a header-and-row map | Cucumber’s built-in DataTable conversion |
@DataTableType |
Rows that need deliberate construction as domain objects | A named Java conversion method |
| Default data-table transformers | Shared conversion through an object mapper across entries or cells | Project-wide transformer methods and mapper configuration |
Cucumber documents these as available mechanisms rather than prescribing one universal choice. See the DataTable API guide and the configuration guide.
Receive a supported collection directly
For straightforward tables, declare a collection type supported by Cucumber and let it convert the table argument. Documented representations include List<List<String>>, List<Map<String, String>>, and several map structures, depending on the table shape. A one-column table can be received as List<String>; Cucumber flattens it using DataTable.asList(String.class).
Cucumber also documents conversion to common numeric types. If the target type or conversion rule is not supported by the built-in conversion, register a data-table type. The API documentation describes the supported shapes and conversions.
Recommended Free Tools
#1 Best Overall
Use direct conversion when the table already matches the collection your step needs. For a table with a header row, for example, a list of maps can make each row’s values accessible by column name. Do not assume that a table will automatically map into an arbitrary domain class solely from matching headers to fields.
Map each row explicitly with @DataTableType
Use @DataTableType when a row needs domain-specific construction. The conversion method can receive a row as Map<String, String> and return the object; a step definition can then accept a list of those objects. The official Java example maps named columns to an Author object.
import io.cucumber.java.DataTableType;
import io.cucumber.java.en.Given;
import java.util.List;
import java.util.Map;
public class AuthorSteps {
@DataTableType
public Author authorEntry(Map<String, String> row) {
return new Author(row.get("name"), row.get("email"));
}
@Given("these authors exist")
public void theseAuthorsExist(List<Author> authors) {
// Use the converted domain objects in the step.
}
}
In a feature, the header names must match the keys the converter reads:
Given these authors exist
| name | email |
| Ada | ada@example.test |
Here, name and email are map keys supplied from the table’s header row. Replace the sample fields and constructor with those from your domain class. Put any required validation, missing-value handling, or error policy in the conversion method as appropriate for the application; the documentation’s example shows named-field access but does not prescribe those policies. Cucumber detects data-table type definitions as glue when they are on the glue path. See the Java configuration guide.
Delegate shared mapping to an object mapper
When many table entries or cells should follow a shared mapping policy, Cucumber supports @DefaultDataTableEntryTransformer and @DefaultDataTableCellTransformer. Its configuration guide demonstrates combining those annotations with @DefaultParameterTransformer and using Jackson’s ObjectMapper.convertValue with the target reflective type:
import com.fasterxml.jackson.databind.ObjectMapper;
import io.cucumber.java.DefaultDataTableCellTransformer;
import io.cucumber.java.DefaultDataTableEntryTransformer;
import io.cucumber.java.DefaultParameterTransformer;
import io.cucumber.core.reference.TypeReference;
public class MappingConfiguration {
private final ObjectMapper objectMapper = new ObjectMapper();
@DefaultParameterTransformer
@DefaultDataTableEntryTransformer
@DefaultDataTableCellTransformer
public Object transform(Object fromValue, TypeReference<?> toValueType) {
return objectMapper.convertValue(
fromValue,
objectMapper.constructType(toValueType.getType())
);
}
}
This pattern delegates the conversion to Jackson rather than defining each row’s construction in a separate method. Configure the mapper for the constructors, naming conventions, and value formats your application uses. The annotations and conversion hook are documented by Cucumber; the example does not establish a universal Jackson configuration for every project. See the configuration guide.
Keep expression-parameter mapping distinct
Cucumber’s Java Expressions documentation discusses its built-in conversion for numeric types and enums, and recommends an object mapper for converting anonymous expression parameters to other types. That concerns step-expression parameters; for DataTable entries and cells, use the data-table transformer mechanisms described above. See Cucumber Expressions.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Check your Cucumber dependency versions
Use the same version for all Cucumber dependencies in a Cucumber-JVM project. The official Java installation guide illustrates dependency setup with version 8.0.2; that example does not establish that 8.0.2 is the latest release. Verify the current release before choosing dependency coordinates.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

