MessageBodyWriter not found for media type = multipart / form-data in JerseyTest

I am trying to create a test for the POST method in a resource class in a Jersey program.

Here's the POST resource method:

 @POST @Path("/new") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response HTTPPostMethod(@FormDataParam("file") InputStream fileIS, @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { // ... some code that handles the InputStream } 

My ResourceConfig is created as follows:

 public class MyApp extends ResourceConfig { public MyApp(String param) { register(createMoxyJsonResolver()); register(MultiPartFeature.class); register(MyResource.class); } private static ContextResolver<MoxyJsonConfig> createMoxyJsonResolver() { final MoxyJsonConfig moxyJsonConfig = new MoxyJsonConfig(); Map<String, String> nsPrefixManager = new HashMap<String, String>(1); nsPrefixManager.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); moxyJsonConfig.setNamespacePrefixMapper(nsPrefixManager).setNamespaceSeparator(':'); return moxyJsonConfig.resolver(); } /** * Start the Grizzly HTTP Server * */ public final void startHttpServer(int port) { try { final String url = "http://localhost:" + port + "/myapp"; final HttpServer server = GrizzlyHttpServerFactory .createHttpServer(URI.create(url), this); Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { server.shutdown(); } })); Thread.currentThread().join(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { try { final MyApp app = new MyApp(args[1]); int port = Integer.parseInt(args[0]); app.startHttpServer(port); } catch(NumberFormatException e) { e.printStackTrace(); } } } 

My jersey test setup:

 public class TestBase extends JerseyTest { protected Application app; protected static final String param = "myparam"; @Override protected Application configure() { // The MultiPartFeature is registered. this.app = new MyApp(param); return app; } } 

Finally, a test that causes problems:

 public class MyResourceTest extends TestBase { // ... @Test public void testHTTPPost() { try { FileDataBodyPart filePart = new FileDataBodyPart("file", new File("path/to/a/file/i/know/exists")); FormDataMultiPart formDataMultipart = new FormDataMultiPart(); FormDataMultiPart multipart = (FormDataMultiPart)formDataMultipart.bodyPart(filePart); Response result = target("/myResource/new").request().post(Entity.entity(multipart, multipart.getMediaType())); formDataMultipart.close(); multipart.close(); assertEquals(Response.Status.OK.getStatusCode(), result.getStatus()); } catch (IOException e) { e.printStackTrace(); } } // ... } 

I always get the error:

 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:247) at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130) at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:502) at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388) at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255) at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684) at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681) 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.process(Errors.java:228) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437) at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343) at services.MyResourceTest.testHTTPPost(MyResourceTest.java:151) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) 

I tried the following code in TestBase , but it did not work:

 @Override protected Application configure() { ResourceConfig app = new ResourceConfig(); app.register(MultiPartFeature.class); app.register(MyResource.class); this.app = app; return app; } 

The same mistakes. What am I doing wrong here?

+6
source share
1 answer

MultiPartFeature register the required MessageBodyWriter/MessageBodyReader to handle multipart. You registered it on the server (which the reader will use to deserialize the essence of the incoming request), but you also need to register it on the client (which uses the record to serialize the outgoing request object).

There are actually several places where you can register it. The pair consists of WebTarget or with Client . If you want to register it with a client, you can override configureClient(ClientConfig) in JerseyTest

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

Or, with WebTarget , you can just do

 target(...).register(MultiPartFeature.class).. 
+6
source

All Articles