1

It's about a parametrized Request. The users of my application should be able to choose the parameters for the request. I will then read xml from the response and parse it with JAXB. I have done it successfully like this:

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);

But I want to create the request dynamically. There is a JSF-Page where the user can enter the parameters. I thought of a Jersey-Client, because I can easily replace the Strings in the queryParam with fields. But I cannot link the Jersey-Client to my Unmarshaller.

My idea is to cast the response into a inputstream and feed it to Unmarshaller.

Here is what I tried.

Main Method

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);

    }
}

Errormessage

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

Does anyone know why this happens?

BAB
  • 11
  • 3
  • Why would you want an `InputStream` with XML data? Why not get the XML? I mean, what are you going to do with the `InputStream`? This sounds like an [XY problem](https://meta.stackexchange.com/q/66377/351454) to me. – Andreas Jan 26 '21 at 22:15
  • I don't understand why do you want inputstream. You should be able to get response and then the inputstream from the response. – Nehghal Jan 26 '21 at 22:04
  • @Nehgal, yes that should be simple `Response response = target.request().accept(MediaType.TEXT_XML).get(Response.class);` and then `InputStream stream = response.getEntity().getContent();` but Eclipse tells me "The method getContent() is undefined for the type Object" – BAB Jan 27 '21 at 09:13
  • I have reformulated my question to make clear what I want to achieve and what I have tried. – BAB Jan 27 '21 at 09:18

2 Answers2

0

You are correct in trying to use 3d party Http client rather than doing it with HttpURLConnection class. What you can do is try some other HTTP clients available. Popular ones would be Apache Http Client or OK Http client. However, I may suggest my own Open Source MgntUtils library with Http client as well. It may be not as extensive as other library but is very simple and geared for sending requests multiple times to the same URL. In case you want to use my library your code would look something like this

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);

Here is a Javadoc for HttpClient class. The library could be obtained as Maven artifacts or on Github (with source code and Javadoc)

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
0

Problem was the WebTarget With the above code the request called only this URL https://cmi.zb.uzh.ch/primo/api/oaipmh?verb=ListRecords which does result in an error!

<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>

As explained here Jersey rest client not adding query parameters I had to overwrite target.

    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" );
BAB
  • 11
  • 3