Reputation: 825
I have a little bit understanding about Spring Integration and so far i have used JMS and File outbound adapters and now i want to introduce the HTTP out bound adapter for Spring REST support. So far so good an i was able to call external REST api with outany issue as below.
Spring Integration Config
<int-http:outbound-gateway id="outbound.gateway"
request-channel="get.request.channel" url="https://jsonplaceholder.typicode.com/posts/1"
http-method="GET" expected-response-type="com.cst.entity.Post"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel">
</int-http:outbound-gateway>
Outbound gateway invokation
public void restTest() throws Exception{
Message<?> message = MessageBuilder.withPayload().build();
getRequestChannel.send(message);
Message<?> receivedMsg = receivedChannel.receive();
Post post = (Post) receivedMsg.getPayload();
System.out.println("############## ServerMsg ##############");
System.out.println(post.toString());
System.out.println("############## Done! ##############");
}
However i want to develop a framework where developers can invoke any REST url with any method and expect different types of response types. I found a way of dynamically setting the URL as below by introducing
<int-http:outbound-gateway id="outbound.gateway"
request-channel="get.request.channel" url="{fhirurl}"
http-method="GET" expected-response-type="com.bst.pages.crm.web.Post"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel">
</int-http:outbound-gateway>
with
public void restTest() throws Exception{
FHIRInput input = new FHIRInput();
input.setUrl(url);
Message<?> message = MessageBuilder.withPayload(input).build();
getRequestChannel.send(message);
Message<?> receivedMsg = receivedChannel.receive();
Post post = (Post) receivedMsg.getPayload();
System.out.println("############## ServerMsg ##############");
System.out.println(post.toString());
System.out.println("############## Done! ##############");
}
Then i tried to implement dynamic HTTP methods with dynamic response types using the above method and it didn't work and it looks like we can handle only the URL using <int-http:uri-variable/>
.
What would be the ideal solution for this. appreciate your help
Thanks, Keth
EDIT
After following below comments i was able to implement a framework where developers can call use dynamic URL s based on the payload content. below is my configuration for HTTP outbound adapter.
<int-http:outbound-gateway id="outbound.gateway"
request-channel="get.request.channel" url="{fhirurl}"
http-method-expression="payload.getHttpMethod()" expected-response-type-expression="payload.getResponseType()"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel">
<int-http:uri-variable name="fhirurl" expression="payload.getUrl()"/>
</int-http:outbound-gateway>
However im still looking for a way to pass a dynamic request body as a POST parameter. Since we use payload to carry the URL, http method and expected response type i can not pass the request body.
Upvotes: 0
Views: 2173
Reputation: 174554
It's not clear what you mean by
Then i tried to implement dynamic HTTP methods with dynamic response types using the above method and it didn't work and it looks like we can handle only the URL using
<int-http:uri-variable/>
.
To handle multiple response types, get them as String (JSON) and then use transformer(s) to convert to the types.
EDIT1
The response type and method can be an expressions:
<xsd:attribute name="expected-response-type-expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
SpEL expression to determine the type for the expected response to which the response body should be converted
The returned value of the expression could be an instance of java.lang.Class or
java.lang.String representing a fully qualified class name.
This attribute cannot be provided if expected-response-type has a value
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="http-method-expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
The SpEL expression to determine HTTP method, use when executing requests with this adapter,
dynamically. This attribute cannot be provided if http-method has a value.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
Solution
I was able to come with a solution for a simple framework where we can allow developers to call different rest URLs with different HTTP methods and Response types.
This is the configuration for Spring Integration
<int:channel id='reply.channel'>
<int:queue capacity='10' />
</int:channel>
<int:channel id='request.channel'/>
<int:channel id='outbound.Channel'/>
<int:gateway id="outboundGateway"
service-interface="com.bst.pm.PostGateway"
default-request-channel="outbound.Channel">
</int:gateway>
<int:object-to-json-transformer input-channel="outbound.Channel" output-channel="request.channel"/>
<int-http:outbound-gateway id="outbound.gateway"
request-channel="request.channel" url-expression="headers.bstUrl"
http-method-expression="headers.bstHttpMethod" expected-response-type-expression="headers.bstExpectedResponseType"
charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel"
mapped-request-headers="bst*, HTTP_REQUEST_HEADERS">
</int-http:outbound-gateway>
and here is my Java code for invoking the above integration system.
@Autowired @Qualifier("reply.channel") PollableChannel receivedChannel;
@Autowired @Qualifier("request.channel") MessageChannel getRequestChannel;
@Autowired @Qualifier("outbound.Channel") MessageChannel httpOutboundGateway;
Post post = new Post();
post.setTitle("Spring INtegration Test");
post.setBody("This is a sample request body to test Spring Integration HTTP Outbound gateway");
post.setUserId(Long.valueOf(1));
Message<?> message = MessageBuilder.withPayload(post)
.setHeader("bstUrl", "https://jsonplaceholder.typicode.com/posts")
.setHeader("bstHttpMethod", "POST")
.setHeader("bstExpectedResponseType", "com.bst.pages.crm.web.Post")
.build();
httpOutboundGateway.send(message);
Message<?> receivedMsg = receivedChannel.receive();
Post post = (Post) receivedMsg.getPayload();
System.out.println("############## ServerMsg ##############");
System.out.println(o);
System.out.println("############## Done! ##############");
Upvotes: 1