找不到媒体类型= application / x-www-form-urlencoded的jersey-client MessageBodyWriter

时间:2015-03-10 16:30:32

标签: jersey-client

使用org.glassfish.jersey.core.jersey-client版本2.16并且似乎无法发出简单的POST请求:

MessageBodyProviderNotFoundException:找不到媒体类型= application / x-www-form-urlencoded的MessageBodyWriter

客户端

String response = ClientBuilder.newClient().target("http://0.0.0.0:8080")
        .path("/get")
        .request(MediaType.APPLICATION_JSON_TYPE)
        .post(Entity.entity(getForm(), MediaType.APPLICATION_FORM_URLENCODED_TYPE), String.class);

private Form getForm()
{
    return new Form() {{ this.param("whatever", "whatever"); }};
}

服务器

@Path("/get")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String postForToken(@FormParam("whatever") final String whatever) {...}

根据this帖子注册MultiPartFeature没有任何区别。

config.register(MultiPartFeature.class);

2 个答案:

答案 0 :(得分:2)

好的,所以线索在完整的异常消息中(未在上面发布)。

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/x-www-form-urlencoded, type=class com.blah.AcceptanceTest$1, genericType=class com.blah.AcceptanceTest$1.

$ 1表示它试图解决某种内部类 - 这导致我进入Form的匿名子类。将上述内容更改为以下内容可以正常工作:

private Form getForm()
{
    final Form form = new Form();
    form.param("whatever", "whatever");
    return form;
}

答案 1 :(得分:0)

Jersey使用Entity Providers序列化和反序列化Java对象 - 它使用MessageBodyWriter进行序列化,MessageBodyReader进行反序列化。一些实体提供程序是开箱即用的,包括FormProvider,它处理媒体类型Form的{​​{1}}对象的读写。

泽西文档的

Section 8.3概述了在决定使用哪个注册提供商时使用的算法。第5步说:

  
      
  1. 遍历已排序的MessageBodyWriter提供程序,   利用每个的isWriteable方法,直到找到一个   MessageBodyWriter返回true。
  2.   

问题是application/x-www-form-urlencoded中的implementation of isWriteable()检查对象的运行时类型是否完全等于FormProvider - 子类,包括匿名类,不符合条件,因此该方法返回Form.class并且false不用于序列化。然后,找不到其他匹配的提供者,结果是FormProvider

简易解决方案:

简单的解决方案是使用实际的MessageBodyProviderNotFoundException类。

硬解决方案:

对于任何真正想要使用Form子类的人来说,硬解决方案是重新实现Form(标记为FormProvider,所以你不能只将其子类化),替代final方法的以下代码:

isWriteable()

然后,在使用之前,您必须使用public boolean isWriteable(...) { return Form.class.isAssignableFrom(type); } 注册自定义FormProvider:

Client