2016-01-06 8 views
15

Sometime gdy próbuję przesłać plik na moich odległych VPS i uzyskać ten wyjątek (przystanek wysyłania proccess w 60%)Prześlij plik stop z Nieoczekiwany EOF przeczytać na wyjątek gniazda

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 

aw Google Chrome na connextion traci jak serwer jest w dół, ja dostać ERR_CONNECTION_ABORTED

i przesłać plik jak to wiosną 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()); ; 
     } 

} 

mój kontroler:

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

mój fasola

public class UploadForm { 

    ... 
    public MultipartFile scan; 

Więc jak można rozwiązać ten problem?

+0

Czy operacja nie powiedzie się dla wszystkich rozmiarów plików lub czy małe pliki się powiodą? Czy możesz udostępnić specyficzny dla wiosny kod, który odwzorowuje żądanie na tę metodę? – tdimmig

+0

@tdimmig czasami kończy się niepowodzeniem, a czasami w tym samym rozmiarze jest okey !! aktualizuję moje pytanie. – Youssef

+1

Sprawdź, czy ta odpowiedź może ci pomóc: http://stackoverflow.com/a/18543887/4056187 – robert

Odpowiedz

4

Czy próbowałeś stream?

kod JSP:

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

Kontroler:

@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 

} 

Wszystko, co pracował dla mnie ze sprężyną 4,0 i bezpieczeństwa sprężyny.

Po drugie, należy sprawdzić, czy połączenie http jest ustawione na timeout. Chrome nie obsługuje tej konfiguracji. Więc możesz użyć firefox i śledzić tutaj http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html.

+0

Api api dla pliku jest bezpieczniejsze niż domyślne apki Java dla plików? – Youssef

+0

Użyłem go, tylko dlatego, że jest czysty i przetestowany. Nie sądzę, że jest bezpieczniejsza. – ahll

1

Not sure about the getBytes() metoda na upfile. Bardziej odpowiednim podejściem byłoby użycie InputStream, który będzie zarządzał plikiem o dowolnym rozmiarze i będzie buforował w razie potrzeby. Coś takiego jak:

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()); ; 
    } 

} 
+0

dlaczego 'nowy bajt [1024]'? rozmiar zostanie podzielony przez 1024? – Youssef

+0

możesz zrobić to w dowolnym rozmiarze, 1024 to 1K i zazwyczaj jest to najbardziej wydajny rozmiar do pobrania. Próbowałeś tego? –

+0

Jeszcze nie kiedy wrócę do domu, spróbuję tego. – Youssef

1

Miałem podobne problemy i problem występuje, gdy przesyłasz plik, w którym używasz wielostronicowego formularza Zapytanie POST. Możesz przeczytać o 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-- 

zasadzie kwestią było to, że wniosek został wieloczęściowy z częścią meta informacji, część tekstu i rzeczywisty plik zakodowany wierzę w base64. Każda z tych części jest podzielona granicami. Jeśli nie ustawisz tej granicy (w powyższym przykładzie jest to nazywane "granicą"), poprawnie serwer rozpoczyna czytanie pliku, ale nie wie, gdzie kończy się, dopóki nie dotrze do EOF i zwróci błąd o nieoczekiwanym EOF, ponieważ nie znalazł wymaganego Granic.

Problem z kodem polega na tym, że zapisujesz plik do ByteOutputStream, który jest odpowiedni, gdy zwracasz plik z serwera do użytkownika, a nie odwrotnie. Serwer oczekuje tego żądania wieloczęściowego z pewnym standardowym wstępnie zdefiniowanym formatowaniem. Użyj biblioteki Apache Commons HttpClient, która wykonuje dla Ciebie wszystkie te ustawienia formatowania i granic. Jeśli używasz Mavena, to this link.

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); 

Uwaga: kod nie jest moje To przykład od Apache website for multipart request

+0

OP jest przesyłanie za pomocą przeglądarki, bez kodu klienta? – Michal

+0

Cóż, od jego pytania zrozumiałem, że przesyła z Spring Client, ponieważ powiedział: "Przesyłam taki plik na wiosnę", dlatego założyłem, że przesyła z klienta – MichaelDD

+0

. Chyba miał na myśli coś takiego jak "do". Przesyła za pomocą Google Chrome na klienta i ma Spring MVC po stronie serwera. – Michal

1

Ten problem pojawia się, ponieważ w pobliżu strumienia, aż strumień napisać całą danych.

Niewłaściwy sposób:

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

Prawy sposób:

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

Należy zamknąć strumień po całe dane są zapisywane.

+0

Oczywiście, stream.close() powinien umieścić w bloku finally. – ahll