2012-05-14 2 views
2

문서를 읽고 인터넷에서 몇 가지 팁을 검색하는 데 많은 시간을 소비 한 끝에 마침내 스택 오버플로 계정을 만들기로 결정했습니다. 필사적으로 보입니까? 하하, 가자.부품을 사용한 Amazon S3 다중 파일 업로드

EDIT (05/16/2012) : 해결책을 찾았을 때 (마침내 혼자서) 이전 코드를 실행 코드로 바꿨습니다.

내 데이터베이스에서 이미지 (URL) 레코드 컬렉션을 가져 오는/admin/lstimg (ListImage)로 이동합니다. 그런 다음 컬렉션은 jsp 파일의 데이터를 사용할 수있는 특성으로 설정됩니다.

참고 : ListImageServlet 공용 클래스는 HttpServlet으로 확장되며 MultipartConfig으로 주석 처리됩니다.

@Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException 
    { 
     try 
     { 
      Collection images = ImageFacade.getIjc().findImageEntities(); 
      request.setAttribute("images", images); 
      request.getRequestDispatcher("/adm/img/lstimg.jsp").forward(request, response); 
     } 

     catch (Exception ex) 
     { 
      Logger.getLogger(ListImageServlet.class.getName()).log(Level.SEVERE, "Cannot retrieve the images.", ex); 
     } 
    } 

내 jsp에는 큰 이미지가 있습니다 ("이미지"컬렉션이 있음). 여기에서는 "images"컬렉션의 데이터를 사용합니다. 각 이미지의 첫 번째 열에는 축소판이 있고 두 번째 열에는 파일 입력이 있습니다. 이 (단일) 양식을 통해 여러 업데이트를 수행하려고합니다.

<form method="post" action="../admin/lstimg" enctype="multipart/form-data"> 
<table> 
    <thead> 
     <tr> 
      <th>Thumb</th> 
      <th>to update</th> 
     </tr> 
    </thead> 
    <tbody> 
     <c:forEach items="${images}" var="image"> 
      <tr> 
       <td> 
        <img src="myURL" height="100"/> 
       </td> 
       <td> 
        <input type="file" name="${image.thumb}"/> 
       </td> 
      </tr> 
     </c:forEach> 
    </tbody> 
</table> 
<input type="submit" value="Proceed" /> 
</form> 

내 첫 번째 질문은 다음과 같습니다 나는 (열쇠) 같은 "image.thumb"을 가지고 새로운 이미지가 필요, 나는 현재 "image.thumb"에 파일 입력 이름을 설정하지만, 컴퓨터에서 파일을 검색 할 때 몇 가지 문제가 있는지 궁금합니다. 내 컴퓨터의 파일은 자체 경로/파일 이름을 가지므로 내 서버의 파일은 다른 경로/UUID (키)를 갖습니다.

EDIT (05/16/2012) : AWS가 (수동으로 설정하는) 파일 경로를 요구하지 않으므로이 문제는 발생하지 않습니다.

어떻게 양식 외모 ( Web Browser)

내가/변경을 업데이트해야 이미지 (들)을 choosed 할 후, 내가 제출 버튼 (진행)를 클릭합니다.

  1. 모든 부품 (파일 입력)을 가져 와서 "allParts"컬렉션에 저장합니다.
  2. "allParts"컬렉션의 모든 부분을 확인합니다. 파일 크기가 1b와 10Mo 사이에 있으면 해당 부분이 "selectedParts"컬렉션에 추가됩니다.
  3. 여기서는 원하는 작업을 수행하는 방법을 모르겠습니다 ... 내 모든 이미지가 Amazon S3 서버에서 호스팅됩니다. 나는 Jets3t Toolkit을 사용한다. 첫 번째 업로드의 경우 buildPostForm 메서드 (아래)를 호출하고 모든 작업을 수행합니다. 업로드/난 내 자신의 양식을 사용, 나는 내 S3Object에 파일을 설정해야합니다, 서블릿을 통해 파일을 변경하려면,하지만 난 안 :
