TL;博士
我有一个REST服务,它响应XML主体。我想使用HTTP消息转换器解组响应。但是,从服务返回的XML并不总是映射到单个Java类型。如何配置HTTP出站网关以期望多种响应类型?
我正在使用
我正在尝试设置调用REST服务的int-http:outbound-gateway
。 REST服务使用&text; / xml'进行响应。我希望能够使用MarshallingHttpMessageConverter来编组对Java对象的响应。
REST服务可以响应成功的' XML响应或“错误”#39; 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
上,我注入了一个绑定了Success和Failure对象的OXM unmarshaller:
<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.Success
或com.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.Success
还是 com.example.Failure
?
答案 0 :(得分:2)
Artem Bilan's answer按照要求回答了我的问题。但是,我最终使用另一种方法来实现我的目标。
我设置我的出站网关以接收xml作为字符串,但我没有使用MarshallingHttpMessageConverter
。相反,我将出站网关放在一个链中,其中网关是第一个端点,而解组转换器是第二个端点。所以我的配置如下:
<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:chain input-channel="restRequest" output-channel="restResponse">
<int-http:outbound-gateway
id="myRestServiceGateway"
url-expression="'http://localhost:8855/webapp/ws/testId/{testId}'"
http-method="GET"
rest-template="restTemplate"
expected-response-type="java.lang.String">
<int-http:uri-variable name="testId" expression="payload"/>
</int-http:outbound-gateway>
<int-xml:unmarshalling-transformer unmarshaller="myRestMarshaller"/>
</int:chain>
我更喜欢这种方法,因为我认为它提供了更多的关注点分离。现在网关只关心与HTTP服务的通信,而编组人员则关注翻译响应。
我也不需要在我的模型中引入一个永远不会被使用的额外课程。
答案 1 :(得分:1)
您无法指定多个expected-response-type
,因为它是RestTemplate
的一部分
通过ResponseExtractor
转换回复。
RestTemplate
确实使用HttpMessageConverter
将响应转换为适当的Java对象。
由于您希望XML作为响应并希望将其转换为POJO,因此使用MarshallingHttpMessageConverter
是正确的方法。
那么如何处理转换成功和失败响应的要求呢?
我们无法为RestTemplate
配置多种类型,但我们可以为JaxbMarshaller
执行此操作。有一种欺骗RestTemplate
和MarshallingHttpMessageConverter
的技巧。
您可以为Success
和Failure
创建超类,并将其配置为expected-response-type
。除了class-to-be-bound
和JaxbMarshaller
之外,我还要将Success
添加为Failure
。
并且不要忘记使用@XmlRootElement
标记新的超类,因为JaxbMarshaller
默认使用checkForXmlRootElement = true
。