web-dev-qa-db-ja.com

S3にアップロードされたファイルのコンテンツタイプがapplication / octet-streamであるのは、ファイルに.htmlという名前を付けない場合

コンテンツタイプをtext/htmlに設定しても、S3ではapplication/octet-streamになります。

ByteArrayInputStream contentsAsStream = new ByteArrayInputStream(contentAsBytes);
ObjectMetadata md = new ObjectMetadata();
md.setContentLength(contentAsBytes.length);
md.setContentType("text/html");
s3.putObject(new PutObjectRequest(ARTIST_BUCKET_NAME, artistId, contentsAsStream, md));

ただし、.htmlで終わるようにファイルに名前を付ける場合

s3.putObject(new PutObjectRequest(ARTIST_BUCKET_NAME, artistId + ".html", contentsAsStream, md));

それは動作します。

私のmdオブジェクトは単に無視されていますか?時間の経過とともに何千ものファイルをアップロードする必要があるので、S3 UIに移動してcontentTypeを手動で修正することはできません。

17
Paul Taylor

コードで何か他のことをしている必要があります。 1.9.6 S3 SDKを使用してコード例を試してみましたが、ファイルは「text/html」コンテンツタイプを取得します。

正確な(Groovy)コードは次のとおりです。

class S3Test {
    static void main(String[] args) {

        def s3 = new AmazonS3Client()

        def random = new Random()
        def bucketName = "raniz-playground"
        def keyName = "content-type-test"

        byte[] contentAsBytes = new byte[1024]
        random.nextBytes(contentAsBytes)

        ByteArrayInputStream contentsAsStream = new ByteArrayInputStream(contentAsBytes);
        ObjectMetadata md = new ObjectMetadata();
        md.setContentLength(contentAsBytes.length);
        md.setContentType("text/html");
        s3.putObject(new PutObjectRequest(bucketName, keyName, contentsAsStream, md))

        def object = s3.getObject(bucketName, keyName)
        println(object.objectMetadata.contentType)
        object.close()
    }
}

プログラムは印刷します

text/html

S3メタデータも同じことを言っています。

S3 properties view

以下は、ネット経由で送信される通信です(Apache HTTP Commonsデバッグロギングのおかげです)。

>> PUT /content-type-test HTTP/1.1
>> Host: raniz-playground.s3.amazonaws.com
>> Authorization: AWS <nope>
>> User-Agent: aws-sdk-Java/1.9.6 Linux/3.2.0-84-generic Java_HotSpot(TM)_64-Bit_Server_VM/25.45-b02/1.8.0_45
>> Date: Fri, 12 Jun 2015 02:11:16 GMT
>> Content-Type: text/html
>> Content-Length: 1024
>> Connection: Keep-Alive
>> Expect: 100-continue
<< HTTP/1.1 200 OK
<< x-amz-id-2: mOsmhYGkW+SxipF6S2+CnmiqOhwJ62WfWUkmZk4zU3rzkWCEH9P/bT1hUz27apmO
<< x-amz-request-id: 8706AE3BE8597644
<< Date: Fri, 12 Jun 2015 02:11:23 GMT
<< ETag: "6c53debeb28f1d12f7ad388b27c9036d"
<< Content-Length: 0
<< Server: AmazonS3

>> GET /content-type-test HTTP/1.1
>> Host: raniz-playground.s3.amazonaws.com
>> Authorization: AWS <nope>
>> User-Agent: aws-sdk-Java/1.9.6 Linux/3.2.0-84-generic Java_HotSpot(TM)_64-Bit_Server_VM/25.45-b02/1.8.0_45
>> Date: Fri, 12 Jun 2015 02:11:23 GMT
>> Content-Type: application/x-www-form-urlencoded; charset=utf-8
>> Connection: Keep-Alive
<< HTTP/1.1 200 OK
<< x-amz-id-2: 9U1CQ8yIYBKYyadKi4syaAsr+7BV76Q+5UAGj2w1zDiPC2qZN0NzUCQNv6pWGu7n
<< x-amz-request-id: 6777433366DB6436
<< Date: Fri, 12 Jun 2015 02:11:24 GMT
<< Last-Modified: Fri, 12 Jun 2015 02:11:23 GMT
<< ETag: "6c53debeb28f1d12f7ad388b27c9036d"
<< Accept-Ranges: bytes
<< Content-Type: text/html
<< Content-Length: 1024
<< Server: AmazonS3

