2016-08-03 12 views
0

私は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 ma​​pperにヘッダーを自動的に組み込む方法を教えてください。ヘッダーの名前はJson(Entity @Json ...アノテーションを使用)で使用されているものと同じでなければなりません。

可能な限り一般的なものにしたいと考えています。私は、CSV用の特定のMVCコントローラをライターに書かせる必要はありません。

答えて

0

ジャクソンが使用するメカニズムはCsvSchemaheaderが有効になっているためにニーズを使用したことなので、何かのように:

CsvMapper mapper = new CsvMapper(); CsvSchema schema = CsvSchema.emptySchema().withHeader(); String csv = mapper.writer(schema).writeValueAsString(...);

挑戦その後、使用するCsvSchemaに合格する方法のことです。可能であればCsvWriterを使用するように構成されています。 Spring MVCが明示的にサポートしているかどうかはわかりません。

+0

ありがとうございました。私は、フロントエンドでCSVエクスポートを行うことになりました。その主な理由は、私のWeb APIのほとんどがCSVとして表現できない深いjsonオブジェクトを返すということです。 – singe3

+0

@ singe3はい、深いネスティングをサポートすることは困難です。ジャクソンは '@ JsonUnwrapped'でそれをサポートすることができますが、それは迅速で扱いにくく、実際の構造変更が意味をなさないかもしれません。 – StaxMan

関連する問題