2 回答
TA贡献1893条经验 获得超10个赞
经过数小时的工作,我为您找到了解决方案。
我使用 FlexJson 来配置你的 json 的序列化。
<!-- https://mvnrepository.com/artifact/net.sf.flexjson/flexjson -->
<dependency>
<groupId>net.sf.flexjson</groupId>
<artifactId>flexjson</artifactId>
<version>2.0</version>
</dependency>
它不是很漂亮,但它有效。
我希望这对您有所帮助,我相信您可以改进此代码
public String generateJsonFromCSV(File csvFile, File schemaJson) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//Get CsvSchema as Map
Map<String, CsvSchema.ColumnType> map = getSchemaMapFromJson(schemaJson);
//Create CsvSchema from CsvSchemaMap
CsvSchema.Builder schemaBuilder = new CsvSchema.Builder();
map.forEach(schemaBuilder::addColumn);
CsvSchema schema = schemaBuilder.build();
//read CSV
CsvMapper csvMapper = new CsvMapper();
MappingIterator<Map<?, ?>> mappingIterator = csvMapper.readerFor(Map.class).with(schema).readValues(csvFile);
//Get configured JsonSerializer from CsvSchemaMap
JSONSerializer jsonSerializer = getJsonSerializer(map);
List<Map<?, ?>> lines = mappingIterator.readAll();
//remove first line
lines.remove(0);
//serialize
return jsonSerializer.deepSerialize(lines);
}
/**
*
* @param schemaMap mapping field to ColumnType
* @return a configured JSONSerializer
*/
private JSONSerializer getJsonSerializer(Map<String, CsvSchema.ColumnType> schemaMap){
Map<CsvSchema.ColumnType, Transformer> transformerMap = new EnumMap<>(CsvSchema.ColumnType.class);
transformerMap.put(CsvSchema.ColumnType.STRING, new StringTransformer());
transformerMap.put(CsvSchema.ColumnType.NUMBER, new NumberTransformer());
JSONSerializer jsonSerializer = new JSONSerializer();
for (Map.Entry<String, CsvSchema.ColumnType> columnTypeEntry : schemaMap.entrySet()) {
jsonSerializer.transform(transformerMap.get(columnTypeEntry.getValue()),columnTypeEntry.getKey());
}
return jsonSerializer;
}
/**
/**
*
* @param file JSON CsvSchema
* @return fieldname ColumnType mapping
* @throws ClassNotFoundException
*/
private Map<String, CsvSchema.ColumnType> getSchemaMapFromJson(File file) throws ClassNotFoundException {
Map<String, String> schema = new JSONDeserializer<Map<String,String>>().deserialize(getResourceFileAsString(file.getName()));
Map<String, CsvSchema.ColumnType> result = new HashMap<>(schema.size());
for (Map.Entry<String, String> columnSchema : schema.entrySet()) {
result.put(columnSchema.getKey(), CsvSchema.ColumnType.valueOf(columnSchema.getValue().toUpperCase()));
}
return result;
}
输出将是
[{"name":"foobar","year":1986},{"name":"testtest","year":777}]
TA贡献1831条经验 获得超9个赞
强制CsvMapper使用给定类型的最好方法是使用POJO. 在这种情况下CsvMapper,知道类型并在可能的情况下自动转换它。让我们创建一个示例数据:
name,year
1,1
2,2
3,2
(在您的示例中,第一列名称是,test但我认为这只是一个错误,应该是name。)
下面的应用程序显示了如何解析CSV和编写JSON使用POJO:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class CsvApp {
public static void main(String[] args) throws IOException {
File csvFile = new File("./resource/test.csv").getAbsoluteFile();
CsvMapper csvMapper = new CsvMapper();
CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
ObjectReader reader = csvMapper.readerFor(User.class).with(bootstrapSchema);
MappingIterator<User> iterator = reader.readValues(csvFile);
List<User> users = new ArrayList<>();
iterator.forEachRemaining(users::add);
System.out.println("Users read from CSV file:");
users.forEach(System.out::println);
System.out.println();
System.out.println("Users in JSON format:");
ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(jsonMapper.writeValueAsString(users));
}
}
class User {
private final String name;
private final int year;
@JsonCreator
public User(@JsonProperty("name") String name, @JsonProperty("year") int year) {
this.name = name;
this.year = year;
}
public String getName() {
return name;
}
public int getYear() {
return year;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", year=" + year +
'}';
}
}
上面的代码打印:
Users read from CSV file:
User{name='1', year=1}
User{name='2', year=2}
User{name='3', year=2}
Users in JSON format:
[ {
"name" : "1",
"year" : 1
}, {
"name" : "2",
"year" : 2
}, {
"name" : "3",
"year" : 2
} ]
添加回答
举报