0
votes

I'm using RestEasy as a client to read news from a service.

    ResteasyClient listClient = new ResteasyClientBuilder().build();
    ResteasyWebTarget listTarget = listClient.target("https://someservice.com/file.xml");
    Response r = listTarget.request().get();
    final HexMl feedList = r.readEntity(HexMl.class);

The service does not return an encoding or media type in the response header, only an encoding in the xml itself

<?xml version="1.0" encoding="windows-1252"?>

RestEasy does not seem to evaluate this so I get an exception:

javax.ws.rs.ProcessingException: org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 116; columnNumber: 30; Invalid byte 2 of 3-byte UTF-8 sequence.]
    at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:300)
    at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:196)
    at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:218)
    at com.roche.services.NewsImportService.importFeed(NewsImportService.java:72)
    at com.roche.commands.NewsImportCommand.execute(NewsImportCommand.java:26)
    at com.roche.commands.NewsImportCommand$execute.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:122)
    at Script1.run(Script1.groovy:4)
    at info.magnolia.module.groovy.console.MgnlGroovyConsole$1.call(MgnlGroovyConsole.java:154)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: javax.xml.bind.UnmarshalException

Is there a way to overwrite the encoding RestEasy uses or intercept the response before the entity is read? I tried

Response r = listTarget.request().accept(APPLICATION_XML + ";charset=windows-1252").get();

and

Response r = listTarget.request(APPLICATION_XML + ";charset=windows-1252").get();

and

@Consumes(APPLICATION_XML + ";charset=windows-1252")
public class HexMl { ... }

without success. The XML itself seems to be correctly encoded in windows-1252.

1

1 Answers

0
votes

For now I'm using a ReaderInterceptor, but this doesn't seem right. So I'd still be glad about better suggestions.

ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder();
ResteasyProviderFactory providerFactory = new ResteasyProviderFactory();
RegisterBuiltin.register( providerFactory );
providerFactory.getClientReaderInterceptorRegistry().registerSingleton( new ReaderInterceptor() {
    @Override
    public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
            InputStream is = context.getInputStream();
            String responseBody = IOUtils.toString( is , "windows-1252");

            LOGGER.debug( "received response:\n{}\n\n", responseBody );

            context.setInputStream( new ByteArrayInputStream( responseBody.getBytes() ) );
        return context.proceed();
    }
} );
clientBuilder.providerFactory( providerFactory );

Then I use this clientBuilder to create my client.