工作中经常会遇到将行数据转换成Java(POJO)对象的场景,其中关于字段校验和类型转换的处理繁琐而冗余,对于有代码洁癖的人着实不能忍。这里分享下自己封装的工具代码,也许能够帮助你更简单地完成此类任务。
先将以下五个文件加入你豪华午餐(项目)中
FieldItem:
/***
*@authorlichmama
**/
public classFieldItem {public intgetIndex() {returnindex;
}public void setIndex(intindex) {this.index =index;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicObject getValue() {returnvalue;
}public voidsetValue(Object value) {this.value =value;
}publicFieldProcessor getProcessor() {returnprocessor;
}public voidsetProcessor(FieldProcessor processor) {this.processor =processor;
}public voidsetValidator(FieldValidator validator) {this.validator =validator;
}publicFieldValidator getValidator() {returnvalidator;
}public booleanvalidate() {return validator.validate(this);
}public Object process() throwsException {return processor.process(this);
}private intindex;privateString name;privateObject value;private FieldValidator validator = newFieldValidator() {
@Overridepublic booleanvalidate(FieldItem field) {return true;
}
};private FieldProcessor processor = newFieldProcessor() {
@OverridepublicObject process(FieldItem field) {returnfield.getValue();
}
};publicFieldItem() {
}public FieldItem(intindex, String name) {this.index =index;this.name =name;
}public FieldItem(intindex, String name, FieldValidator validator) {this.index =index;this.name =name;this.validator =validator;
}public FieldItem(intindex, String name, FieldProcessor processor) {this.index =index;this.name =name;this.processor =processor;
}public FieldItem(intindex, String name, FieldValidator validator, FieldProcessor processor) {this.index =index;this.name =name;this.validator =validator;this.processor =processor;
}
}
View Code
FieldProcessor:
/*** 扩展接口:可针对字段做个性化处理
*
*@authorlichmama
**/
public interfaceFieldProcessor {
Object process(FieldItem field)throwsException;
}
View Code
FieldValidator:
/*** 校验接口:可针对字段做个性化校验
*
*@authorlichmama
**/
public interfaceFieldValidator {booleanvalidate(FieldItem field);
}
View Code
ConvertException:
/*** 转换异常
*
*@authorlichmama
**/
public class ConvertException extendsRuntimeException {publicConvertException(String msg) {super(msg);
}publicConvertException(Throwable throwable) {super(throwable);
}publicConvertException(String msg, Throwable throwable) {super(msg, throwable);
}
}
View Code
RowConverter:
/*** 行转换器:用于将行数据转换成bean
*
*@authorlichmama
**/
public classRowConverter {private Map fieldMap = new HashMap();publicRowConverter() {}publicRowConverter(String[] fieldNames) {for (int i = 0; i < fieldNames.length; i++) {
String name=fieldNames[i];
FieldItem field= newFieldItem();
field.setIndex(i);
field.setName(name);
fieldMap.put(name, field);
}
}public voidsetField(FieldItem field) {if (field == null) {throw new ConvertException("field is null");
}
String name=field.getName();if (!fieldMap.containsKey(name)) {throw new ConvertException("the field \"" + name + "\" not found");
}
fieldMap.put(name, field);
}public voidsetFieldValidator(String name, FieldValidator validator) {if (!fieldMap.containsKey(name)) {throw new ConvertException("the field \"" + name + "\" not found");
}
fieldMap.get(name).setValidator(validator);
}public voidsetFieldProcessor(String name, FieldProcessor processor) {if (!fieldMap.containsKey(name)) {throw new ConvertException("the field \"" + name + "\" not found");
}
fieldMap.get(name).setProcessor(processor);
}public T convert(Object[] row, Class beanClass) throwsException {
Map properties = new HashMap();
Iterator iter =fieldMap.values().iterator();while(iter.hasNext()) {
FieldItem field=iter.next();
Object value=row[field.getIndex()];
field.setValue(value);if (!field.validate()) {throw new ConvertException("the field \"" + field.getName() + "\" validate failed");
}
Object processedValue=field.process();
properties.put(field.getName(), processedValue);
}
T bean=beanClass.newInstance();//powered by commons-beanutils
BeanUtils.populate(bean, properties);returnbean;
}
}
View Code
下面我们就可以愉快的写代码了:
目标类User:
public class User implementsSerializable {private intid;privateString name;privateString gender;private intage;privateString birthday;//省略getter、setter
@OverridepublicString toString() {return "User [id=" + id + ", name=" + name + ", gender=" + gender + ", age=" + age + ", birthday=" +birthday+ "]";
}
}
测试类Test:
public classTest {public static void main(String[] args) throwsException {
String[] fieldNames= { "id", "name", "gender", "age", "birthday"};
Object[] row= { 1, "lichmama", "man", 17, newDate() };
RowConverter converter= newRowConverter(fieldNames);
testValidator(row, converter);
testProcessor(row, converter);
}/*** 字段个性化校验
*
*@paramrow
*@paramconverter
*@throwsException*/
public static void testValidator(Object[] row, RowConverter converter) throwsException {
converter.setFieldValidator("age", (FieldItem field) ->{int age = (int) field.getValue();return age >= 18; // 未成年禁止入内
});
User user= converter.convert(row, User.class);
}/*** 字段个性化处理
*
*@paramrow
*@paramconverter
*@throwsException*/
public static void testProcessor(Object[] row, RowConverter converter) throwsException {
converter.setFieldProcessor("birthday", (FieldItem field) ->{return new SimpleDateFormat("yyyy-MM-dd").format(field.getValue()); // 将日期转换成格式化字符串
});
User user= converter.convert(row, User.class);
}
}
看上去是不是好多了