OpenCSV解析自定义逻辑:入职日期校验与CSVException抛出需求
Got it, let's walk through how to add that custom date range validation to your OpenCSV parsing workflow. Here's a step-by-step solution that fits your needs:
We'll implement a custom bean verifier to check if firstDayOfWork is earlier than lastDayOfWork, and collect any validation failures as CSVExceptions during parsing.
1. Define Your CSV Entity Class
First, create a POJO to map your CSV fields, including date fields with proper formatting annotations:
import com.opencsv.bean.CsvBindByName; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDate; public class Employee { @CsvBindByName(column = "firstName") private String firstName; @CsvBindByName(column = "secondName") private String secondName; @CsvBindByName(column = "firstSalary") private BigDecimal firstSalary; @CsvBindByName(column = "lastSalary") private BigDecimal lastSalary; @CsvBindByName(column = "firstDayOfWork") @DateTimeFormat(pattern = "yyyy-MM-dd") // Adjust to match your CSV date format private LocalDate firstDayOfWork; @CsvBindByName(column = "lastDayOfWork") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate lastDayOfWork; // Getters and setters for all fields }
2. Create a Custom Bean Verifier
Implement OpenCSV's BeanVerifier interface to add your date range check. This verifier will throw a CsvValidationException if the date condition isn't met:
import com.opencsv.bean.BeanVerifier; import com.opencsv.exceptions.CsvValidationException; import java.time.LocalDate; public class EmployeeDateRangeVerifier implements BeanVerifier<Employee> { @Override public boolean verifyBean(Employee employee) throws CsvValidationException { LocalDate startDate = employee.getFirstDayOfWork(); LocalDate endDate = employee.getLastDayOfWork(); // Validate both dates exist and start is before end if (startDate != null && endDate != null && !startDate.isBefore(endDate)) { throw new CsvValidationException( String.format("Invalid date range for %s %s: firstDayOfWork (%s) is not earlier than lastDayOfWork (%s)", employee.getFirstName(), employee.getSecondName(), startDate, endDate) ); } return true; } }
3. Parse CSV with Custom Validation
Configure your CsvToBean instance to use the verifier, and enable exception capturing to collect all validation errors instead of stopping at the first failure:
import com.opencsv.bean.CsvToBean; import com.opencsv.bean.CsvToBeanBuilder; import com.opencsv.exceptions.CsvException; import java.io.FileReader; import java.util.List; public class CsvParser { public static void main(String[] args) { try (FileReader reader = new FileReader("your-employees.csv")) { CsvToBean<Employee> csvParser = new CsvToBeanBuilder<Employee>(reader) .withType(Employee.class) .withVerifier(new EmployeeDateRangeVerifier()) // Attach your custom verifier .withThrowExceptions(false) // Critical: Collects all exceptions instead of halting early .build(); // Parse valid records List<Employee> validEmployees = csvParser.parse(); // Retrieve all validation exceptions List<CsvException> validationErrors = csvParser.getCapturedExceptions(); // Handle the errors if (!validationErrors.isEmpty()) { System.out.println("Parsing encountered validation errors:"); for (CsvException error : validationErrors) { System.out.printf("Line %d: %s%n", error.getLineNumber(), error.getMessage()); } } // Process your valid employee records here // ... } catch (Exception e) { e.printStackTrace(); } } }
Key Tips
- Date Format Matching: Ensure the
@DateTimeFormatpattern exactly matches the date format in your CSV (e.g., use"MM/dd/yyyy"if your dates are formatted that way). - Null Handling: The verifier checks for null dates to avoid
NullPointerExceptions—adjust this logic if your CSV guarantees these fields are always populated. - Exception Capturing:
withThrowExceptions(false)is mandatory if you want to collect all validation errors; without it, parsing stops at the first invalid record.
内容的提问来源于stack exchange,提问作者Poppo Pippo

