Jersey客户端无法反序列化XML输出:找不到消息正文阅读器

问题描述 投票:0回答:1

我正在使用旧的[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无法独自完成它(也许在XMLJAXBElementProviderXMLRootElementProviderXMLRootObjectProvider的帮助下?)。这是怎么回事?

java xml spring rest jersey
1个回答
0
投票

我发现解决此问题的最简单方法是创建自定义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);

您现在应该成功反序列化对象。

© www.soinside.com 2019 - 2024. All rights reserved.