Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve MessageBodyWriter not found for media type=multipart/form-data error

Tags:

How to configure provider for simple multi-form post. Any suggestions/pointers would be much appreciated.

Stacktrace:

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) 

pom.xml dependencies:

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

The 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));     }  } 
like image 745
Doug Avatar asked Oct 29 '13 20:10

Doug


2 Answers

Well, reading the documentation was not helpful but reading the jersey integration tests source code was.

In the JerseyTest instance you need to override the configureClient method and pass in the MultiPartFeature class.

@Override protected void configureClient(ClientConfig config) {     config.register(MultiPartFeature.class); } 

Working Code:

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));     }  } 
like image 194
Doug Avatar answered Sep 22 '22 15:09

Doug


If you are working on the client side instead, as I was, and using Jersey 1.X, the answer by angstadt530 on this page is what you need.

Jersey client exception: A message body writer was not found

DefaultClientConfig clientConfig = new DefaultClientConfig(); clientConfig.getClasses().add(MultiPartWriter.class); Client client = Client.create(clientConfig); 

is how it looks in my code, but the example on that page is excellent as well.

like image 31
Karl Henselin Avatar answered Sep 21 '22 15:09

Karl Henselin