我想从带有枚举的 bean 编写一个 csv 文件。我的豆子包含:
@NotNull(message = "userRole should not be blank")
private UserRole userRole;
用户角色类:
@Getter
@RequiredArgsConstructor
public enum UserRole {
STUDENT("student"),
TEACHER("teacher");
private final String value;
}
构建 csv 文件如下所示:
private <T extends CsvBean> String writeCsvFromBean(Path ddir, String fileName, List<T> obj) throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
String filePath = ddir.resolve(fileName).toString();
try (Writer writer = new FileWriter(filePath)) {
StatefulBeanToCsv<T> sbc = new StatefulBeanToCsvBuilder<T>(writer)
.withSeparator(ICSVWriter.DEFAULT_SEPARATOR)
.build();
sbc.write(obj);
}
return filePath;
}
在生成的 csv 文件中,我可以看到列为 STUDENT/TEACHER(大写字母)的枚举值,而不是枚举的 valueOf 结果学生/教师。如何强制opencsv根据enum valueOf生成csv?
BR
您对 UserRole 的定义是这样的,一旦您将其 de-Lombokked 后:
public enum UserRole {
STUDENT("student"),
TEACHER("teacher");
private final String value;
UserRole(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
没有任何内容表明
valueOf
应该是“学生”或“老师”。事实上,UserRole.valueOf("student")
会抛出IllegalArgumentException
,但UserRole.valueOf("STUDENT")
会返回正确的值。
您需要的是重写
toString
方法以返回 value
。
默认情况下,枚举转换使用枚举的
name()
,指的是 ConverterEnum
。
您可以使用 CsvCustomBindByName
覆盖此转换并创建自定义转换器。
import com.opencsv.bean.CsvCustomBindByName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CsvBean {
@CsvCustomBindByName(converter = UserRoleConverter.class)
private UserRole userRole;
}
import com.opencsv.bean.AbstractBeanField;
import java.util.Arrays;
public class UserRoleConverter extends AbstractBeanField<UserRole, String> {
// for reading back from csv to bean
@Override
protected Object convert(String value) {
return Arrays.stream(UserRole.values())
.filter(userRole -> userRole.getValue().equals(value))
.findFirst().orElse(null);
}
@Override
protected String convertToWrite(Object value) {
if (value == null) {
return "";
}
return ((UserRole) value).getValue();
}
}