SetExpectedResponseType () в HttpRequestExecutingMessageHandler

Ниже представлена ​​конфигурация 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;
}

Ниже приведен метод POST в классе контроллера REST:

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

Я получаю значение null в теле объекта ResponseEntity. Какая конфигурация мне не хватает?

Изменить 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?)

0
0
269
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Но вы сами сказали - 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) {

вместо. В этом случае вы действительно можете сопоставить целевой ожидаемый тип ответа с requestMessage, а также получить доступ ко всему BeanFactory для некоторых других вызовов bean-компонентов.

Здравствуйте, Артем, я добавил правку, чтобы объяснить проблему, с которой я столкнулся с setExpectedResponseType

AbNig 27.04.2018 22:51

Ой! Я понимаю. Вы хотите использовать ResponseEntity<RTPResponse> в качестве аргумента метода, но мы этого не поддерживаем. Вместо этого вам понадобится Message<RTPResponse>. в ResponseEntity нет причин, так как мы извлекаем его body на payload и копируем все заголовки на MessageHeaders, включая status.

Artem Bilan 27.04.2018 22:58

Извините, Артем, я не понял, что вы имели в виду под «Вместо этого вам нужен Message<RTPResponse>» в своем комментарии выше. Добавление запроса как Edit 2.

AbNig 27.04.2018 23:14

Да, извините, я не понял. Ваш метод обслуживания makeCall() должен быть изменен, чтобы принимать Message<RTPTesponse> вместо текущего ResponseEntity. HttpReeuestExecutionMessageHandler все еще должен быть настроен с setExpectedResponseType(). Дайте мне знать, если это еще не ясно.

Artem Bilan 28.04.2018 02:53

Спасибо, Артем. Я понял из вашего последнего комментария, когда внимательно его прочитал. Теперь это работает. У меня есть перегруженный метод в классе контроллера. Один возвращает RTPResponse, а другой возвращает ResponseEntity для использования в Интернете.

AbNig 28.04.2018 03:08

Другие вопросы по теме