Irwene
Irwene

Reputation: 3035

How to have a properly encoded Stream when uploading an ANSI file with Vaadin Upload component

I'd like to upload an ANSI file (ISO-8859-1), it contains characters such as (é, è, à, ê, and others).

In a dummy project i wrote this :

package com.mic;

import com.vaadin.cdi.CDIUI;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.server.FileDownloader;
import com.vaadin.server.StreamResource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.AbstractSelect;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.UI;
import com.vaadin.ui.Upload;
import com.vaadin.ui.VerticalLayout;
import java.io.*;

/**
 *
 * @author stagiaire
 */
@CDIUI
public class TestCDIUI extends UI {



    @Override
    protected void init(VaadinRequest request) 
    {
        VerticalLayout verticalLayout = new VerticalLayout();
        Upload upload = new Upload("Merci de sélectionner le fichier à importer", null);
        upload.setButtonCaption("Importer");
        verticalLayout.addComponent(upload);
        FileUploader uploader = new FileUploader();
        upload.setReceiver(uploader);
        upload.addSucceededListener(uploader);
        setContent(verticalLayout);

    }
}

And the class FileUploader is the following one :

package com.mic;

import com.vaadin.ui.Upload;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.StringReader;

class FileUploader implements Upload.Receiver, Upload.SucceededListener
    {
        private OutputStream os;       
        @Override
        public OutputStream receiveUpload(String filename, String mimeType) {

            this.os = new ByteArrayOutputStream();
            return this.os;//On retourne le flux dans lequel le controle ecrira le contenu du fichier uploadé
        }

        @Override
        public void uploadSucceeded(Upload.SucceededEvent event) 
        {
            System.out.println(this.getStringContent());

        }

        public String getStringContent()
        {
            return this.os.toString();
        }

        public BufferedReader getReader()
        {
            return new BufferedReader(new StringReader(this.getStringContent()));
        }

    }

And with that code i have this kind of output :

P�dago;Ann�e;Mois;Semaine;Nb jours;Date;Matin / Apr�s-midi;Heures;Code analytique;Intitul� des modules;Intervenants;Hono pr�visionnels;Partage (coef.);Nb salles;Ann�e apprentissage;CA
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2012;7;;0,5j;25/07/2012;1;4h;NT1N2143;Revision .NET;OBER;300;1;1;;300
;2012;7;;0,5j;27/07/2012;2;4h;NT1N2143;Revision .NET;AGUESSE;250;1;1;;250
;2013;6;;0,5j;15/06/2013;1;4h;NT1N2143;Revision .NET;VALL;200;1;1;;200
;2013;6;;0,5j;15/06/2013;2;4h;NT1N2143;Revision .NET;VALL;500;1;1;;500

But what was in the uploaded file was :

Pédago;Année;Mois;Semaine;Nb jours;Date;Matin / Après-midi;Heures;Code analytique;Intitulé des modules;Intervenants;Hono prévisionnels;Partage (coef.);Nb salles;Année apprentissage;CA
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2012;7;;0,5j;25/07/2012;1;4h;NT1N2143;Revision .NET;OBER;300;1;1;;300
;2012;7;;0,5j;27/07/2012;2;4h;NT1N2143;Revision .NET;AGUESSE;250;1;1;;250
;2013;6;;0,5j;15/06/2013;1;4h;NT1N2143;Revision .NET;VALL;200;1;1;;200
;2013;6;;0,5j;15/06/2013;2;4h;NT1N2143;Revision .NET;VALL;500;1;1;;500

The uploaded file was encoded in ISO-8859-1 and produced the above output. When i convert it manually into an UTF-8 encoded file, no problem, i have a correct output. The problem is : the file is generated by Excel and i can't change the encoding.

I Already searched the vaadin Book/API for that and didn't found a clue.

Also tried this for the uploadSuceeded method :

public void uploadSucceeded(Upload.SucceededEvent event) 
        {
            try
            {
                OutputStream out = new ByteArrayOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(out, "8859_1");
                osw.write(getStringContent());
                osw.close();
                System.out.println(out.toString());
            }
            catch (Exception e)
            {
                System.out.println(e);
            }


        }

And this was the new output :

P?dago;Ann?e;Mois;Semaine;Nb jours;Date;Matin / Apr?s-midi;Heures;Code analytique;Intitul? des modules;Intervenants;Hono pr?visionnels;Partage (coef.);Nb salles;Ann?e apprentissage;CA
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2011;4;17;0,5j;22/04/2011;1;4h;NT1N2143;Revision .NET;MCY;0;1;1;;0
;2012;7;;0,5j;25/07/2012;1;4h;NT1N2143;Revision .NET;OBER;300;1;1;;300
;2012;7;;0,5j;27/07/2012;2;4h;NT1N2143;Revision .NET;AGUESSE;250;1;1;;250
;2013;6;;0,5j;15/06/2013;1;4h;NT1N2143;Revision .NET;VALL;200;1;1;;200
;2013;6;;0,5j;15/06/2013;2;4h;NT1N2143;Revision .NET;VALL;500;1;1;;500

So it wasn't really a sucess....

If any of you had an idea about that i'll be really grateful.

Upvotes: 0

Views: 1306

Answers (1)

Irwene
Irwene

Reputation: 3035

Found the solution The Upload component of Vaadin is writing in the ouputStream provided in the recieveUpload method in the FileUploader class.

The file uploaded is not changed at this point. This means that we just have to make java understand that it have to read the Stream using a latin-1/9 Charset. Because without that he don't know which encoding it is and use the default platform charset : UTF-8 (in my case)

This is done doing this in the uploadSucceeded method :

public void uploadSucceeded(Upload.SucceededEvent event) 
        {
            try
            {
                OutputStream out = new ByteArrayOutputStream();
                out.write(getStringContent().getBytes(Charset.forName("8859_1")));
                out.close();
                System.out.println(out.toString());
            }
            catch (Exception e)
            {
                System.out.println(e);
            }


        }

Here, we are creating a new stream in which we are writing the latin1/9 encoded version of the String contained in the original Stream

And when displaying this stream... No problem at all we have a correct output.

Hope this will help

Upvotes: 1

Related Questions