我正在尝试使用Amazon的Java API将文件上传到Amazon S3存储。代码是
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编码的字符串(即图像数据)时,文件会上传但图像已损坏。
亚马逊文档说我需要创建并附加POST策略和签名才能使用。我怎么能在java中做到这一点?我没有使用html
表单进行上传。
答案 0 :(得分:12)
首先你应该从字符串的开头删除数据:image / 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);
答案 1 :(得分:1)
这是一个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");
}
}
答案 2 :(得分:0)
对于使用更高版本SDK的用户:
实现组:software.amazon.awssdk
,名称:s3
,版本:2.10.3
byte[] bI = Base64.decodeBase64((base64Data.substring(base64Data.indexOf(",") + 1)).getBytes());
InputStream fis = new ByteArrayInputStream(bI);
amazonS3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(fileName)
.contentType(contentType)
.contentLength(Long.valueOf(bI.length))
.build(),
RequestBody.fromInputStream(fis, Long.valueOf(bI.length)));
答案 3 :(得分:0)
如何上传图像(png / jpg)的示例代码如下。 -
try {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 s3Client =
AmazonS3ClientBuilder.standard().withRegion(clientRegion)
.withCredentials(new
AWSStaticCredentialsProvider(awsCreds))
.build();
PutObjectRequest request = new PutObjectRequest(bucketName, fileName, new File(fileToUpload));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/jpg");
request.setMetadata(metadata);
s3Client.putObject(request.withCannedAcl(CannedAccessControlList.PublicRead));
logger.info("File " + fileToUpload + " uploaded to AWS bucket " + bucketName);
} catch (AmazonServiceException e) {
logger.error(e);
fileName = Common.NO_VALUE.toString();
} catch (SdkClientException e) {
logger.error(e);
fileName = Common.NO_VALUE.toString();
}
但是,我没有使用任何编码或解码的概念。这种平面简单的元数据内容类型的“图像/ jpg”有效。