web-dev-qa-db-fra.com

Téléchargement du fichier arrêté avec une inattendue EOF lu sur le socket Exception

Parfois, lorsque j'essaie de télécharger un fichier sur mon vps distant, j'obtiens cette exception (le processus de téléchargement s'arrête à 60%)

06-Jan-2016 11:59:36.801 SEVERE [http-nio-54000-exec-9] org.Apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Request processing failed;
nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request;
nested exception is org.Apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket]
with root cause
 Java.io.EOFException: Unexpected EOF read on the socket

et en Google Chrome la connexion est perdue comme le serveur est en panne, j'obtiens ERR_CONNECTION_ABORTED

je télécharge un fichier comme celui-ci au printemps mvc

public void save_file(MultipartFile upfile , String path){

        try {

            File fichier = new File( path ) ;
            byte[] bytes = upfile.getBytes();
            BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
            stream.write(bytes);
            stream.close();
            System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );

        } catch (Exception e) {
            System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
        }

}

mon contrôleur:

@RequestMapping(value = "/administration/upload", method = RequestMethod.POST)
public String Upload_AO_journal(
        @ModelAttribute  UploadForm uploadForm,
                Model map , HttpServletRequest request, HttpSession session ) throws ParseException, UnsupportedEncodingException {

mon haricot

public class UploadForm {

    ...
    public MultipartFile scan;

Alors, comment résoudre ce problème?

16
Youssef

Avez-vous essayé le streaming?

Code JSP:

<form method="POST" onsubmit="" ACTION="url?${_csrf.parameterName}=${_csrf.token}" ENCTYPE="multipart/form-data">

Manette:

 @RequestMapping(
        value = "url", method = RequestMethod.POST
)
public void uploadFile(
        @RequestParam("file") MultipartFile file
) throws IOException {

 InputStream input = upfile.getInputStream();
 Path path = Paths.get(path);//check path
 OutputStream output = Files.newOutputStream(path);
 IOUtils.copy(in, out); //org.Apache.commons.io.IOUtils or you can create IOUtils.copy

}

Tout cela a fonctionné pour moi avec le printemps 4.0 et la sécurité du printemps.

Deuxièmement, vous devez vérifier si la connexion http a expiré. Chrome ne prend pas en charge cette configuration. Vous pouvez donc utiliser Firefox et suivre ici http://morgb.blogspot.com.es/2014/05/firefox-29-and- http-response-timeout.html .

5
ahll

Ce problème se produit car vous fermez le flux jusqu'à ce que le flux écrive des données entières.

Fausse route:

stream.write(bytes);
stream.close();

La bonne façon:

try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier))) 
{
    stream.write(data);
}

Vous devez fermer votre flux une fois les données entières écrites.

2
eg04lt3r

Pas sûr de la méthode getBytes () sur le fichier upfile. Une approche plus appropriée consisterait à utiliser InputStream qui gérera n'importe quel fichier de taille et mettra en mémoire tampon si nécessaire. Quelque chose comme:

public void save_file(MultipartFile upfile , String path){

    try {
        File fichier = new File( path ) ;
        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
        InputStream is = upfile.getInputStream();
        byte [] bytes = new byte[1024];
        int sizeRead;
        while ((sizeRead = is.read(bytes,0, 1024)) > 0) {
            stream.write(bytes, 0, sizeRead);
        }
        stream.flush();
        stream.close();
        System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );

    } catch (Exception e) {
        System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
    }

}
1
Mike Murphy

J'ai eu des problèmes similaires et le problème est que lorsque vous téléchargez un fichier, vous utilisez le formulaire en plusieurs parties POST Request. Vous pouvez lire environ MIME =.

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier

This is a message with multiple parts in MIME format.
--frontier
Content-Type: text/plain

This is the body of the message.
--frontier
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64

PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--frontier--

Fondamentalement, le problème que j'avais était que la partie multiple de la demande avait une partie méta-information, une partie texte et un fichier réel codé, je crois en base64. Chacune de ces parties est divisée par limite. Si vous ne configurez pas cette limite (dans l'exemple ci-dessus, elle est appelée "frontière"), le serveur commence à lire le fichier mais ne sait pas où il se termine jusqu'à ce qu'il atteigne EOF et renvoie une erreur à propos de inattendu EOF car il n'a pas trouvé les limites requises.

Le problème avec votre code est que vous écrivez un fichier dans ByteOutputStream, ce qui convient lorsque vous retournez un fichier du serveur à l'utilisateur, et non l'inverse. Le serveur attend cette demande en plusieurs parties avec un formatage prédéfini standard. Utilisez Apache Commons HttpClient bibliothèque qui fait tout le formatage des demandes et la définition des limites pour vous. Si vous utilisez Maven alors ce lien .

File f = new File("/path/fileToUpload.txt");
PostMethod filePost = new PostMethod("http://Host/some_path");
Part[] parts = {
  new StringPart("param_name", "value"),
  new FilePart(f.getName(), f)
};
filePost.setRequestEntity(
  new MultipartRequestEntity(parts, filePost.getParams())
  );
HttpClient client = new HttpClient();
int status = client.executeMethod(filePost);

Avertissement: le code n'est pas le mien, il est un exemple de site Web Apache pour une demande en plusieurs parties

1
MichaelDD