java - Unable to read the data back properly -
this question exact duplicate of:
java csv file, supercsv dozer: how avoid looping nested object 1 replyi trying persist person class has list of pets csv file , read corresponding objects. able write unable read. please see below -
person.java
import java.util.arraylist; import java.util.list; public class person { private string name; private list<pet> pets; public person() { } public person(final string name, final list<pet> pets) { this.name = name; this.pets = pets; } /** * @return name */ public string getname() { homecoming name; } /** * @return pets */ public list<pet> getpets() { homecoming pets; } /** * @param pets * pets set */ public void setaddpet(final pet pet) { if (pets == null) { pets = new arraylist<pet>(); } pets.add(pet); } /** * @param name * name set */ public void setname(final string name) { this.name = name; } /** * @param pets * pets set */ public void setpets(final list<pet> pets) { this.pets = pets; } @override public string tostring() { homecoming string.format("person [name=%s, pets=%s]", name, pets); } } pet.java
public class pet { private string typeofanimal; private string color; public pet() { } public pet(final string typeofanimal, final string color) { this.typeofanimal = typeofanimal; this.color = color; } /** * @return color */ public string getcolor() { homecoming color; } /** * @return typeofanimal */ public string gettypeofanimal() { homecoming typeofanimal; } /** * @param color * color set */ public void setcolor(final string color) { this.color = color; } /** * @param typeofanimal * typeofanimal set */ public void settypeofanimal(final string typeofanimal) { this.typeofanimal = typeofanimal; } @override public string tostring() { homecoming string.format("pet [typeofanimal=%s, color=%s]", typeofanimal, color); } } writer.java
import java.io.filewriter; import java.util.arrays; import java.util.list; import org.supercsv.cellprocessor.constraint.notnull; import org.supercsv.cellprocessor.ift.cellprocessor; import org.supercsv.io.dozer.csvdozerbeanwriter; import org.supercsv.io.dozer.icsvdozerbeanwriter; import org.supercsv.prefs.csvpreference; public class author { private static final string[] headers = new string[] { "name", "pets" }; private static final cellprocessor[] processors = new cellprocessor[] { new notnull(), new notnull() }; private static final string csv_filename = "c:\\users\\desktop\\test.csv"; public static void writewithdozercsvbeanwriter() throws exception { // create survey responses write final person person1 = new person("dereck", arrays.aslist(new pet("dog", "black"))); final person person2 = new person("gavin", arrays.aslist(new pet("squirrel", "brown"), new pet("cat", "white"))); final list<person> people = arrays.aslist(person1, person2); icsvdozerbeanwriter beanwriter = null; seek { beanwriter = new csvdozerbeanwriter(new filewriter(csv_filename), csvpreference.standard_preference); // configure mapping fields csv columns beanwriter.configurebeanmapping(person.class, headers); // write header beanwriter.writeheader(headers); // write beans (final person person : people) { beanwriter.write(person, processors); } } { if (beanwriter != null) { beanwriter.close(); } } } } reader.java
import java.io.filereader; import org.supercsv.cellprocessor.optional; import org.supercsv.cellprocessor.constraint.notnull; import org.supercsv.cellprocessor.ift.cellprocessor; import org.supercsv.io.csvbeanreader; import org.supercsv.io.icsvbeanreader; import org.supercsv.prefs.csvpreference; public class reader { private static final string csv_filename = "c:\\users\\desktop\\test.csv"; /** * illustration of reading using csvbeanreader. */ public static void readwithcsvbeanreader() throws exception { icsvbeanreader beanreader = null; seek { beanreader = new csvbeanreader(new filereader(csv_filename), csvpreference.standard_preference); // header elements used map values bean (names must match) final string[] header = beanreader.getheader(true); // set field mapping , processors dynamically final string[] fieldmapping = new string[header.length]; final cellprocessor[] processors = new cellprocessor[header.length]; (int = 0; < header.length; i++) { if (i < 1) { // normal mappings fieldmapping[i] = header[i]; processors[i] = new notnull(); } else { // attribute mappings fieldmapping[i] = "addpet"; processors[i] = new optional(new parsepersonpet(header)); } } person person; while ((person = beanreader.read(person.class, fieldmapping, processors)) != null) { system.out.println(string.format("person=%s", person)); } } { if (beanreader != null) { beanreader.close(); } } } } parsepersonpet.java
import org.supercsv.cellprocessor.cellprocessoradaptor; import org.supercsv.util.csvcontext; public class parsepersonpet extends cellprocessoradaptor { private final string[] header; public parsepersonpet(final string[] header) { this.header = header; } @override public object execute(final object value, final csvcontext context) { if (value == null) { homecoming null; } final pet pet = new pet(); pet.settypeofanimal((string) value); homecoming pet; } } currently, beingness written csv below -
but when read , print it, prints below -
person=person [name=dereck, pets=[pet [typeofanimal=[pet [typeofanimal=dog, color=black]], color=null]]] person=person [name=gavin, pets=[pet [typeofanimal=[pet [typeofanimal=squirrel, color=brown], pet [typeofanimal=cat, color=white]], color=null]]] i know problem in parsepersonpet.java at
pet.settypeofanimal((string) value); but value seems coming string pet [typeofanimal=dog, color=black] have utilize string tokenizer , set appropriate values? quite tedious right? do here?
thanks
update: got code work changing parsepersonpet below -
import org.supercsv.cellprocessor.cellprocessoradaptor; import org.supercsv.util.csvcontext; public class parsepersonpet extends cellprocessoradaptor { private final string[] header; public parsepersonpet(final string[] header) { this.header = header; } @override public object execute(final object value, final csvcontext context) { if (value == null) { homecoming null; } final string str = (string) value; final pet pet = new pet(); pet.settypeofanimal(getvalue("typeofanimal", str)); pet.setcolor(getvalue("color", str)); homecoming pet; } public string getvalue(final string strvaluetosearchfor, final string str) { if (str.contains(strvaluetosearchfor)) { final int startindex = str.lastindexof(strvaluetosearchfor) + strvaluetosearchfor.length() + 1; int endindex = str.indexof(",", startindex); if (endindex == -1) { endindex = str.indexof("]", startindex); } homecoming str.substring(startindex, endindex); } homecoming null; } } i need know how avoid setaddpet , utilize setpets instead , do if have map of pets instead of list.
thanks
you have 2 options. jump 'quick answer' if want.
continue using standard csvbeanreader/writeras you're aware, csvbeanreader , csvbeanwriter can't handle indexed or nested mapping, there has getters/setters on parent class access kid class' fields.
after cell processor execution, super csv phone call tostring() on value escape embedded commas, quotes , newlines necessary. in writer, after notnull() has ensured list not null, it's doing tostring() , escaping. end single pets column in csv file.
if wanted column each pet, you'd have have separate getter (getpet1(), getpet2(), etc) accesses desired pet in list. you'd have know how many pets want back upwards - csv shouldn't have variable columns. i'm imagining you'd want 2 columns each pet - animal type , color - have different getters ((getpet1type(), getpet1color(), etc), or write 2 cell processors (fmtpettype , fmtpetcolor) homecoming type or color.
so csv file like:
name,pet1type,pet1color,pet2type,pet2color jo,dog,black,cat,white quick answer
otherwise, if want maintain tostring pets list (knowing csv file harder other people parse), you'll need write custom cell processor can take tostring()'d list , parse list of pets again. it's bit painful, doable. wouldn't need setaddpet() method then, utilize setpets().
i've seen other question, know you've considered used dozer extension. in case i'd recommend it. csv file i've suggested above configure fieldmapping with:
string[] fieldmapping = {"name","pets[0].typeofanimal","pets[0].color", "pets[1].typeofanimal","pets[1].color"}; and not have worry custom cell processors. if have lot of pets, can create fieldmapping dynamically i've suggested in other question.
java csv dozer supercsv
No comments:
Post a Comment