S3Service.buildPostForm(String bucketName, String key, ProviderCredentials credentials, Date expiration, String[] conditions, String[] inputFields, String textInput, boolean isSecureHttp);

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException 
    { 
     try 
     { 
      ImageCheck.initAS3(request); 
      ImageCheck.update(request, response); 
     } 

     catch (S3ServiceException ex) 
     { 
      Logger.getLogger(ListImageServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     catch (ServiceException ex) 
     { 
      Logger.getLogger(ListImageServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     catch (NoSuchAlgorithmException ex) 
     { 
      Logger.getLogger(ListImageServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     catch (IllegalStateException ex) 
     { 
      Logger.getLogger(ListImageServlet.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     response.sendRedirect("../admin/lstimg"); 
    } 

내 두 번째 질문은 내 "selectedParts"로 내가 뭘 할 수 있는지 알아? 파트를 파일로 변경하는 방법이 있습니까? Part 이외의 다른 것을 사용해야합니까?

EDIT (2012년 5월 16일) : 내 영어에 대한 My solution

죄송합니다. 제안, 조언, 답변을 미리 보내 주셔서 감사합니다. 코드와 관련하여 질문이 있거나 더 궁금한 점이 있으시면 언제든지 주저하지 마십시오.

답변

1

저는 S3Object#S3Object(java.io.File)에 집중하여 StorageObject#setDataInputStream을 사용할 수 있음을 깨닫지 못했습니다.

이전 이미지 키를 새 이미지 키로 설정 했으므로 새로운 문제는 캐시에 이전 이미지를 유지하는 웹 브라우저입니다. 나는이 일에 많은 시간을 보냈는데, 내가 실수를 범할 수있는 곳조차 알지 못했다고하더라도 내 기능이 제대로 작동하지 않는다고 생각했다. 하지만 필자는 AWS를 사용하여 성공적으로 업데이트 된 'Last Modified'값을 확인했습니다. 나는 내 캐시를 지웠고 모든 것이 처음부터 괜찮다고 생각했습니다.

일부 도움이 될 수 있다면, 단일 양식을 통해 여러 S3Object를 변경할 수있는 기능을 제공합니다. 질문이나 제안 사항이 있거나 해당 코드에 대한 의견이 필요한 경우 여기에 있습니다.

public static void upload(HttpServletRequest request, Part part, S3Service s3Service, S3Bucket s3Bucket) 
     throws S3ServiceException, NoSuchAlgorithmException, IOException 
{ 
    S3Object s3Object = new S3Object(); 
    s3Object.setDataInputStream(part.getInputStream()); 
    s3Object.setKey(part.getName()); 
    s3Object.setContentLength(part.getSize()); 
    s3Object.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); 
    s3Service.putObject(s3Bucket, s3Object); 
} 

     public static void update(HttpServletRequest request) 
     throws S3ServiceException, ServiceException, NoSuchAlgorithmException, IOException, IllegalStateException, ServletException 
{ 
    AWSCredentials awsCredentials = (AWSCredentials) request.getSession().getAttribute("awsCredentials"); 
    S3Service s3Service = (S3Service) request.getSession().getAttribute("s3Service"); 
    S3Bucket s3Bucket = (S3Bucket) request.getSession().getAttribute("s3Bucket"); 
    String bucketName = (String) request.getSession().getAttribute("bucketName"); 

    String prefix = "uploads/"; 
    String delimiter = null; 
    S3Object[] filteredObjects = s3Service.listObjects(bucketName, prefix, delimiter); 

    Collection<Part> allParts = request.getParts(); 
    Collection<Part> selectedParts = new ArrayList<Part>(); 
    Collection<String> keys = new ArrayList<String>(); 

    for (Part part : allParts) 
    { 
     if (part.getSize()>1 && part.getSize()<10485760) 
     { 
      selectedParts.add(part); 
     } 
    } 

    for (int o = 0; o < filteredObjects.length; o++) 
    { 
     String keyObject = filteredObjects[o].getName(); 
     keys.add(keyObject); 
    } 

    if (selectedParts.size() > 0) 
    { 
     for (Part part : selectedParts) 
     { 
      if (keys.contains(part.getName())) 
      { 
       s3Service.deleteObject(s3Bucket, part.getName()); 
       upload(request, part, s3Service, s3Bucket); 
      } 

      else 
      { 
       selectedParts.remove(part); 
      } 
     } 
    } 

    else 
    { 
     String ex = "No file to update."; 
     exceptions.add(ex); 
    } 
} 
0

javadocPart입니다.입력 필드의 이름은 Part#getName()입니다.

String name = part.getName(); 

업로드 된 파일의 내용은 Part#getInputStream()입니다.

InputStream content = part.getInputStream(); 

당신은 그것을 읽고 임의의 OutputStreamthe usual Java I/O way에 기록 할 수 있습니다. 예 : FileOutputStream. 그러나 나는 궁극적으로 무엇을 File으로해야하는지 확신하지 못합니다. DB에 저장하는 것이 유일한 목적이라면 먼저 디스크에 저장하는 대신 InputStream을 직접 저장하십시오.

+0

나는 (어제) 이미 이것을 시도했지만, 그럼 나는 (파일을 얻으려면) IS/OS와 어떻게 해야할지 모르겠다. 나는 전에 이것을 사용하지 않았다 ... 나는 많은 것을 시도했지만 모든 것이 실패했다. 내 DB에는 내 AS3S에서 내 이미지를 쉽게 가져올 수있는 S3Object 키만 있습니다. 앞에서 말했듯이 내 모든 이미지는 Amazon S3 서버에 저장됩니다 (또는 새 이미지의 경우). S3Bucket에'S3Object'를 저장하기 위해서는'File'을 설정해야합니다. 그게 내가 필요한 이유 야. 'public S3Object (java.io.File file)는 java.security.NoSuchAlgorithmException, java.io.IOException'을 던집니다. – ltin