我正在使用旧的[email protected]
库,使用application/x-www-form-urlencoded
内容类型在私有第三方REST服务上调用POST。
一切似乎都按预期执行,但是响应不会自动反序列化到我的POJO。 ClientHandlerException
是一个例外,它声称该POJO没有消息正文解析器。
可用的默认提供者为:
com.sun.jersey.core.impl.provider.entity.FormProvidercom.sun.jersey.core.impl.provider.entity.StringProvidercom.sun.jersey.core.impl.provider.entity.ByteArrayProvidercom.sun.jersey.core.impl.provider.entity.FileProvidercom.sun.jersey.core.impl.provider.entity.InputStreamProvidercom.sun.jersey.core.impl.provider.entity.DataSourceProvidercom.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider $ Generalcom.sun.jersey.core.impl.provider.entity.ReaderProvidercom.sun.jersey.core.impl.provider.entity.DocumentProvidercom.sun.jersey.core.impl.provider.entity.SourceProvider $ StreamSourceReadercom.sun.jersey.core.impl.provider.entity.SourceProvider $ SAXSourceReadercom.sun.jersey.core.impl.provider.entity.SourceProvider $ DOMSourceReadercom.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider $ Generalcom.sun.jersey.json.impl.provider.entity.JSONArrayProvider $ Generalcom.sun.jersey.json.impl.provider.entity.JSONObjectProvider $ Generalcom.sun.jersey.core.impl.provider.entity.XMLRootElementProvider $ Generalcom.sun.jersey.core.impl.provider.entity.XMLListElementProvider $ Generalcom.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider $ Generalcom.sun.jersey.core.impl.provider.entity.EntityHolderReadercom.sun.jersey.json.impl.provider.entity.JSONRootElementProvider $ Generalcom.sun.jersey.json.impl.provider.entity.JSONListElementProvider $ Generalcom.sun.jersey.json.impl.provider.entity.JacksonProviderProxy
预期的第三方服务XML输出模板:
<foobar>
<foo>Foooooooo</foo>
<bar>Barrrrrrr</bar>
</foobar>
POJO:
@XmlRootElement(name = "foobar")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foobar {
@XmlElement(name = "foo")
private String foo;
@XmlElement(name = "bar")
private String bar;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
请求:
MultivaluedMap parameters = new MultivaluedMapImpl();
parameters.add(...);
Foobar response = client.resource(URL)
.type(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.APPLICATION_XML)
.post(Foobar.class, parameters);
例外:
线程“ main”中的异常com.sun.jersey.api.client.ClientHandlerException:消息正文Java类foo.bar.Foobar和Java类型类的阅读器foo.bar.Foobar和MIME媒体类型text / html; charset = UTF-8不是发现于com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:630)在com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:586)在com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)在com.sun.jersey.api.client.WebResource.access $ 200(WebResource.java:74)在com.sun.jersey.api.client.WebResource $ Builder.post(WebResource.java:570)在foo.bar.Main.jerseySample(Main.java:103)处foo.bar.Main.main(Main.java:109)
使用JAXB解组器对XML字符串进行反序列化可以很好地工作,但是Jersey无法独自完成它(也许在XMLJAXBElementProvider
,XMLRootElementProvider
,XMLRootObjectProvider
的帮助下?)。这是怎么回事?
我发现解决此问题的最简单方法是创建自定义MessageBodyReader
。
public static class FoobarMessageBodyReader implements MessageBodyReader<Foobar> {
private JAXBContext jaxbContext;
private Unmarshaller jaxbUnmarshaller;
public RespostaIncluirMessageBodyReader() throws JAXBException {
jaxbContext = JAXBContext.newInstance(Foobar.class);
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
}
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return type.isAssignableFrom(Foobar.class);
}
@Override
public Foobar readFrom(Class<Foobar> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
try {
return (Foobar) jaxbUnmarshaller.unmarshal(entityStream);
}
catch (JAXBException e) {
throw new IOException("Could not unmarshal the XML output", e);
}
}
}
...并将其添加到客户端配置中,如下所示:
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getClasses().add(FoobarMessageBodyReader.class);
Client client = Client.create(clientConfig);
您现在应该成功反序列化对象。