2015-06-19 3 views
4

Я пытаюсь загрузить файлы в хранилище Amazon S3, используя Java API Amazon. КодЗагрузка кодированного изображения Base64 в Amazon s3 с помощью java

Byte[] b = data.getBytes(); 
InputStream stream = new ByteArrayInputStream(b); 
//InputStream stream = new FileInputStream(new File("D:/samples/test.txt")); 
AWSCredentials credentials = new BasicAWSCredentials("<key>", "<key1>"); 
AmazonS3 s3client = new AmazonS3Client(credentials); 
s3client.putObject(new PutObjectRequest("myBucket",name,stream, new ObjectMetadata())); 

Когда я запускаю код после того, как комментируя первые две строки и раскомментировать третий, т.е. stream является FileoutputStream, файл правильно загружен. Но когда data является строкой с кодировкой base64, которая представляет собой данные изображения, файл загружается, но изображение повреждено. Документация Amazon говорит, что мне нужно создать и приложить политику POST и подпись для этого. Как я могу это сделать в java? Я не использую форму html для загрузки.

+0

действительно хороший вопрос +1 – Chris

+0

Хороший Q, любая удача, выясняя это? – MMeah

ответ

6

Во-первых, вы должны удалить данные: изображения/PNG; base64, от начала строки:

Образец кода блока:

byte[] bI = org.apache.commons.codec.binary.Base64.decodeBase64((base64Data.substring(base64Data.indexOf(",")+1)).getBytes()); 

InputStream fis = new ByteArrayInputStream(bI); 

AmazonS3 s3 = new AmazonS3Client(); 
Region usWest02 = Region.getRegion(Regions.US_WEST_2); 
s3.setRegion(usWest02); 
ObjectMetadata metadata = new ObjectMetadata(); 
metadata.setContentLength(bI.length); 
metadata.setContentType("image/png"); 
metadata.setCacheControl("public, max-age=31536000"); 
s3.putObject(BUCKET_NAME, filename, fis, metadata); 
s3.setObjectAcl(BUCKET_NAME, filename, CannedAccessControlList.PublicRead); 
+2

с java8 вы можете декодировать строку со встроенным утилитом: 'byte [] bI = java.util.Base64.getDecoder.decode (base64Data)' – trudolf

0

Вот класс DTO, который принимает данные base64Image прошли непосредственно из вашего клиента и проанализировано в его различные компоненты, которые могут быть легко прошли в вашем методе uploadToAwsS3:

public class Base64ImageDto { 

    private byte[] imageBytes; 
    private String fileName; 
    private String fileType; 
    private boolean hasErrors; 
    private List<String> errorMessages; 
    private static final List<String> VALID_FILE_TYPES = new ArrayList<String>(3); 

    static { 
     VALID_FILE_TYPES.add("jpg"); 
     VALID_FILE_TYPES.add("jpeg"); 
     VALID_FILE_TYPES.add("png"); 
    } 

    public Base64ImageDto(String b64ImageData, String fileName) { 
     this.fileName = fileName; 
     this.errorMessages = new ArrayList<String>(2); 
     String[] base64Components = b64ImageData.split(","); 

     if (base64Components.length != 2) { 
      this.hasErrors = true; 
      this.errorMessages.add("Invalid base64 data: " + b64ImageData); 
     } 

     if (!this.hasErrors) { 
      String base64Data = base64Components[0]; 
      this.fileType = base64Data.substring(base64Data.indexOf('/') + 1, base64Data.indexOf(';')); 

      if (!VALID_FILE_TYPES.contains(fileType)) { 
       this.hasErrors = true; 
       this.errorMessages.add("Invalid file type: " + fileType); 
      } 

      if (!this.hasErrors) { 
       String base64Image = base64Components[1]; 
       this.imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image); 
      } 
     } 
    } 

    public byte[] getImageBytes() { 
     return imageBytes; 
    } 

    public void setImageBytes(byte[] imageBytes) { 
     this.imageBytes = imageBytes; 
    } 

    public boolean isHasErrors() { 
     return hasErrors; 
    } 

    public void setHasErrors(boolean hasErrors) { 
     this.hasErrors = hasErrors; 
    } 

    public List<String> getErrorMessages() { 
     return errorMessages; 
    } 

    public void setErrorMessages(List<String> errorMessages) { 
     this.errorMessages = errorMessages; 
    } 

    public String getFileType() { 
     return fileType; 
    } 

    public void setFileType(String fileType) { 
     this.fileType = fileType; 
    } 

    public String getFileName() { 
     return fileName; 
    } 

    public void setFileName(String fileName) { 
     this.fileName = fileName; 
    } 
} 

И вот метод, который вы можете добавить в свой AwsS3Service, который поместит объект туда (Примечание. Возможно, вы не можете использовать диспетчер передачи для управления вашими позициями, поэтому вам необходимо будет изменить этот код соответственно):

public void uploadBase64Image(Base64ImageDto base64ImageDto, String pathToFile) { 
    InputStream stream = new ByteArrayInputStream(base64ImageDto.getImageBytes()); 

    ObjectMetadata metadata = new ObjectMetadata(); 
    metadata.setContentLength(base64ImageDto.getImageBytes().length); 
    metadata.setContentType("image/"+base64ImageDto.getFileType()); 

    String bucketName = awsS3Configuration.getBucketName(); 
    String key = pathToFile + base64ImageDto.getFileName(); 

    try { 
     LOGGER.info("Uploading file " + base64ImageDto.getFileName() + " to AWS S3"); 
     PutObjectRequest objectRequest = new PutObjectRequest(bucketName, key, stream, metadata); 
     objectRequest.setCannedAcl(CannedAccessControlList.PublicRead); 
     Upload s3FileUpload = s3TransferManager.upload(objectRequest); 
     s3FileUpload.waitForCompletion(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     LOGGER.info("Error uploading file " + base64ImageDto.getFileName() + " to AWS S3"); 
    }  
} 
Смежные вопросы