Comment configurer le fournisseur pour une publication multi-formulaire simple. Toute suggestion/indication serait très appréciée.
Trace de la pile:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=multipart/form-data, type=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=class org.glassfish.jersey.media.multipart.FormDataMultiPart.
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.Java:227)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.Java:149)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.Java:1139)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.Java:433)
at org.glassfish.jersey.test.inmemory.internal.InMemoryConnector.apply(InMemoryConnector.Java:214)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.Java:217)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.Java:655)
dépendances de pom.xml:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
Le code:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
public class TestMultiPartTest extends JerseyTest {
@Override
protected Application configure() {
ResourceConfig rc = new ResourceConfig(ServerSideResource.class);
rc.register(MultiPartFeature.class);
return rc;
}
@Path("test")
public static class ServerSideResource {
@POST
@Path("/multipart")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response file(FormDataMultiPart formParams) {
System.out.println("found multipart resource");
return Response.ok().build();
}
@POST
@Path("/encoded")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
public Response file(Form formParams) {
System.out.println("found encoded resource");
return Response.ok().build();
}
}
@Test
public void testPostMultiPartFile() {
final WebTarget target = target().path("test/multipart");
final FormDataMultiPart mp = new FormDataMultiPart();
final FormDataBodyPart p = new FormDataBodyPart("field1", "CONTENT ONE");
mp.bodyPart(p);
final FormDataBodyPart p2 = new FormDataBodyPart("field2", "CONTENT TWO");
mp.bodyPart(p2);
System.out.println("making multipart request");
final Response r = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), Response.class);
System.out.println(r.getStatus());
assertThat("response is 200", r.getStatus(), is(200));
}
@Test
public void testPostEncodedForm() {
final WebTarget target = target().path("test/encoded");
final Form form = new Form();
form.param("test", "value");
System.out.println("making encoded request");
final Response r = target.request().post(Entity.form(form), Response.class);
System.out.println(r.getStatus());
assertThat("response is 200", r.getStatus(), is(200));
}
}
Eh bien, la lecture de la documentation n'a pas été utile, mais la lecture du code source des tests d'intégration de jersey l'a été.
Dans l'instance JerseyTest, vous devez remplacer la méthode configureClient et passer la classe MultiPartFeature.
@Override
protected void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
Code de travail:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
public class TestMultiPartTest extends JerseyTest {
@Override
protected Application configure() {
ResourceConfig rc = new ResourceConfig(ServerSideResource.class);
rc.register(MultiPartFeature.class);
return rc;
}
@Override
protected void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
@Path("test")
public static class ServerSideResource {
@POST
@Path("/multipart")
@Consumes(MediaType.MULTIPART_FORM_DATA)
// @Produces(MediaType.APPLICATION_JSON)
public Response file(FormDataMultiPart formParams) {
System.out.println("found multipart resource");
return Response.ok().build();
}
@POST
@Path("/encoded")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
// @Produces(MediaType.APPLICATION_JSON)
public Response file(@FormParam("field3") String field3) {
System.out.println("found encoded resource");
System.out.println("got form.field3 value: " + field3);
return Response.ok().build();
}
}
@Test
public void testAnotherWay() {
WebTarget target = target("test/encoded");
final Form form = new Form();
form.param("field3", "field3 value");
System.out.println("testAnotherWay");
Response response = target.request().post(Entity.form(form), Response.class);
System.out.println(response);
}
@Test
public void testPostMultiPartFile() {
final WebTarget target = target().path("test/multipart");
final FormDataMultiPart mp = new FormDataMultiPart();
final FormDataBodyPart p = new FormDataBodyPart("field1", "CONTENT ONE");
mp.bodyPart(p);
final FormDataBodyPart p2 = new FormDataBodyPart("field2", "CONTENT TWO");
mp.bodyPart(p2);
System.out.println("field1: " + mp.getField("field1").getValue());
System.out.println("field2: " + mp.getField("field2").getValue());
System.out.println("making multipart request");
final Response r = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA), Response.class);
System.out.println(r);
assertThat("response is 200", r.getStatus(), is(200));
}
@Test
public void testPostEncodedForm() {
final WebTarget target = target().path("test/encoded");
final Form form = new Form();
form.param("field3", "field3 value");
System.out.println("making encoded request");
final Response r = target.request().post(Entity.form(form), Response.class);
System.out.println(r);
assertThat("response is 200", r.getStatus(), is(200));
}
}
Si vous travaillez plutôt du côté client, comme je l'ai été, et que vous utilisez Jersey 1.X, la réponse de angstadt530 sur cette page est ce dont vous avez besoin .
Exception du client Jersey: un rédacteur de corps de message est introuvable
DefaultClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getClasses().add(MultiPartWriter.class);
Client client = Client.create(clientConfig);
est à quoi il ressemble dans mon code, mais l'exemple sur cette page est également excellent.