使用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);
答案 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步说:
- 遍历已排序的MessageBodyWriter提供程序, 利用每个的isWriteable方法,直到找到一个 MessageBodyWriter返回true。
醇>
问题是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