9

여기 내가하고있는 일이 있습니다. 스프링 웹 애플리케이션에 Ajax를 통해 멀티 파트 파일을 업로드하고 싶습니다. 서버가 POST 요청을 받으면 데이터베이스에 티켓 번호를 작성합니다. 그런 다음 실제 파일 업로드를 처리하는 스레드를 시작합니다. 그런 다음 서버는 티켓 번호를 반환합니다.비동기 파일 업로드 (스프링)

요청을 처리하기 위해 CommonsMultipartResolver를 사용하고 있으며, Multipart가 즉시 해결되지 않도록 resolveLazily 플래그를 true로 설정했습니다.

그래서 여기 그래서 여기에 포인트가 티켓 번호는 진행 업데이트를 가져 오는 데 사용할 수 있다는 것입니다 내가

@Controller 
public class myController{ 

    @RequestMapping(value = "/upload", method = RequestMethod.POST) 
    @ResponseStatus(value = HttpStatus.OK) 
    @ResponseBody 
    public String upload(MultipartHttpServletRequest request, String fileName){ 

     String ticket = dao.createUploadTicket(fileName); 
     Runnable run = new Runnable(){ 

      @Override 
      public void run(){ 

       dao.writeUpdate(ticket, "Getting data from request"); 
       final MultipartFile file = request.getFile("theFile"); 
       dao.writeUpdate(ticket, "Multipart file processed"); 
       try { 
        dao.writeUpdate(ticket, "Saving file to disk"); 
        file.transferTo(new File("/myDirectory")); 
        dao.writeUpdate(ticket, "File saved to disk"); 
       } 
       catch(Exception e){ 
        dao.writeUpdate(ticket, "File upload failed with the exception " + e.toString()); 
       } 
      } 
     }; 
     Thread t = new Thread(run); 
     t.start(); 
     return ticket; 
    } 
} 

을 가지고있는의 라인을 따라 뭔가. 큰 파일이 업로드되고 있다고 가정 해보십시오. 파일을 POST로 업로드 한 클라이언트 (이 경우 Ajax 요청)는이를 비동기 적으로 수행하고 티켓 번호를 다시받을 수 있습니다. 클라이언트는 티켓 번호를 사용하여 파일 업로드 단계를 결정하고 다른 페이지에 정보를 표시 할 수 있습니다.

다른 사용법은 서버에 모든 티켓 번호를 요청한 HTML 페이지를 가질 수 있으며 서버에서 발생하는 모든 파일 업로드의 "라이브"보기를 보여줍니다.

컨트롤러가 리턴하자마자 Spring은 CommonsMultipartResolver에서 cleanupMultipart()를 호출하기 때문에 이것을 작동시키지 못했습니다. resolveLazily 플래그가 false로 설정되어 있으므로 cleanupMultipart()가 호출되면 멀티 파트 파일을 확인하고 초기화합니다. 이로 인해 "request.getFile ("theFile ");" runnable 및 cleanupMultipart() 호출에서 결국 예외가 발생합니다.

누구든지 아이디어가 있습니까? 백엔드 비동기 파일 처리를 원한다는 이유로 여기에서 HTTP 계약을 위반하고 있습니다.

+0

Commention 비동기 언제 나중에, 티켓의 현재 상태를 가져옵니다. 나는 해결책을 내놓는 것을 도울지도 모른다 뒤에 오는 블로그를 찾아 냈다. http://blog.springsource.org/2012/05/06/spring-mvc-3-2-preview-introducing-servlet-3-async-support/ https://blogs.oracle.com/ enterprisetechtips/entry/asynchronous_support_in_servlet_3 실례를 생각해 보면 다시 게시하겠습니다. – CAL5101

답변

5

HTTP 요청은 이미 자체 스레드에서 실행되며 클라이언트는 비동기 적으로 병렬로 요청할 수 없습니다. 따라서 새로운 스레드를 시작할 필요가 없습니다. 메인 스레드에서 평상시처럼 파일을 저장/처리하십시오. 클라이언트 측에서만 '비동기 파일 업로드'을 작성하십시오.

또한 입력을 처리 한 경우에만 http 응답을 보내야합니다. 제 말은 입력 헤더를 읽고 http 응답을 작성하고 브라우저에서 데이터를 계속 읽을 수 없다는 것입니다. 소비 입력 -> 처리 -> 출력 보내기, HTTP 1/1.1 프로토콜 작동 방법.

업로드 보낼 티켓 번호가 필요한 경우, 당신은 실제 업로드 전에처럼, 두 단계 업로드를 사용하여 만들 수 있습니다

  • 아약스 티켓 번호
  • POST a를 얻을 GET 요청 파일 내용과 (이전 단계에서 수신) 티켓 번호
  • + 아약스 내 자신의 게시물에
+0

가 동의합니다.나는 약간의 설명을 추가하고 싶다 : user1404399가 물어 보는 것은 서버 사이드의 새로운 쓰레드에 의해 "async upload"하는 법이다.이 문제를 처리하는 올바른 방법은 javascript로 handle-uploading 액션을 만드는 것이다. 다른 작업으로 폴링하여 진행 상황을 사용자에게보고합니다. 그게 당신 생각인가요? –

+0

@ HoàngLong right –

+0

답장을 보내 주셔서 감사합니다. 나는 이것이 가능하지 않다는 느낌이 좋았지 만 해결책을 찾기 위해 밀려났습니다. 우리는 아무것도 정상적으로 파일 업로드를 구현하지 못했습니다. P. 내 표시 이름을 user1404399보다 읽기 쉬운 것으로 업데이트했습니다. – CAL5101