私はjackson-dataformat-csvにCSVヘッダーを含めるのに苦労しています。AutoにはSpring MVCとjackson-dataformat-csvのCSVヘッダーが含まれています
現在、エンティティ(List)のコレクションを出力できますが、ヘッダーが存在しないため、列にタイトルがないため、ファイルを解析できません。
マイMVCの設定(短縮):
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
@Autowired
private Environment env;
public static final String JSON_OBJECT_MAPPER_NAME = "json";
public static final String CSV_OBJECT_MAPPER_NAME = "csv";
private static final TimeZone OUTPUT_DATE_TIMEZONE = TimeZone.getTimeZone(ZoneOffset.UTC);
private static final DateFormat OUTPUT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
@Autowired
@Qualifier(value = JSON_OBJECT_MAPPER_NAME)
private ObjectMapper jsonObjectMapper;
@Autowired
@Qualifier(value = CSV_OBJECT_MAPPER_NAME)
private ObjectMapper csvObjectMapper;
public MvcConfig() {
super();
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true);
configurer.ignoreAcceptHeader(false);
configurer.defaultContentType(MediaType.APPLICATION_JSON);
configurer.useJaf(false);
final Map<String,MediaType> mediaTypes = new HashMap<>();
mediaTypes.put("html", MediaType.TEXT_HTML);
mediaTypes.put("json", MediaType.APPLICATION_JSON);
mediaTypes.put("csv", new MediaType("text","csv", Charset.forName("utf-8")));
configurer.mediaTypes(mediaTypes);
}
@Bean(name = JSON_OBJECT_MAPPER_NAME)
@Primary
public ObjectMapper jsonObjectMapper(){
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(Boolean.parseBoolean(env.getProperty("jsonPrettyPrint")));
builder.timeZone(OUTPUT_DATE_TIMEZONE);
builder.dateFormat(OUTPUT_DATE_FORMAT);
return builder.build();
}
@Bean(name = CSV_OBJECT_MAPPER_NAME)
public ObjectMapper csvObjectMapper(){
CsvMapper csvMapper = new CsvMapper();
//csvMapper.enable(CsvParser.Feature.WRAP_AS_ARRAY);
csvMapper.setTimeZone(OUTPUT_DATE_TIMEZONE);
csvMapper.setDateFormat(OUTPUT_DATE_FORMAT);
csvMapper.registerModule(new CsvMappingModule());
csvMapper.registerModule(new JodaModule());
return csvMapper;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(createJsonHttpMessageConverter());
converters.add(createCsvHttpMessageConverter());
}
private HttpMessageConverter<Object> createJsonHttpMessageConverter() {
return createHttpMessageConverter(jsonObjectMapper, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8);
}
private HttpMessageConverter<Object> createCsvHttpMessageConverter() {
return createHttpMessageConverter(csvObjectMapper, TEXT_CSV);
}
private HttpMessageConverter<Object> createHttpMessageConverter(ObjectMapper objectMapper, MediaType... supportedMediaTypes){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
converter.setSupportedMediaTypes(Lists.newArrayList(supportedMediaTypes));
return converter;
}
}
値のリストをouputをコントローラ:
@Controller
@RequestMapping("/api/history")
public class HistoricController {
@Autowired
public IHistoryService historyService;
@Autowired
public IThingService thingService;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
public List<HistoryDTO> findHistory(@PathVariable("id") Long thingId){
Thing thing = thingService.find(thingId);
return historyService.findByThing(thing);
}
}
Iは、JSON形式で返すことができています:
[
{
"location": {
"id": 101483,
"name": "City A"
},
"dateEnteredLocation": "2016-06-06T18:44:03.000Z",
"dateLeavingLocation": "2016-06-13T13:02:34.000Z"
},
{
"location": {
"id": 101483,
"name": "City A"
},
"dateEnteredLocation": "2016-06-13T16:02:34.000Z",
"dateLeavingLocation": "2016-06-15T11:54:57.000Z"
},
{
"location": {
"id": 101485,
"name": "City C"
},
"dateEnteredLocation": "2016-06-16T04:05:06.000Z",
"dateLeavingLocation": "2016-06-16T11:34:58.000Z"
}
]
しかし、私は、私が入手CSV形式を使用してみてください:
2016-06-06T18:44:03.000Z,2016-06-13T13:02:34.000Z,101483,City A
2016-06-13T16:02:34.000Z,2016-06-15T11:54:57.000ZZ,101483,City A
2016-06-16T04:05:06.000Z,2016-06-16T11:34:58.000Z,101485,City C
をので、CSV形式では、それは大丈夫です。しかし、ヘッダーは含まれていません。 ファイルを人間や機械が理解できるようにするには、ヘッダーが必要です。
jackson csv mapperにヘッダーを自動的に組み込む方法を教えてください。ヘッダーの名前はJson(Entity @Json ...アノテーションを使用)で使用されているものと同じでなければなりません。
可能な限り一般的なものにしたいと考えています。私は、CSV用の特定のMVCコントローラをライターに書かせる必要はありません。
ありがとうございました。私は、フロントエンドでCSVエクスポートを行うことになりました。その主な理由は、私のWeb APIのほとんどがCSVとして表現できない深いjsonオブジェクトを返すということです。 – singe3
@ singe3はい、深いネスティングをサポートすることは困難です。ジャクソンは '@ JsonUnwrapped'でそれをサポートすることができますが、それは迅速で扱いにくく、実際の構造変更が意味をなさないかもしれません。 – StaxMan