在 Jersey 客户端中使用 BeanParam API

Using BeanParam in Jersey Client API

在 Jersey API 文档中有一个使用表单封装表单参数发布到服务的示例:

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9998").path("resource");

Form form = new Form();
form.param("x", "foo");
form.param("y", "bar");

MyJAXBBean bean =
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE),
    MyJAXBBean.class);

我不想使用 Form 对象,而是想使用 BeanParam,与传递到我的方法中的那个相同(即我的方法只是充当代理并重新 posting 到另一个服务)。所以像这样:

@POST
@Path("/CallService")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response callService(@BeanParam final MyBean requestBean) {

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9998").path("resource");

MyJAXBBean bean =
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(requestBean,MediaType.APPLICATION_FORM_URLENCODED_TYPE),
    MyJAXBBean.class);
}

当我调用这个端点时,我得到一个 MessageBodyProviderNotFoundException:

javax.servlet.ServletException: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/x-www-form-urlencoded, type=class MyBean, genericType=class MyBean.

MyBean 只是一个用 @XmlRootElement@XmlAccessorType(XmlAccessType.FIELD) 注释的 pojo,然后是一些用 @FormParam("company").

注释的字段

看起来在创建 post 时它不会调用类型 application/x-www-form-urlencoded 的提供程序...

"Instead of using a Form object, I want to use a BeanParam"

你不能。坚持使用 Form@BeanParam 是严格意义上的服务器端,它甚至不只是表单参数,它也适用于所有其他参数。重点是在服务器端将它们组合起来,方便访问。

当您尝试在客户端发送 bean 时。客户端寻找可以处理 application/x-www-form-urlencodedMyBeanMessageBodyWriter。它不会找到一个,你会得到你目前得到的错误。可用于 application/x-www-form-urlencodedMessageBodyWriter 可以处理 FormMultivaluedMap[1] .

如果您真的想将数据作为 bean 发送,则将其作为 application/json 发送。除此之外,您只能使用 FormMultivaluedMap

[1] - 请参阅