web-dev-qa-db-fra.com

Comment définir le type de contenu du fichier lors du téléchargement multipart lorsque vous utilisez RestTemplate (à partir d'un client de repos)

Le fichier que j'essaye de télécharger sera toujours un fichier xml. Je veux définir le type de contenu comme application/xml Voici mon code:

         MultiValueMap<String, Object parts = new LinkedMultiValueMap<String,
         Object(); parts.add("subject", "some info"); 
         ByteArrayResource xmlFile = new    ByteArrayResource(stringWithXMLcontent.getBytes("UTF-8")){
                 @Override
                 public String getFilename(){
                     return documentName;
                 }             
             };

     parts.add("attachment", xmlFile);

//sending the request using RestTemplate template;, the request is successfull 
String result = template.postForObject(getRestURI(), httpEntity,String.class);      
//but the content-type of file is 'application/octet-stream'

la requête brute ressemble à ceci:

    Content-Type:
    multipart/form-data;boundary=gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz
    User-Agent: Java/1.7.0_67 Host: some.Host Connection: keep-alive
    Content-Length: 202866

    --gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz Content-Disposition: form-data;    name="subject" Content-Type: text/plain;charset=ISO-8859-1
    Content-Length: 19

    some info

    --gbTw7ZJbcdbHIeCRqdX81DVTFfA-oteHHEqgmlz Content-Disposition: form-data;   name="attachment"; filename="filename.xml" Content-Type:
    application/octet-stream Content-Length: 201402

    ....xml file contents here ..

Le type de contenu du fichier est généré sous le nom "application/octet-stream", où je souhaite qu'il soit "application/xml" Comment définir le type de contenu du fichier?

14
RGR

J'ai compris la solution après avoir pris un indice de ce lien:

Effectuer une demande de publication en plusieurs parties avec un tableau d'octets jpeg compressé avec ressort pour Android

La solution consiste à placer ByteArrayResource dans une HttpEntity avec l’en-tête requis et à ajouter HttpEntity à Multivaluemap (au lieu d’ajouter ByteArrayResource lui-même.)

Code:

Resource xmlFile = new ByteArrayResource(stringWithXMLcontent.getBytes("UTF-8")){
            @Override
            public String getFilename(){
                return documentName;
            }
        };
        HttpHeaders xmlHeaders = new HttpHeaders();
        xmlHeaders.setContentType(MediaType.APPLICATION_XML);
        HttpEntity<Resource> xmlEntity = new HttpEntity<Resource>(xmlFile, xmlHeaders);
        parts.add("attachment", xmlEntity);
26
RGR

Je n'ai pas utilisé RestTemplate mais j'ai déjà utilisé HttpClient dans le passé - voici comment je passe la partie du corps - 

MultipartEntityBuilder eb = MultipartEntityBuilder.create().setBoundary(MULTIPART_BOUNDARY)
                .addTextBody(BODYPART_ENTITY, key, ContentType.create("application/xml", Charset.forName("UTF-8")));

Vous devrez rechercher une API dans RestTemplate qui peut prendre le type de contenu

0
Pankaj

Comme je ne peux pas commenter la réponse de @RGR, je publie cette réponse comme nouvelle réponse, bien que la réponse de RGR soit tout à fait correcte. 

Le problème est que le Sprint RestTemplates utilise FormHttpMessageConverter pour envoyer la demande en plusieurs parties. Ce convertisseur détecte tout ce qui hérite de Resource et l'utilise comme partie "fichier" de la requête. par exemple. Si vous utilisez MultiValueMap, chaque propriété que vous ajoutez sera envoyée dans sa propre partie dès que vous ajoutez une "ressource" ...--> Paramétrage du nom de fichier, type MIME, longueur, .. ne fera pas partie du fichier " partie". 

Pas une réponse, mais c'est la raison pour laquelle ByteArrayResource doit être étendu pour renvoyer le nom de fichier et être envoyé en tant que partie unique de la demande. L'envoi de plusieurs fichiers fonctionnera avec une MultiValueMap

Il semble que ce problème ait été résolu dans Spring 4.3 par SPR-13571

0
Clemens Eberwein