Я работаю над сервлетом Restlet, который должен быть способен обслуживать несколько строк данных в разных форматах (XML, JSON, CSV сейчас).
Я поселился в Jackson для сопоставления своих 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 и wrappers:
@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;
}
}
Я думаю, что в текущем коде есть ошибка. Картограф 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;
}
};
Он также работает со списком бобов.