J'utilise une stratégie d'implémentation de service reposante basée sur Jersey pour créer un service qui sera utilisé pour télécharger des fichiers . Le nom de ma classe de service est: UploadFileService.Java (voir le code ci-dessous).
package com.jerser.service;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.OutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.Sun.jersey.core.header.FormDataContentDisposition;
import com.Sun.jersey.multipart.FormDataParam;
@Path("/fileUpload")
public class UploadFileService {
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) {
String uploadedFileLocation = "d://uploaded/" + fileDetail.getFileName();
// save it
writeToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded to : " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
// save uploaded file to new location
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(
uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Voici les fichiers JAR que j'ai dans ma bibliothèque:
aopalliance-repackaged-2.4.0-b10.jar asm-debug-all-5.0.2.jar hk2-api-2.4.0-b10.jar hk2-locator-2.4.0-b10.jar hk2-utils-2.4.0-b10.jar javassist-3.18.1-GA.jar javax.annotation-api-1.2.jar javax.inject-2.4.0-b10.jar javax.servlet-api-3.0.1.jar javax.ws.rs-api-2.0.1.jar jaxb-api-2.2.7.jar jersey-client.jar jersey-common.jar jersey-container-servlet-core.jar jersey-container-servlet.jar jersey-core-1.11.jar jersey-guava-2.17.jar jersey-media-jaxb.jar jersey-multipart-1.18.jar jersey-server.jar org.osgi.core-4.2.0.jar osgi-resource-locator-1.0.1.jar persistence-api-1.0.jar validation-api-1.1.0.Final.jar
Je reçois le message d'erreur suivant lorsque j'essaie de mettre à niveau mon serveur Tomcat:
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public javax.ws.rs.core.Response com.jerser.service.UploadFileService.uploadFile(Java.io.InputStream,com.Sun.jersey.core.header.FormDataContentDisposition) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.jerser.service.UploadFileService, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@d3e2d4]}, definitionMethod=public javax.ws.rs.core.Response com.jerser.service.UploadFileService.uploadFile(Java.io.InputStream,com.Sun.jersey.core.header.FormDataContentDisposition), parameters=[Parameter [type=class Java.io.InputStream, source=file, defaultValue=null], Parameter [type=class com.Sun.jersey.core.header.FormDataContentDisposition, source=file, defaultValue=null]], responseType=class javax.ws.rs.core.Response}, nameBindings=[]}']
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.Java:528)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.Java:166)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.Java:327)
at org.glassfish.jersey.internal.Errors$2.call(Errors.Java:289)
at org.glassfish.jersey.internal.Errors$2.call(Errors.Java:286)
at org.glassfish.jersey.internal.Errors.process(Errors.Java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.Java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.Java:286)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.Java:324)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.Java:338)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.Java:171)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.Java:363)
at javax.servlet.GenericServlet.init(GenericServlet.Java:160)
at org.Apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.Java:1176)
at org.Apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.Java:1102)
at org.Apache.catalina.core.StandardWrapper.load(StandardWrapper.Java:1009)
at org.Apache.catalina.core.StandardContext.loadOnStartup(StandardContext.Java:4885)
at org.Apache.catalina.core.StandardContext$3.call(StandardContext.Java:5212)
at org.Apache.catalina.core.StandardContext$3.call(StandardContext.Java:5207)
at Java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at Java.util.concurrent.FutureTask.run(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
Sur Internet, j'ai trouvé de nombreux exemples montrant comment télécharger un fichier MULTIPART à l'aide de l'API RESTFul. Mais avec la même solution. Je ne parviens pas non plus à exécuter ce code… .. Je pense que les fichiers JAR ne fonctionnent pas bien. Quelqu'un pourrait-il m'aider s'il vous plaît à ce sujet?
Débarrassez-vous de jersey-multipart-1.18.jar
. C'est pour Jersey 1.x. Ajouter ces deux
Pour Maven, vous utiliseriez la dépendance suivante (vous n'avez pas besoin d'ajouter explicitement la dépendance mimepull
car celle-ci l'utilisera).
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.17</version> <!-- Make sure the Jersey version matches
the one you are currently using -->
</dependency>
Ensuite, vous devez enregistrer la MultiPartFeature
. Si vous utilisez une ResourceConfig
pour la configuration, vous pouvez simplement faire
register(MultiPartFeature.class);
Si vous utilisez web.xml, vous pouvez ajouter la classe en tant que <init-param>
au servlet Jersey.
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
Notez que si vous souhaitez enregistrer plusieurs fournisseurs, vous pouvez délimiter chaque classe de fournisseurs avec une virgule ou un point-virgule. Vous ne pouvez pas utiliser ce même param-name
deux fois. Voir Réponse de Suarabh
METTRE &AGRAVE; JOUR
En outre, une fois que vous aurez supprimé jersey-multipart-1.18.jar
, vous aurez des erreurs de compilation pour les classes importées manquantes. Pour la plupart, les noms de classe sont toujours les mêmes, seuls les packages ont changé, c.-à-d.
org.glassfish.jersey.media.multipart.FormDataParam
org.glassfish.jersey.media.multipart.FormDataContentDisposition
Si vous êtes ici pour une ModelValidationException
différente, voici quelques liens pour obtenir des informations sur les autres causes de l'exception.
Moi aussi j'ai eu la même exception. J'ai fait les modifications suivantes dans web.xml
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.moxy.json.MoxyFeature;org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
et changé maillot 2.7 à 2.9 .Je ne sais pas quel changement de ce 2 a résolu le problème.
Enregistrez MultiPartFeature. Dans web.xml, ajoutez à la servlet Jersey:
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
Une autre cause possible de cette erreur très générique est que Jersey ne recherche que les fabriques associées à la dernière annotation lorsque plusieurs d'entre elles sont déclarées dans un paramètre. (Voir rapport de bug )
Jusqu'à ce que cela soit corrigé, si vous utilisez des annotations autres que @FormDataParam
, elles doivent être passées en dernier.
Cela marche:
@NotEmpty @FormDataParam("myParam") String myParam
Cela ne veut pas:
@FormDataParam("myParam") @NotEmpty String myParam
Si quelqu'un utilise @FormDataParam
avec @ApiOperation
annotation swagger, cela ne fonctionnera pas (comme dans la dernière version de swagger pour le moment), comme indiqué ici: