2013-02-13 3 views
9

Java JDK 1.7 및 Jersey 웹 서비스 프레임 워크를 사용하여 웹 서비스를 작성 중입니다. 내가 제공해야 할 사항 중 하나는 인증 된 클라이언트가 특정 대용량 데이터 파일 (1 ~ 3GB)을 다운로드 할 수있게하는 방법입니다. 이상적으로는이 기능을 일시 중지하고 다시 다운로드 할 수있는 유형을 선택하십시오. 저지 멀티 파트 API를 사용하여 400MB까지 클라이언트 컴퓨터에서 작동 할 수 있었지만 메모리 부족 문제가 발생했습니다. 동시 다운로드 요청에 직면했을 때 서버가 실패 할까봐 걱정됩니다. 이것이 어떻게 행해질 수 있는지에 대한 생각? Netty는 옵션입니까? Netty가 기존의 Jersey 기반 웹 서비스에 통합 될 수있는 방법에 대한 지침은 무엇입니까? 이 작업을 수행하는 데 도움이되는 다른 프레임 작업이 있습니까? 자바를 웹 서비스에 사용해야한다. 모든 포인터가 도움이 될 것입니다.Java Jersey Rest API를 실행하는 HTTP 서버에서 큰 파일 전송

+0

어쩌면 허용 대답이 당신을 너무 도움이 될 수 있습니다 http://stackoverflow.com/questions/10326460/upload-a-large-file-using-jersey-client – Eich

+0

인가 sftp 또는 ftps에 "outsource"하는 옵션이 있습니까? 그런 다음 서버 측을 표준 ftp-server-application으로 관리 할 수 ​​있습니다. 클라이언트 측에는 바로 사용할 수있는 구성 요소가 있습니다. – Fildor

+0

다운로드 만하기 때문에 웹 서비스가 파일을 제공하는 일부 웹 서버 (예 : apache httpd)에 http : 링크를 제공하게하십시오. 아파치 httpd를 통해 프록시를 사용하면 인증을 수행 할 수도 있습니다. –

답변

6

메모리 부족 문제가 계속되는 경우 다운로드중인 데이터를 어떻게 처리하는지 확인해야합니다. Jersey의 ClientResponse를 사용하는 경우 getEntityInputStream()을 사용하고 getEntity()를 사용하지 않아야합니다. 이렇게하면 Java 힙 공간에 데이터를 쌓아두기보다는 데이터를 스트리밍하여 파일에 쓰고 따로 버릴 수 있습니다.

귀하의 동시 다운로드 문제에 관해서는 정말로 말씀 드릴 수 없지만 웹 서비스 프레임 워크를 사용하고 있다면 제대로 처리해야합니다.

두 가지 문제 모두 특정 구현, 특히 코드에 대한 자세한 정보를 통해보다 나은 응답을 얻을 수 있습니다.

2

서버와 클라이언트는 모두 HTTP를 사용하여 데이터를 스트리밍 할 수있는 HTTP 청크 분할 인코딩을 지원해야합니다. 아래 코드는 Jersey 2.11에서 작동합니다.

큰 파일을 다운로드하는 경우, 서버에서 이것을 시도 :

@GET 
@Path("/files/{fileName}") 
@Produces(MediaType.APPLICATION_OCTET_STREAM) 

public StreamingOutput getFile(@PathParam("fileName") final String fileName) throws Exception { 
    //create instance of StreamingOutput here 
    return streamingOutput; 
} 

파일을 다운로드하는 스팀을 사용하여 클라이언트 GET 요청이보십시오.

public String getFileReq(File outFile) throws IOException { 

    client = ClientBuilder.newClient(new ClientConfig()); 
    client.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED"); 
    WebTarget target = client.target(URI) 
    OutputStream fileOutputStream = new FileOutputStream(outFile); 
    InputStream fileInputStream = target.request().get(InputStream.class); 
    writeFile(fileInputStream, fileOutputStream);  

}

public static void writeFile(InputStream fileInputStream, OutputStream outputStream) throws IOException { 
try { 
    byte[] buffer = new byte[1024]; 
    int bytesRead; 

    while((bytesRead = fileInputStream.read(buffer)) !=-1) { 
     outputStream.write(buffer, 0, bytesRead); 
    } 

    fileInputStream.close(); 
    outputStream.flush(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
    outputStream.close(); 
} 
관련 문제