Reputation: 352
Below is the configuration of HttpRequestExecutingMessageHandler
@ServiceActivator(inputChannel = "rtpRequestChannel")
@Bean
public MessageHandler httResponseMessageHandler(MessageChannel rtpResponseChannel) {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
"http://localhost:8080/rtp");
handler.setHttpMethod(HttpMethod.POST);
handler.setOutputChannel(rtpResponseChannel);
handler.setShouldTrack(true);
handler.setStatsEnabled(true);
return handler;
}
Below is the POST method in the REST controller class:
@RequestMapping(value = "/rtp", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<RTPResponse> persistRTP(@RequestBody RTPRequest request) {
System.out.println("In post method " + request);
if (request != null) {
return new ResponseEntity<RTPResponse>(new RTPResponse("12:12:2017", "Test", null, "100", "100"), HttpStatus.OK);
}
return new ResponseEntity<RTPResponse>(new RTPResponse("12:12:2017", "Dummy", null, "Dummy", "Dummy"), HttpStatus.OK);
}
Below is the config of the service activator method:
@Override
@ServiceActivator(inputChannel="rtpResponseChannel")
public void makeCall(ResponseEntity<RTPResponse> message) {
System.out.println("Message: " + message.getBody());
System.out.println(message.getClass().getCanonicalName());
}
I am receiving null in the body of the ResponseEntity object. Which configuration am I missing?
Edit 1:
When I use the setExpectedResponseType()
, with the same controller configuration as above.
@ServiceActivator(inputChannel = "rtpRequestPostOperationRequestChannel")
@Bean
public MessageHandler httResponseMessageHandler(MessageChannel rtpRequestPostOperationResponseChannel) {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(
"http://localhost:8080/rtp");
handler.setHttpMethod(HttpMethod.POST);
handler.setOutputChannel(rtpRequestPostOperationResponseChannel);
handler.setExpectedResponseType(RTPResponse.class);
return handler;
}
The RTPResponse
object is not wrapped in the ResponseEntity
.
I get the error as below:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method makeCall(rtp.model.RTPResponse) cannot be found on rtp.RTPRequestServiceClient type
Edit 2:
In other words, what configuration should I use on the HttpRequestExecutingMessageHandler
to get hold of the message object so that I have the extracted body in the message payload and all the headers to the MessageHeaders
, including status.
I tried using GenericMessage
being passed to the setExpectedResponseType
method of HttpRequestExecutingMessageHandler
class.
But it gave me the error as below which is understandable:
Can not construct instance of org.springframework.messaging.support.GenericMessage: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
Upvotes: 0
Views: 322
Reputation: 121552
But you said yourself - setExpectedResponseType()
.
You really miss exactly this configuration.
In that case the body
of response entity is empty:
private class ResponseEntityResponseExtractor<T> implements ResponseExtractor<ResponseEntity<T>> {
@Nullable
private final HttpMessageConverterExtractor<T> delegate;
public ResponseEntityResponseExtractor(@Nullable Type responseType) {
if (responseType != null && Void.class != responseType) {
this.delegate = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
}
else {
this.delegate = null;
}
}
@Override
public ResponseEntity<T> extractData(ClientHttpResponse response) throws IOException {
if (this.delegate != null) {
T body = this.delegate.extractData(response);
return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).body(body);
}
else {
return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).build();
}
}
}
If you don't like to provide a Class<?>
for that option, you can consider to use:
/**
* Specify the {@link Expression} to determine the type for the expected response
* The returned value of the expression could be an instance of {@link Class} or
* {@link String} representing a fully qualified class name.
* @param expectedResponseTypeExpression The expected response type expression.
* Also see {@link #setExpectedResponseType}
*/
public void setExpectedResponseTypeExpression(Expression expectedResponseTypeExpression) {
instead. In this case you really can resolve the target expected response type against a requestMessage
and also get access to the whole BeanFactory
for some other beans calls.
Upvotes: 2