Jersey REST-Client WebTarget - 无法找到内容类型的 MessageBodyReader
Jersey REST-Client WebTarget - Unable to find a MessageBodyReader of content-type
这是关于参数化的请求。我的应用程序的用户应该能够为请求选择参数。然后我将从响应中读取 xml 并使用 JAXB 对其进行解析。
我是这样成功完成的:
String uri = "https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords&metadataPrefix=oai_primo&set=PRIMO&from=2020-01-22T12:39:59Z&until=2020-02-28T11:40:00Z";
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
InputStream xml = connection.getInputStream();
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
oai = (OAIPMHtype) jaxbUnmarshaller.unmarshal(xml);
但我想动态创建请求。有一个 JSF 页面,用户可以在其中输入参数。
我想到了一个 Jersey-Client,因为我可以很容易地用字段替换 queryParam 中的字符串。但是我不能 link Jersey-Client 到我的 Unmarshaller。
我的想法是将响应转换为输入流并将其提供给 Unmarshaller。
这是我试过的。
主要方法
public static void main(String[] args) {
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target("https://cmi.zb.uzh.ch/primo/api/oaipmh");
target.queryParam("verb", "ListRecords")
.queryParam("metadataPrefix", "oai-primo")
.queryParam("set", "PRIMO")
.queryParam("from", "2020-01-22T12:39:59Z")
.queryParam("until", "2020-02-28T11:40:00Z" );
InputStream stream = target.request()
.accept(MediaType.TEXT_XML)
.get(InputStream.class);
}
}
错误信息
Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/xml;charset=utf-8 and type class java.io.InputStream
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:163)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:467)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.get(ClientInvocationBuilder.java:197)
at ch.hbu.sacker.oaipmh.VogellaExample.main(VogellaExample.java:45)
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/xml;charset=utf-8 and type class java.io.InputStream
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:37)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:80)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:53)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:211)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:88)
at org.jboss.resteasy.specimpl.AbstractBuiltResponse.readEntity(AbstractBuiltResponse.java:256)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:127)
... 3 more
有人知道为什么会这样吗?
您尝试使用 3d 派对 Http 客户端而不是使用 HttpURLConnection class 是正确的。您可以做的是尝试一些其他可用的 HTTP 客户端。受欢迎的是 Apache Http Client or OK Http client。但是,我也可以建议我自己的带有 Http 客户端的开源 MgntUtils 库。它可能不像其他库那么广泛,但非常简单,适合向同一个 URL 多次发送请求。如果您想使用我的库,您的代码将如下所示
HttpClient client = new HttpClient();
client.setConnectionUrl("https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords&metadataPrefix=oai_primo&set=PRIMO&from=2020-01-22T12:39:59Z&until=2020-02-28T11:40:00Z");
client.setRequestProperty("Accept", "application/xml");
String xmlStr = client.sendHttpRequest(HttpMethod.GET);
这是 HttpClient class. The library could be obtained as Maven artifacts or on Github 的 Javadoc(带有源代码和 Javadoc)
问题是 WebTarget
使用上面的代码,请求只调用了这个 URL https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords
这确实会导致错误!
<OAI-PMH>
<responseDate>2021-02-07T10:06:28Z</responseDate>
<request verb="ListRecords">https://cmi.zb.uzh.ch/primo/api/oaipmh</request>
<error code="badArgument">Unknown arguments: </error>
</OAI-PMH>
如此处所述我不得不覆盖目标。
WebTarget target = client.target("https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords");
target = target.queryParam("metadataPrefix", "oai_primo")
.queryParam("set", "PRIMO")
.queryParam("from", "2020-01-22T12:39:59Z")
.queryParam("until", "2020-02-28T11:40:00Z" );
这是关于参数化的请求。我的应用程序的用户应该能够为请求选择参数。然后我将从响应中读取 xml 并使用 JAXB 对其进行解析。 我是这样成功完成的:
String uri = "https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords&metadataPrefix=oai_primo&set=PRIMO&from=2020-01-22T12:39:59Z&until=2020-02-28T11:40:00Z";
URL url = new URL(uri);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
InputStream xml = connection.getInputStream();
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
oai = (OAIPMHtype) jaxbUnmarshaller.unmarshal(xml);
但我想动态创建请求。有一个 JSF 页面,用户可以在其中输入参数。 我想到了一个 Jersey-Client,因为我可以很容易地用字段替换 queryParam 中的字符串。但是我不能 link Jersey-Client 到我的 Unmarshaller。
我的想法是将响应转换为输入流并将其提供给 Unmarshaller。
这是我试过的。
主要方法
public static void main(String[] args) {
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target("https://cmi.zb.uzh.ch/primo/api/oaipmh");
target.queryParam("verb", "ListRecords")
.queryParam("metadataPrefix", "oai-primo")
.queryParam("set", "PRIMO")
.queryParam("from", "2020-01-22T12:39:59Z")
.queryParam("until", "2020-02-28T11:40:00Z" );
InputStream stream = target.request()
.accept(MediaType.TEXT_XML)
.get(InputStream.class);
}
}
错误信息
Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/xml;charset=utf-8 and type class java.io.InputStream
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:163)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:467)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.get(ClientInvocationBuilder.java:197)
at ch.hbu.sacker.oaipmh.VogellaExample.main(VogellaExample.java:45)
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type text/xml;charset=utf-8 and type class java.io.InputStream
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:37)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:80)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:53)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:211)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:88)
at org.jboss.resteasy.specimpl.AbstractBuiltResponse.readEntity(AbstractBuiltResponse.java:256)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:127)
... 3 more
有人知道为什么会这样吗?
您尝试使用 3d 派对 Http 客户端而不是使用 HttpURLConnection class 是正确的。您可以做的是尝试一些其他可用的 HTTP 客户端。受欢迎的是 Apache Http Client or OK Http client。但是,我也可以建议我自己的带有 Http 客户端的开源 MgntUtils 库。它可能不像其他库那么广泛,但非常简单,适合向同一个 URL 多次发送请求。如果您想使用我的库,您的代码将如下所示
HttpClient client = new HttpClient();
client.setConnectionUrl("https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords&metadataPrefix=oai_primo&set=PRIMO&from=2020-01-22T12:39:59Z&until=2020-02-28T11:40:00Z");
client.setRequestProperty("Accept", "application/xml");
String xmlStr = client.sendHttpRequest(HttpMethod.GET);
这是 HttpClient class. The library could be obtained as Maven artifacts or on Github 的 Javadoc(带有源代码和 Javadoc)
问题是 WebTarget
使用上面的代码,请求只调用了这个 URL https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords
这确实会导致错误!
<OAI-PMH>
<responseDate>2021-02-07T10:06:28Z</responseDate>
<request verb="ListRecords">https://cmi.zb.uzh.ch/primo/api/oaipmh</request>
<error code="badArgument">Unknown arguments: </error>
</OAI-PMH>
如此处所述
WebTarget target = client.target("https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords");
target = target.queryParam("metadataPrefix", "oai_primo")
.queryParam("set", "PRIMO")
.queryParam("from", "2020-01-22T12:39:59Z")
.queryParam("until", "2020-02-28T11:40:00Z" );