使用JacksonRepresentation编写多行CSV

时间:2014-07-04 07:54:16

标签: java csv jackson restlet

我正在研究一个Restlet servlet,它应该能够以不同的格式提供多行数据(现在是XML,JSON,CSV)。

我决定让杰克逊将我的POJO映射到不同的格式,并尝试使用JacksonRepresentation(Restlet扩展)来达到这个目的,但是我在使CSV位工作时遇到了一些麻烦。

如果我使用以下任一JacksonRepresentation构造函数:

List<MyBean> beansList = getBeans(); // Query database etc.
MyBean[] beansArr = beansList.toArray(new MyBean[beansList.size()]);

// Tried all the following 
JacksonRepresentation<MyBean[]> result = new JacksonRepresentation<MyBean[]>(MediaType.TEXT_CSV, beansArr);

JacksonRepresentation<List<MyBean>> result = new JacksonRepresentation<List<MyBean>>(MediaType.TEXT_CSV, beansList);

JacksonRepresentation<ListWrapper> result = new JacksonRepresentation<ListWrapper>(MediaType.TEXT_CSV, new ListWrapper(beansList));

JacksonRepresentation<ArrayWrapper> result = new JacksonRepresentation<ArrayWrapper>(MediaType.TEXT_CSV, new ArrayWrapper(beansArr));


// Explicit schema shouldn't be necessary, since the beans are already annotated
CsvSchema csvSchema = CsvSchema.builder()
        .addColumn("productcode", ColumnType.STRING)
        .addColumn("quantity", ColumnType.NUMBER)
.build();

result.setCsvSchema(csvSchema);

return result;

我得到一个例外:

com.fasterxml.jackson.core.JsonGenerationException: Unrecognized column 'productcode': known columns: ]

但如果我坚持一个对象/行:

JacksonRepresentation<MyBean> result = new JacksonRepresentation<MyBean>(MediaType.TEXT_CSV, beansArr[0]);

我得到了一个包含一行数据的漂亮,有效的CSV文件。

对于JSON,数组包装器方法似乎是为多个对象执行此操作的方法,但我不能为我的生活找出如何制作多行CSV ...

示例bean和包装器:

@JsonPropertyOrder({ "productcode", "quantity" ... })
public class MyBean {

    private String productcode;

    private float quantity;

    public String getProductcode() {
        return productcode;
    }

    public void setProductcode(String productcode) {
        this.productcode = productcode;
    }

    .
    .
    .
}


public class ListWrapper {

    private List<MyBean> beans;

    public ListWrapper(List<MyBean> beans) {
        setBeans(beans);
    }

    public void setBeans(List<MyBean> beans) {
        this.beans = beans;
    }

    public List<MyBean> getBeans() {
        return beans;
    }
}

public class ArrayWrapper {

    private MyBean[] beans;

    public ArrayWrapper(MyBean[] beans) {
        setBeans(beans);
    }

    public void setBeans(MyBean[] beans) {
        this.beans = beans;
    }

    public MyBean[] beans getBeans() {
        return beans;
    }
}

1 个答案:

答案 0 :(得分:1)

我认为目前的代码存在错误。 CSV映射器未正确计算。

我已经为此输入了一个问题(https://github.com/restlet/restlet-framework-java/issues/928),感谢您报告此问题。

作为一种解决方法,我建议你创建JacksonRepresentation如下:

rep = new JacksonRepresentation<MyBean[]>(MediaType.TEXT_CSV, tab) {
    @Override
    protected ObjectWriter createObjectWriter() {
        CsvMapper csvMapper = (CsvMapper) getObjectMapper();
        CsvSchema csvSchema = csvMapper.schemaFor(MyBean.class);
        ObjectWriter result = csvMapper.writer(csvSchema);
        return result;
    }
};

它也适用于豆类列表。