0

オブジェクトをCSV Stringにシリアル化しようとしましたが、オブジェクトにListがあり、@JsonUnwrappedListオブジェクトでは機能しません。CSVをシリアル化およびデシリアライズするにはどうすればよいですか?

予想されるサンプル出力

color,part.name\n 
red,gearbox\n 
red,door\n 
red,bumper 

実際の出力:(そのほとんどが2 POJOのある)

import com.fasterxml.jackson.annotation.JsonAutoDetect; 
import com.fasterxml.jackson.annotation.JsonFormat; 
import com.fasterxml.jackson.annotation.JsonInclude; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.annotation.JsonPropertyOrder; 
import com.fasterxml.jackson.annotation.JsonRootName; 
import com.fasterxml.jackson.dataformat.csv.CsvMapper; 
import com.fasterxml.jackson.dataformat.csv.CsvSchema; 
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; 
import java.io.IOException; 
import static java.util.Arrays.asList; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class NestedWrapping { 

@JsonRootName("Car") 
@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE) 
@JsonPropertyOrder({"color"}) 
public static class Car { 

    @JsonProperty("color") 
    private String color; 

    @JsonFormat(shape = JsonFormat.Shape.STRING) 
    @JacksonXmlElementWrapper(useWrapping = false) 
    private List<Part> parts; 

    public String getColor() { 
     return color; 
    } 

    public void setColor(String color) { 
     this.color = color; 
    } 

    public List<Part> getParts() { 
     return parts; 
    } 

    public void setParts(List<Part> parts) { 
     this.parts = parts; 
    } 

} 

@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE) 
@JsonPropertyOrder({ 
    "name" 
}) 
public static class Part { 

