Having a Java Bean object, I wanted to create a CSV file. For that reason, I have used JSEFA which is a Java Simple exchange format API. So
JSEFA allows us to
convert our Java Bean to CSV file using few lines.
So first, I have created my bean :
import org.jsefa.csv.annotation.CsvDataType;
import org.jsefa.csv.annotation.CsvField;
@CsvDataType
public class UserInfo {
@CsvField(pos = 1)
String userId;
@CsvField(pos = 2)
String userPassword;
@CsvField(pos = 7, converterType = ShortConverter.class)
Short bloodType;
@CsvField(pos = 12, converterType = DoubleConverter.class)
Double altitude;
}
Here if you don't put the Converted, you will get an error of type :
org.jsefa.IOFactoryException: Failed to create an CsvIOFactory
at org.jsefa.csv.CsvIOFactory.createFactory(CsvIOFactory.java:113)
at org.jsefa.csv.CsvIOFactory.createFactory(CsvIOFactory.java:87)
.....
Caused by: org.jsefa.common.mapping.TypeMappingException: Can not create a type mapping for field bloodType of class org.quwic.itms.dal.expression.UserInfo
at org.jsefa.rbf.annotation.RbfTypeMappingFactory.createFieldMappings(RbfTypeMappingFactory.java:181)
at org.jsefa.rbf.annotation.RbfTypeMappingFactory.createComplexTypeMappingIfAbsent(RbfTypeMappingFactory.java:129)
For that reason I have added the
convertType = ShortConverter.class. The same thing for the Double type which is not supported by JSEFA.
So the
ShortConverter and
DoubleConverter classes should be provided. and they need to implements the
JSefa Interface SimpleTypeConverter.
import org.jsefa.common.converter.SimpleTypeConverter;
public class DoubleConverter implements SimpleTypeConverter {
private static final DoubleConverter INSTANCE = new DoubleConverter();
public static DoubleConverter create() {
return INSTANCE;
}
private DoubleConverter() {
}
@Override
public Object fromString(String s) {
return new Double(s);
}
@Override
public String toString(Object d) {
return d.toString();
}
}
Once this is done, you need then to map your beans one by one and create the CSV (or XML file) in your main class:
import java.io.StringWriter;
import org.jsefa.Serializer;
import org.jsefa.csv.CsvIOFactory;
import org.jsefa.csv.config.CsvConfiguration;
public class UsersBeanToCSV {
public void processUser(List<UserInfo> users){
CsvConfiguration config = new CsvConfiguration();
config.setFieldDelimiter(',');
config.getSimpleTypeConverterProvider().registerConverterType(Double.class, DoubleConverter.class);
config.getSimpleTypeConverterProvider().registerConverterType(Short.class, ShortConverter.class);
Serializer serializer = CsvIOFactory.createFactory(config,MddNotification.class).createSerializer();
StringWriter writer = new StringWriter();
serializer.open(writer);
for(UserInfo user:users){
serializer.write(user);
}
serializer.close(true);
}
}
We use here the CsvConfiguration to register the new Converter.
By default, Jsefa uses the
';' to delimit fields, but as I want to use
',', I declare that using the
setFieldDelimiter.
I have just discovered an other issue, so I update my post. In fact, you need to pay attention when the double or Short value may be null (you will have a NullponterException)
So if the values are optional, you may have some beans with null values.
So you need to modify the DoubleConverter:
import org.jsefa.common.converter.SimpleTypeConverter;
public class DoubleConverter implements SimpleTypeConverter {
private static final DoubleConverter INSTANCE = new DoubleConverter();
public static DoubleConverter create() {
return INSTANCE;
}
private DoubleConverter() {
}
@Override
public Object fromString(String s) {
if(s!=null){
return new Double(s);
}else{
return null
}
}
@Override
public String toString(Object d) {
if(d!= null){
return d.toString();
}else{
return null;
}
}
}
That's all, hope it helped you :).