tl; dr

我有一个以XML主体响应的REST服务。我想使用HTTP消息转换器解组响应。但是,从服务返回的XML并不总是映射到单个Java类型。如何配置HTTP出站网关以期望多个响应类型?



我在用


Java 1.6
Spring Integration 3.0.0。发布
Spring Integration HTTP 3.0.0。发布
Spring OXM 4.0.1发布


我正在尝试设置调用REST服务的int-http:outbound-gateway。 REST服务以“ text / xml”响应。我希望能够使用MarshallingHttpMessageConverter来编组对Java Object的响应。

REST服务可以使用“成功” XML响应或“错误” XML响应进行响应。例如,它可能返回:

<?xml version="1.0" encoding="UTF-8"?>
<success>
    <yay>You're call was successful, here is the information you wanted.</yay>
    <information>very important stuff</information>
</success>


否则可能会返回:

<?xml version="1.0" encoding="UTF-8"?>
<failure>
    <boo>You're call was unsuccessful, go in the corner and cry.</boo>
    <error>very important error code</error>
</failure>


因此,我需要设置2个Java对象来将这些不同的响应映射到。所以我创造了

Success.java:

@XmlRootElement(name = "success")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Success{

    private String yay;
    private String information;

    @XmlElement(name = "yay")
    public String getYay() {
        return yay;
    }

    @XmlElement(name = "information")
    public String getInformation() {
        return information;
    }
    //setters omitted for brevity.
}


Failure.java:

@XmlRootElement(name = "failure")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Failure{

    private String boo;
    private String information;

    @XmlElement(name = "boo")
    public String getBoo() {
        return boo;
    }

    @XmlElement(name = "error")
    public String getError() {
        return error;
    }
    //setters omitted for brevity.
}


现在,为了设置出站网关,我为RestTemplate配置了MarshallingHttpMessageConverter。在MarshallingHttpMessageConverter上,我注入绑定了成功和失败对象的OXM解组器:

<oxm:jaxb2-marshaller id="myRestMarshaller">
    <oxm:class-to-be-bound name="com.example.Success" />
    <oxm:class-to-be-bound name="com.example.Failure" />
</oxm:jaxb2-marshaller>


问题是,当我尝试设置int-http:outbound-gateway时,只能将com.example.Successcom.example.Failure之一放入expected-response-type属性。如果我选择使用Success,如果REST服务以Failure响应,它将引发异常,反之亦然。

<int-http:outbound-gateway
    id="myRestServiceGateway"
    url-expression="'http://localhost:8855/webapp/ws/testId/{testId}'"
    http-method="GET"
    request-channel="restRequest"
    reply-channel="restResponse"
    rest-template="restTemplate"
    expected-response-type="com.example.Success">

    <int-http:uri-variable name="testId" expression="payload"/>

</int-http:outbound-gateway>


如何告诉出站网关响应类型可以是com.example.Successcom.example.Failure

最佳答案

您不能指定多个expected-response-type,因为它是RestTemplate的一部分
通过ResponseExtractor转换响应。
的确,RestTemplate使用HttpMessageConverter将响应转换为适当的Java对象。
由于您期望XML作为响应并将其转换为POJO,因此使用MarshallingHttpMessageConverter是正确的方法。


那么如何处理转换成功和失败响应的需求?

我们不能为RestTemplate配置几种类型,但是我们可以为JaxbMarshaller做它。欺骗RestTemplateMarshallingHttpMessageConverter有一个技巧。

您可以为SuccessFailure创建超类,并将其配置为expected-response-type。除了class-to-be-boundJaxbMarshaller以外,将其添加为Success的另一个Failure

并且不要忘记用@XmlRootElement标记新的超类,因为默认情况下JaxbMarshaller使用checkForXmlRootElement = true

07-24 09:49
查看更多