首页 > 解决方案 > HttpRequestExecutingMessageHandler 中的 setExpectedResponseType() 方法

问题描述

下面是 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;
}

下面是 REST 控制器类中的 POST 方法:

@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);
}

下面是服务激活方法的配置:

@Override
@ServiceActivator(inputChannel="rtpResponseChannel")
public void makeCall(ResponseEntity<RTPResponse> message) {
    System.out.println("Message: " + message.getBody());
    System.out.println(message.getClass().getCanonicalName());
}

我在 ResponseEntity 对象的主体中收到 null 。我缺少哪个配置?

编辑1:

当我使用setExpectedResponseType()与上面相同的控制器配置时。

@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;
}

RTPResponse对象未包裹在ResponseEntity.

我得到如下错误:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method makeCall(rtp.model.RTPResponse) cannot be found on rtp.RTPRequestServiceClient type

编辑2:

换句话说,我应该在 上使用什么配置HttpRequestExecutingMessageHandler来获取消息对象,以便我在消息有效负载中拥有提取的正文和所有的标头MessageHeaders,包括状态。

我尝试使用GenericMessage传递给类的setExpectedResponseType方法HttpRequestExecutingMessageHandler

但它给了我如下错误,这是可以理解的:

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?)

标签: springspring-integrationspring-rest

解决方案


但是你自己说—— setExpectedResponseType()

你真的很怀念这个配置。

在这种情况下body,响应实体为空:

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();
        }
    }
}

如果您不喜欢Class<?>为该选项提供一个,您可以考虑使用:

/**
 * 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) {

反而。在这种情况下,您确实可以针对 a 解析目标预期响应类型,requestMessage并且还可以访问整个BeanFactory其他 bean 调用。


推荐阅读