    @JsonProperty("name") 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

public static void main(String args[]) { 
    try { 
     Car car = new Car(); 
     car.setColor("red"); 
     Part part1 = new Part(); 
     part1.setName("geabox"); 
     Part part2 = new Part(); 
     part2.setName("door"); 
     Part part3 = new Part(); 
     part3.setName("bumper"); 
     car.setParts(asList(part1, part2, part3)); 
     System.out.println("serialized: " + serialize(car, Car.class, true)); 
    } catch (IOException ex) { 
     Logger.getLogger(NestedWrapping.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

public static final synchronized String serialize(final Object object, final Class type, final Boolean withHeaders) throws IOException { 
    CsvMapper csvMapper = new CsvMapper(); 
    CsvSchema csvSchema; 
    if (withHeaders) { 
     csvSchema = csvMapper.schemaFor(type).withHeader(); 
    } else { 
     csvSchema = csvMapper.schemaFor(type).withoutHeader(); 
    } 
    return csvMapper.writer(csvSchema).writeValueAsString(object); 
} 

} 

com.fasterxml.jackson.core.JsonGenerationException: Unrecognized column 'name': 

ここでは私のコードです

何も試してみることはできませんが、私はpostをstackoverflowとgithubで読んでいますが、実際の解決策を見つけることはできません。

残念な点がありますが、何の理由もありません。コードで回答する場合は、気軽に削除してください。

+0

任意の理由は?私が言うことができる限り、あなたは1台の車に多くの部品を持っていますが、CSVがそれを表現する最良のフォーマットだとは思わない –

+0

私はXMLとJSONも使用していますが、私はそれをすべて表現できる必要があります3フォーマット。他の2つはすでに正常に動作しています。 – Hooli

+0

@SotiriosDelimanolis:Done。基本的にデータベースJOINと同じ概念です。 – Hooli

答えて

4

エラーから、私はそれがCarなく"name"値に@JsonPropertyOrderから取られた{"color"}の列がありCarのためにあなたのスキーマとは何かを、持っていると信じたいです。

"parts"をそこに追加したいのですが、"name"がそのスキーマの一部ではないという同じエラーが発生します。

コードを少し変更した後、Carオブジェクトをシリアル化して逆シリアル化することができました。

パートここで

、他のいくつかの変更をした後、それは単一の文字列値を持つコンストラクタを必要とするので、ここで

@JsonPropertyOrder({"name"}) 
public static class Part { 
    @JsonProperty("name") 
    private String name; 

    public Part() { 
     this(""); 
    } 

    public Part(String partJSON) { 
     // TODO: Unserialize the parameter... it is a serialized Part string... 
     this.name = partJSON; 
    } 

カー

、あなたがする必要があることを追加しますList<Part>を手動でCSV形式に変換する方法を実装してください。

このような方法は、クラスの先頭にスキーマを修正することを忘れないでください、また、この

@JsonGetter("parts") 
public String getPartString() { 
    String separator = ";"; 
    StringBuilder sb = new StringBuilder(); 

    Iterator<Part> iter = this.parts.iterator(); 
    while (iter.hasNext()) { 
     Part p = iter.next(); 
     sb.append(p.getName()); 

     if (iter.hasNext()) 
      sb.append(separator); 
    } 

    return sb.toString(); 
} 

ようになり

@JsonPropertyOrder({"color", "parts"}) 
public static class Car { 

    @JsonProperty("color") 
    private String color; 
    @JsonProperty("parts") 
    private List<Part> parts; 

    public Car() { 
     this.parts = new ArrayList<>(); 
    } 

シリアル化

することができますserializeメソッドを変更して、明示的なではなくジェネリック型のパラメータとしてクラスの型を取得します210ように。

​​

メイン - あなたはCarをシリアライズ場合は今ライター

、あなたは

color,parts 
red,gearbox;door;bumper 

がメイン表示されるはずです - 読者

そして、そのCSV文字列を読み取り、ループCar.getParts()

Car car = mapper.readerFor(Car.class).with(csvSchema).readValue(csv); 

for (Part p : car.getParts()) { 
    System.out.println(p.getName()); 
} 
gearbox 
door 
bumper 
+0

遅延応答のお詫び。すべてを明確にしていただきありがとうございます。私は先に行って、動作中のCSVシリアライズ/デシリアライズソリューションを探している人のために、以下の完全なソリューションを投稿しました。 – Hooli

+0

ようこそ。あなたは私のコメントをserializeメソッドのように見ていない –

0

全作業CSV Serializeを & デシリアライズソリューション:あなたはCSV代わりにJSONを使用している

import com.fasterxml.jackson.annotation.JsonGetter; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.annotation.JsonPropertyOrder; 
import com.fasterxml.jackson.databind.MappingIterator; 
import com.fasterxml.jackson.dataformat.csv.CsvMapper; 
import com.fasterxml.jackson.dataformat.csv.CsvSchema; 
import java.io.IOException; 
import java.util.ArrayList; 
import static java.util.Arrays.asList; 
import java.util.Iterator; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class NestedWrapping { 

    @JsonPropertyOrder({"color", "parts"}) 
    public static class Car { 

     @JsonProperty("color") 
     private String color; 

     @JsonProperty("parts") 
     private List<Part> parts; 

     public String getColor() { 
      return color; 
     } 

     public void setColor(String color) { 
      this.color = color; 
     } 

     public List<Part> getParts() { 
      return parts; 
     } 

     public void setParts(List<Part> parts) { 
      this.parts = parts; 
     } 

     public Car() { 
      this.parts = new ArrayList<>(); 
     } 

     @JsonGetter("parts") 
     public String getPartString() { 
      String separator = ";"; 
      StringBuilder sb = new StringBuilder(); 

      Iterator<Part> iter = this.parts.iterator(); 
      while (iter.hasNext()) { 
       Part p = iter.next(); 
       sb.append(p.getName()); 

       if (iter.hasNext()) { 
        sb.append(separator); 
       } 
      } 

      return sb.toString(); 
     } 

     @Override 
     public String toString() { 
      return "Car{" + "color=" + color + ", parts=" + parts + '}'; 
     } 

    } 

    @JsonPropertyOrder({ 
     "name" 
    }) 
    public static class Part { 

     @JsonProperty("name") 
     private String name; 

     public Part() { 
     } 

     public Part(String name) { 
      this.name = name; 
     } 

     public String getName() { 
      return name; 
     } 

     public void setName(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return "Part{" + "name=" + name + '}'; 
     } 

    } 

    public static void main(String args[]) { 
     try { 
      Car car = new Car(); 
      car.setColor("red"); 
      Part part1 = new Part(); 
      part1.setName("geabox"); 
      Part part2 = new Part(); 
      part2.setName("door"); 
      Part part3 = new Part(); 
      part3.setName("bumper"); 
      car.setParts(asList(part1, part2, part3)); 
      String serialized = serialize(car, Car.class, true); 
      System.out.println("serialized: " + serialized); 
      List<Car> deserializedCars = (List) deserialize(serialized, Car.class, true); 
      for (Car deserializedCar : deserializedCars) { 
       System.out.println("deserialized: " + deserializedCar.toString()); 
      } 
     } catch (IOException ex) { 
      Logger.getLogger(NestedWrapping.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public static final synchronized String serialize(final Object object, final Class type, final Boolean withHeaders) throws IOException { 
     CsvMapper csvMapper = new CsvMapper(); 
     CsvSchema csvSchema; 
     if (withHeaders) { 
      csvSchema = csvMapper.schemaFor(type).withHeader(); 
     } else { 
      csvSchema = csvMapper.schemaFor(type).withoutHeader(); 
     } 
     return csvMapper.writer(csvSchema).writeValueAsString(object); 
    } 

    public static final synchronized List<Object> deserialize(final String csv, final Class type, final Boolean hasHeaders) throws IOException { 
     CsvMapper csvMapper = new CsvMapper(); 
     CsvSchema csvSchema; 
     if (hasHeaders) { 
      csvSchema = csvMapper.schemaFor(type).withHeader(); 
     } else { 
      csvSchema = csvMapper.schemaFor(type).withoutHeader(); 
     } 
     MappingIterator<Object> mappingIterator = csvMapper.readerFor(type).with(csvSchema).readValues(csv); 
     List<Object> objects = new ArrayList<>(); 
     while (mappingIterator.hasNext()) { 
      objects.add(mappingIterator.next()); 
     } 
     return objects; 
    } 

} 
関連する問題