CXF upload de fichier

De EjnTricks

La documentation concernant l'upload de fichier n'est pas très clair et le premier service de chargement est fastidieux. Cet article se propose de présenter un exemple complet pour réaliser un tel projet. Le code de cet exemple est disponible sous Tuto CXF.


Hand-icon.png Votre avis

Current user rating: 56/100 (1 votes)

 You need to enable JavaScript to vote


XML format icon.png Configuration Spring

La configuration définie:

  • Un service de classe fr.ejn.tutorial.ws.impl.FileTransfertWsImpl
  • Un webservice dont l'adresse de base est /tutorial
 <!-- Class instance Webservice -->
 <bean id="filesWebService" class="fr.ejn.tutorial.ws.impl.FileTransfertWsImpl">
 </bean>
 
 <!-- Webservice -->
 <jaxrs:server id="tutorialService" address="/tutorial">
 	<jaxrs:properties>
 		<entry key="service-list-path" value="/cxf" />
 	</jaxrs:properties>
 	<jaxrs:serviceBeans>
 		<ref bean="filesWebService" />
 	</jaxrs:serviceBeans>
 	<jaxrs:extensionMappings>
 		<entry key="xml" value="application/xml" />
 	</jaxrs:extensionMappings>
 </jaxrs:server>


Java format icon.png Interface

L'interface définie une seule méthode en mode POST, et acceptant un seul argument pour encapsuler le contenu à transférer.

package com.edf.tutorial.ws;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;

import com.edf.tutorial.dto.DummyResponseDto;

@Path("/files")
@Produces(MediaType.APPLICATION_XML)
public interface FileTransfertWs {

	@POST
	@Path("/upload")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public DummyResponseDto postGetFile(@Multipart(value = "content", type = "application/*") Attachment file);

}


Java format icon.png Classe instance

La classe d'instance réceptionne le contenu dans l'argument file. Cet argument doit être de type org.apache.cxf.jaxrs.ext.multipart.Attachment. D'autre types sont disponibles comme javax.activation.DataSource. L'exécution montrée dans cet exemple n'est pas un modèle de code Java, mais il est juste à but informatif. L'objectif de celui ci est de sauvegarder le fichier envoyé.

package com.edf.tutorial.ws.impl;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;

import com.edf.tutorial.dto.DummyResponseDto;
import com.edf.tutorial.ws.FileTransfertWs;

@Path("/files")
@Produces(MediaType.APPLICATION_XML)
public class FileTransfertWsImpl implements FileTransfertWs {

	@POST
	@Path("/upload")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public DummyResponseDto postGetFile(@Multipart(value = "content", type = "application/*") Attachment file) {
		DummyResponseDto dummyResponsDto = new DummyResponseDto();
		try {
			InputStream in = file.getDataHandler().getInputStream();
			byte buffer[]=new byte[512*1024]; 
			int nbLecture; 
			FileOutputStream destinationFile = new java.io.FileOutputStream("...");

			while( (nbLecture = in.read(buffer)) != -1 ) { 
				destinationFile.write(buffer, 0, nbLecture); 
			} 

			destinationFile.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

		return dummyResponsDto;
	}
	
}


Java format icon.png Objet réponse

Pour les besoins de ce tutorial, un DTO réponse a été créé mais ne sert pas à grand chose, d'où son nom:

package com.edf.tutorial.dto;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "DummyResponseDto")
public class DummyResponseDto {

	@XmlElement(name = "dummy")
	public String getDummy() {
		return "dummy";
	}

	/**
	 * 
	 */
	public DummyResponseDto() {
	}
	
}


Mimetypes-html-icon.png Formulaire HTML

Afin de tester le service, un simple formulaire HTML fait l'affaire. Le code HTML est le suivant:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Tutorial Téléverser Fichier avec CXF</title>
</head>
<body>

<script language="Javascript">

function submit() {
	var obj = document.getElementById("uploadform");
	obj.submit();
}

</script>

<form id="uploadform" name="uploadform" action="/fidji_app_dctm/cxf/tutorial/files/upload" method="POST" target="_blank" enctype="multipart/form-data"> 
<input type="file" name="content"> 
</form>
<a href="javascript:submit()">Send</a>

</body>
</html>

A noter, l'envoi du formulaire s'effectue à l'aide de Javascript afin d'éviter d'envoyer tout argument parasite dans le flux HTTP. L'attribut enctype="multipart/form-data" de la balise form est obligatoire pour le bon fonctionnement.