Question Pourquoi les fichiers téléchargés sur S3 ont-ils un type de contenu application / octet-stream sauf si je nomme le fichier .html


Même si je définis le type de contenu sur text / html, il se termine en application / octet-stream sur 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));

Si toutefois je nomme le fichier pour qu'il se termine par .html

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

alors ça marche.

Mon objet md est-il simplement ignoré? Comment puis-je contourner ce problème par programmation, car au fil du temps, je dois télécharger des milliers de fichiers afin que je ne puisse pas simplement aller dans l'interface utilisateur S3 et corriger manuellement le contentType.


13
2018-06-08 10:00


origine


Réponses:


Vous devez faire autre chose dans votre code. Je viens d'essayer votre exemple de code en utilisant le SDK 1.9.6 S3 et le fichier obtient le type de contenu "text / html".

Voici le code exact (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()
    }
}

Le programme imprime

text / html

Et les métadonnées S3 disent la même chose:

S3 properties view

Voici la communication envoyée sur le net (avec la permission de la journalisation de débogage HTTP Apache):

>> 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

Et c'est aussi le comportement qui regarde la code source nous montre - si vous définissez le type de contenu, le SDK ne le remplacera pas.


10
2018-06-12 02:22



Parce que vous devez définir le type de contenu à la fin juste avant l'envoi, en utilisant la méthode 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));

Et après le téléchargement, le type de contenu est défini sur "text / html"

enter image description here

Voici un code factice qui fonctionne, vérifiez, je viens d’essayer et ça fonctionne;

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());
        }

    }

}

J'espère que ça aide.


5
2018-06-15 22:44



Il semble cette

Lors du téléchargement de fichiers, le client Java AWS S3 tentera de déterminer   le type de contenu correct s'il n'en a pas encore été défini. Les utilisateurs sont   responsable de s'assurer qu'un type de contenu approprié est défini lors du téléchargement   ruisseaux. Si aucun type de contenu n'est fourni et ne peut être déterminé par   le nom de fichier, le type de contenu par défaut, "application / octet-stream",   sera utilisé.

Donner au fichier une extension .html permet de définir le type correct.

Selon les exemples que j'ai examinés, le code que vous affichez devrait Faites ce que vous voulez faire. : /


1
2018-06-12 01:55



Avez-vous un remplacement sur le contenu mime par défaut de votre compte S3? Regardez ce lien pour voir comment le vérifier: Comment remplacer les types de contenu par défaut.

Quoi qu'il en soit, il semble que votre client S3 ne parvienne pas à déterminer le type MIME correct en fonction du contenu du fichier. Il dépend donc de l'extension. octet-stream est le type de mime de contenu par défaut le plus utilisé lorsqu'un navigateur / servlet ne peut pas déterminer le type MIME: Y a-t-il un type de mime par défaut?


0
2018-06-15 14:42