Подтвердить что ты не робот

Почему файл, загруженный на S3, имеет приложение типа контента/октет-поток, если я не назвал файл .html

Даже если я задал тип контента text/html, он заканчивается как application/octet-stream на S3.

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.

4b9b3361

Ответ 1

Вы должны делать что-то еще в своем коде. Я просто попробовал ваш пример кода, используя SDK 1.9.6 S3, и файл получает тип содержимого "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()
    }
}

Программа печатает

текст/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 не будет его отменять.

Ответ 2

Поскольку вам нужно установить тип содержимого в конце непосредственно перед отправкой, используя метод 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));

И после загрузки тип контента устанавливается как " текст /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());
        }

    }

}

Надеюсь, что это поможет.

Ответ 3

Кажется,, что

При загрузке файлов клиент AWS S3 Java попытается определить правильный тип контента, если он еще не установлен. Пользователи ответственный за обеспечение подходящего типа контента, устанавливается при загрузке потоки. Если тип содержимого не указан и не может быть определен имя файла, тип содержимого по умолчанию, "приложение/октет-поток", будет использоваться.

Предоставление файла расширением .html обеспечивает способ установки правильного типа.

В соответствии с примерами, которые я рассматривал, код, который вы показываете, должен делать то, что вы хотите сделать.:/

Ответ 4

Есть ли у вас переопределение по умолчанию mime-контента в вашей учетной записи S3? Посмотрите на эту ссылку, чтобы узнать, как ее проверить: Как переопределить типы содержимого по умолчанию.

В любом случае, похоже, что ваш клиент S3 не может определить правильный тип mime по содержимому файла, поэтому он полагается на расширение. octet-stream - широко используемый тип mime-типа по умолчанию, когда браузер/сервлет не может определить тип mimetype: Есть ли тип mime по умолчанию?