Как заставить Spring Integration Http.inboundGateway вернуть HAL Json?

Я установил для следующего свойства значение true spring.hateoas.use-hal-as-default-json-media-type и добавил org.springframework.boot:spring-boot-starter-hateoas в качестве зависимости.

Код

@Bean
public IntegrationFlow myUserFlow() {
    return IntegrationFlows
            .from(Http.inboundGateway("/user")
                    .requestMapping(r -> r.methods(HttpMethod.GET))
                    .get()
            )
            .handle((payload, headers) -> new MyUser("Joe Blogs")
                    .add(Link.of("http://localhost:8080/account", LinkRelation.of("account"))))
            .get();
}

Ответ

GET http://localhost:8080/user
HTTP/1.1 200 
connection: Keep-Alive, keep-alive
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 11 Jan 2021 18:31:13 GMT
Keep-Alive: timeout=60

{
  "name": "Joe Blogs",
  "links": [
    {
      "rel": "account",
      "href": "http://localhost:8080/account"
    }
  ]
}

Response code: 200; Time: 19ms; Content length: 87 bytes

Я ожидал, что ответ будет возвращен в формате HAL, например.

{
  "name": "Joe Blogs",
  "_links": [
    {
      "account":{
          "href": "http://localhost:8080/account"
       }
    }
  ]
}

Почему это не так? И как мне сделать так?

Пример приложения: https://github.com/kevvvvyp/si-hateoas-demo


person Kevvvvyp    schedule 11.01.2021    source источник


Ответы (1)


Решение такое:

public IntegrationFlow myUserFlow(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
    return IntegrationFlows
            .from(Http.inboundGateway("/user")
                    .messageConverters(requestMappingHandlerAdapter.getMessageConverters().toArray(HttpMessageConverter[]::new))

Проблема в том, что адаптеры HTTP-канала Spring Integration не настраиваются Spring Boot автоматически, и они определенно не знают о вашей настройке HAL.

Итак, нам нужно подождать, пока RequestMappingHandlerAdapter не будет обработано Spring Boot и настройкой hatoas. Затем мы берем его преобразователи и внедряем их в наш Http.inboundGateway().

Я хотел сказать, что мы можем подумать о чем-то автоматическом в Spring Boot, чтобы подобрать эту настройку, но поскольку мы действительно говорим не о какой-то инфраструктуре, такой как @RequestMapping MVC, а скорее о некоторых конкретных компонентах, вероятно, действительно лучше придерживаться явного конфигурация.

Я не уверен, почему мы не можем использовать вместо этого HttpMessageConverters, но похоже, что RequestMappingHandlerAdapter настраивается позже, когда этот вид bean-компонентов (IntegrtionFlow) уже проанализирован и создан.

person Artem Bilan    schedule 11.01.2021
comment
Спасибо Артем - person Kevvvvyp; 12.01.2021