2015-06-08 24 views
11

Anche se imposto il tipo di contenuto in text/html finisce come application/octet-stream su S3.Perché il file caricato su S3 ha il tipo di contenuto application/octet-stream a meno che non denomini il file .html

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

Se però ho un nome al file in modo che finisce con .html

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

allora funziona.

Il mio oggetto md viene semplicemente ignorato? Come posso aggirare questo a livello di programmazione poiché nel tempo ho bisogno di caricare migliaia di file, quindi non posso semplicemente andare nell'interfaccia utente S3 e correggere manualmente il contentType.

+0

Come si controlla il tipo di contenuto? Nell'interfaccia utente di AWS S3 o tramite API? Se tramite API puoi incollare il codice. Utilizzi l'ultima versione di AWS SDK? Se è così puoi provare con uno. – Jakozaur

+0

Controllo il tipo di contenuto aprendo guardando il contentype in un browser all'interno della console S3 –

+0

Im usando aws versione 1.9.6 che ritenevo essere l'ultima –

risposta

1

It seems che

Quando il caricamento di file, il client AWS S3 Java tenterà di determinare il tipo di contenuto corretto se uno non è stato ancora stabilito. Gli utenti sono responsabili di garantire che venga impostato un tipo di contenuto adatto quando si caricano gli stream . Se non viene fornito alcun tipo di contenuto e non può essere determinato da , verrà utilizzato il nome file, il tipo di contenuto predefinito "application/octet-stream", .

Assegnare al file un'estensione .html fornisce un modo per impostare il tipo corretto.

Secondo gli esempi che ho visto, il codice che si visualizza deve fare facendo ciò che si vuole fare. :/

+0

Questo non spiega perché viene reimpostato su "application/octet-stream" quando impostato esplicitamente su "text/html". – Raniz

+0

Poiché quel tipo di contenuto sembra non essere impostato correttamente, aws trova il più appropriato. Ma se imposti il ​​tipo di contenuto prima di usare il metodo putObject, verrà impostato il tipo di contenuto. Puoi controllare la mia risposta. –

9

Devi fare qualcos'altro nel tuo codice. Ho appena provato il tuo esempio di codice usando l'SDK 1.9.6 S3 e il file ha il tipo di contenuto "text/html".

Ecco l'esatto (Groovy) Codice:

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

Il programma stampa

text/html

E i metadati S3 dice la stessa:

S3 properties view

Ecco la comunicazione inviata sopra la rete (per gentile concessione di Apache HTTP Commons registrazione di debug):

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

e questo è anche il comportamento che guardando il source code ci mostra - se si imposta il tipo di contenuto l'SDK non lo sovrascriverà.

+1

Questo non spiega perché viene reimpostato su "application/octet-stream" quando è impostato esplicitamente su "text/html". : P – Tim

+2

No, ma * dimostra * che non è =) – Raniz

0

Hai un override sul contenuto mime predefinito sul tuo account S3? Guarda questo link per vedere come controllarlo: How to override default Content Types.

In ogni caso, sembra che il client S3 non riesca a determinare il tipo mime corretto dal contenuto del file, quindi si basa sull'estensione.octet-stream è il tipo di contenuto MIME predefinito ampiamente utilizzato quando un browser/servlet non può determinare il tipo MIME: Is there any default mime type?

4

Perché devi impostare il tipo di contenuto al termine poco prima di inviare, utilizzando il metodo 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)); 

E dopo il caricamento, tipo di contenuto è impostato come "text/html"

enter image description here

Questo vuole essere un codice fittizio di lavoro, verificare che fuori, ho appena provato ed è lavoro;

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

    } 

} 

Spero che sia d'aiuto.