Java 如何解决 MessageBodyWriter not found for media type=multipart/form-data 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19668426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:16:16  来源:igfitidea点击:

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

javajax-rsjersey-client

提问by Doug

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.call(JerseyInvocation.java:655)

pom.xml dependencies:

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>

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

}

回答by Doug

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

好吧,阅读文档没有帮助,但阅读 jersey 集成测试源代码很有帮助。

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

在 JerseyTest 实例中,您需要覆盖 configureClient 方法并传入 MultiPartFeature 类。

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

}

回答by Karl Henselin

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

如果您像我一样在客户端工作,并且使用 Jersey 1.X,那么此页面上angstadt530的答案就是您所需要的。

Jersey client exception: A message body writer was not found

Jersey 客户端异常:未找到消息正文编写器

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.

是它在我的代码中的外观,但该页面上的示例也非常出色。