また、これは ソースコード を見ると表示される動作です。コンテンツタイプを設定しても、SDKはそれを上書きしません。

12
Raniz

コンテンツタイプを最後に設定する必要があるため送信の直前、putObjectメソッドを使用;

        ObjectMetadata md = new ObjectMetadata();

        InputStream myInputStream = new ByteArrayInputStream(bFile); 
        md.setContentLength(bFile.length);
        md.setContentType("text/html");
        md.setContentEncoding("UTF-8");

        s3client.putObject(new PutObjectRequest(bucketName, keyName, myInputStream, md));

アップロード後、コンテンツタイプは「text/html」に設定されます

enter image description here

これが動作するダミーコードです。チェックしてみてください。試したところ、動作しています。

public class TestAWS {

    //TEST
    private static String bucketName = "whateverBucket";

    public static void main(String[] args) throws Exception {
        BasicAWSCredentials awsCreds = new BasicAWSCredentials("whatever", "whatever");

        AmazonS3 s3client = new AmazonS3Client(awsCreds);
        try
        {
            String uploadFileName = "D:\\try.txt";
            String keyName = "newFile.txt";

            System.out.println("Uploading a new object to S3 from a file\n");
            File file = new File(uploadFileName);

            //bFile will be the placeholder of file bytes
            byte[] bFile = new byte[(int) file.length()];
            FileInputStream fileInputStream=null;

            //convert file into array of bytes  
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(bFile);
            fileInputStream.close();

            ObjectMetadata md = new ObjectMetadata();

            InputStream myInputStream = new ByteArrayInputStream(bFile); 
            md.setContentLength(bFile.length);
            md.setContentType("text/html");
            md.setContentEncoding("UTF-8");

            s3client.putObject(new PutObjectRequest(bucketName, keyName, myInputStream, md));
        } catch (AmazonServiceException ase)
        {
            System.out.println("Caught an AmazonServiceException, which "
                    + "means your request made it "
                    + "to Amazon S3, but was rejected with an error response"
                    + " for some reason.");
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace)
        {
            System.out.println("Caught an AmazonClientException, which "
                    + "means the client encountered "
                    + "an internal error while trying to "
                    + "communicate with S3, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ace.getMessage());
        }

    }

}

それが役立つことを願っています。

5

らしい that

ファイルをアップロードするとき、AWS S3 Javaクライアントは、まだ設定されていない場合は正しいコンテンツタイプを決定しようとします。ユーザーは、ストリームのアップロード時に適切なコンテンツタイプを設定する責任があります。コンテンツタイプが提供されておらず、ファイル名で判別できない場合は、デフォルトのコンテンツタイプ「application/octet-stream」が使用されます。

ファイルに.html拡張子を付けると、正しいタイプを設定する方法が提供されます。

私が見てきた例によると、あなたが示すコードはあなたがやりたいことをしているはずです。 :/

2
Tim

S3アカウントのデフォルトのMIMEコンテンツにオーバーライドがありますか?このリンクを確認して、それを確認する方法を確認してください: デフォルトのコンテンツタイプをオーバーライドする方法

とにかく、S3クライアントはファイルの内容によって正しいMIMEタイプを判断できないように見えるため、拡張子に依存します。 octet-streamは、ブラウザ/サーブレットがmimetypeを判別できない場合に広く使用されているデフォルトのコンテンツmimeタイプです。 デフォルトのmimeタイプはありますか?

0
crigore