通过JSON模式将映射转换为JSON字符串

时间:2019-03-08 13:56:21

标签: java jackson

是否可以通过json模式将地图转换为json字符串?我需要通过json模式执行此操作,因为我不知道映射中的对象是字符串还是数字。例如,我的csv如下所示:

name, year
1   , 1

我需要将其转换为json字符串"{'name': '1', 'year': 1}",仅通过json模式,我就可以知道1是字符串(在名称中)还是数字(在年份中)。

5 个答案:

答案 0 :(得分:2)

Jackson有module to parse CSV个文档。假设您的项目中已经有Jackson依赖项,那么jusy需要添加以下内容:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-csv</artifactId>
    <version>${jackson.version}</version>
</dependency>

然后创建一个类来定义您的模式并保存值(注意@JsonPropertyOrder批注,因为它定义了CSV列的顺序):

@JsonPropertyOrder({"name", "year"})
public class Person {

    private String name;
    private Integer year;

    // Getters and setters   
}

将CSV文档解析为一个列表,最后将该列表写入JSON字符串:

CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(Person.class).withHeader();

MappingIterator<Object> iterator = mapper.readerFor(Person.class)
        .with(schema).readValues(new FileInputStream("/path/to/the/csv/file"));

String json = new ObjectMapper().writeValueAsString(iterator.readAll());

答案 1 :(得分:1)

您可以使用Jackson尝试类似的事情:

您唯一需要自己实现的方法是将CsvSchema.json转换为包含列名和列类型的Map的第二种方法。

     public String generateJsonFromCSV() throws IOException {
        File csvFile = new File("path/to/csv/mycsv.csv");
        File schemaJson = new File("path/to/json/schema.json");
        Map<String, CsvSchema.ColumnType> map = getSchemaMapFromJson(schemaJson);
        CsvSchema.Builder schemaBuilder = new CsvSchema.Builder();
        map.forEach(schemaBuilder::addColumn);
        CsvSchema schema = schemaBuilder.build();
        CsvMapper csvMapper = new CsvMapper();
        MappingIterator<Map<?, ?>> mappingIterator = csvMapper.readerFor(Map.class).with(schema).readValues(csvFile);
        String json = new ObjectMapper().writeValueAsString(mappingIterator.readAll());
        return json;
    }

    //Convert your JsonSchema to Map<String,CsvSchema.ColumnType>
    private Map<String, CsvSchema.ColumnType> getSchemaMapFromJson(File file) {
        return new HashMap<>();
    }

依赖性:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-csv</artifactId>
    <version>${jackson.version}</version>
</dependency>

答案 2 :(得分:0)

您可以使用org.json库:

Map<String, Object> map = new HashMap<>();
map.put("name", "1");
map.put("year", 1);
org.json.JSONObject obj = new org.json.JSONObject(map);
System.out.println(obj.toString());

输出:

{"year":1,"name":"1"}

答案 3 :(得分:0)

您可以使用GSON。 这是非常容易使用和非常强大的。 现在,我已经能够解决这个库的所有问题。 (https://github.com/google/gson

// your map
Map<String, Object> map = new HashMap<>();
map.put("name", "1");
map.put("year", 1);

// create Gson instance
Gson gson = new GsonBuilder().create();

// convert to JSON
String jsonString = gson.toJson(map);

// convert back to map
Map map = gson.fromJson(jsonString, Map.class);

答案 4 :(得分:-1)

在阅读您的评论后,我建议您需要这样做。 这是一个简单的Java解决方案。我想有些库可以帮助您解析csv。 希望我能为您提供帮助

给出CSV:

using System;

namespace BinarySearchFast
{
    public class BinarySearchFast
    {
        // csharp version, assuming compiler removes the inner branch, there should be almost no branching impact    
        // if index not found, returns ~(index of element to insert sorted) at.
        public static int BinarySearchFast<T>(T[] array, T value) where T : IComparable<T>
        {
            if (array == null || array.Length == 0 || value == null)
            {
                return -1;
            }
            int start;
            int mid;
            int end;
            int cmp = -1;
            start = 0;
            end = array.Length - 1;
            mid = (start + end) / 2;
            while (start <= end && (cmp = array[mid].CompareTo(value)) != 0)
            {
                // I *think* any good compiler will optimize this to avoid the branch by using a lerp based on cmp > 0 for end and start
                // something like:
                // end = lerp(end, mid - 1, cmp > 0);
                // start = lerp(mid + 1, start, cmp > 0);
                // but if not, the lerp could be inserted instead for C/C++, C# does not allow easy conversion of bool to int outside of System.Convert or an if statement.
                if (cmp > 0)
                {
                    end = mid - 1;
                }
                else
                {
                    start = mid + 1;
                }
                mid = (start + end) >> 1;
            }
            // could also replace with return lerp(~(++mid), mid, (cmp == 0));
            return (cmp == 0 ? mid : ~(++mid));
        }
    }
}

Java代码:

name,year
1,1
test,38
foo,78

输出将是:

    try {
        File file = ResourceUtils.getFile(this.getClass().getResource("/import.csv"));
        List<List<String>> lines = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                lines.add(Arrays.asList(values));
            }
        }

        Map<String,Integer> resultMap = new HashMap<>();
        for (int i = 1; i < lines.size(); i++) {
            List<String> currentLine = lines.get(i);
            String name = currentLine.get(0);
            String year = currentLine.get(1);
            if(StringUtils.isNoneEmpty(name,year) && StringUtils.isNumeric(year)){
                resultMap.put(name,Integer.valueOf(year));
            }
        }

        Gson gson = new GsonBuilder().create();
        String jsonString = gson.toJson(resultMap);
        System.out.println(jsonString);

    } catch (IOException e) {
        System.out.println(e);
    }