6

我正在嘗試在澤西島程序的資源類中爲POST方法創建一個測試。MessageBodyWriter找不到在JerseyTest中的media type = multipart/form-data

這裏的資源POST方法:

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

ResourceConfig通過以下方式創建:

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(); 
     } 
    } 
} 

我的球衣測試設置:

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

最後,測試這是造成問題:

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(); 
     } 
    } 

// ... 

} 

我總是得到錯誤:

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) 

我試圖在TestBase下面的代碼,但沒有奏效:

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

同樣的錯誤。我在這裏做錯了什麼?

+0

這類似於https://開頭計算器。 com/questions/19668426/how-to-resolve-messagebodywriter-not-found-for-media-type-multipart-form-data-er –

回答

6

MultiPartFeature註冊所需的MessageBodyWriter/MessageBodyReader以處理多部分。您已經在服務器上註冊了它(它將使用讀取器反序列化入站請求實體),但是您還需要在客戶端(使用編寫器序列化出站請求實體)上註冊它。

實際上有幾個地方你可以註冊它。一對夫婦與WebTargetClient。如果你想與客戶端進行註冊,就可以在JerseyTest

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

覆蓋configureClient(ClientConfig)或者與WebTarget,你可以簡單地做

target(...).register(MultiPartFeature.class).. 
+0

謝謝!接受一分鐘。 'configureClient'方法並使它工作。 – luispcosta

相關問題