在 JerseyTest 中找不到媒体类型 =multipart/form-data 的 MessageBodyWriter
MessageBodyWriter not found for media type=multipart/form-data in JerseyTest
我正在尝试为 Jersey 程序中资源 class 中的 POST
方法创建测试。
这是资源的 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.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation.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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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;
}
同样的错误。我在这里做错了什么?
MultiPartFeature
注册所需的 MessageBodyWriter/MessageBodyReader
来处理多部分。您已经在服务器上注册了它(它将使用 reader 来反序列化入站请求实体),但是您还需要在客户端上注册它(它使用编写器来序列化出站请求实体)。
实际上有几个地方可以注册。一对是同WebTarget
还是同Client
。如果你想用客户端注册它,你可以覆盖 JerseyTest
中的 configureClient(ClientConfig)
@Override
public void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
或者,使用 WebTarget
,您可以简单地执行
target(...).register(MultiPartFeature.class)..
我正在尝试为 Jersey 程序中资源 class 中的 POST
方法创建测试。
这是资源的 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.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation.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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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;
}
同样的错误。我在这里做错了什么?
MultiPartFeature
注册所需的 MessageBodyWriter/MessageBodyReader
来处理多部分。您已经在服务器上注册了它(它将使用 reader 来反序列化入站请求实体),但是您还需要在客户端上注册它(它使用编写器来序列化出站请求实体)。
实际上有几个地方可以注册。一对是同WebTarget
还是同Client
。如果你想用客户端注册它,你可以覆盖 JerseyTest
configureClient(ClientConfig)
@Override
public void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
}
或者,使用 WebTarget
,您可以简单地执行
target(...).register(MultiPartFeature.class)..