Как удалить свойство "_embedded" в Spring HATEOAS

Я использую Spring Boot и HATEOAS для создания REST API, и когда мой API возвращает коллекцию, она завершается внутри свойства "_embedded", например:

{
   "_links":{
      "self":{
         "href":"http://localhost:8080/technologies"
      }
   },
   "_embedded":{
      "technologies":[
         {
            "id":1,
            "description":"A",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/technologies/1"
               }
            }
         },
         {
            "id":2,
            "description":"B",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/technologies/2"
               }
            }
         }
      ]
   }
}

Я хочу, чтобы ответ был таким:

{
   "_links":{
      "self":{
         "href":"http://localhost:8080/technologies"
      }
   },
   "technologies":[
      {
         "id":1,
         "description":"A",
         "_links":{
            "self":{
               "href":"http://localhost:8080/technologies/1"
            }
         }
      },
      {
         "id":2,
         "description":"B",
         "_links":{
            "self":{
               "href":"http://localhost:8080/technologies/2"
            }
         }
      }
   ]
}

My TechnologiesController:

@RestController
@ExposesResourceFor(Technology.class)
@RequestMapping(value = "/technologies")
public class TechnologiesController {
    ...
    @ResquestMapping(method = RequestMethod.GET, produces = "application/vnd.xpto-technologies.text+json")
    public Resources<Resource<Technology>> getAllTechnologies() {
        List<Technology> technologies = technologyGateway.getAllTechnologies();
        Resources<<Resource<Technology>> resources = new Resources<Resource<Technology>>(technologyResourceAssembler.toResources(technologies));
        resources.add(linkTo(methodOn(TechnologiesController.class).getAllTechnologies()).withSelfRel());
        return resources;
    }

В классе конфигурации есть аннотация @EnableHypermediaSupport (type = EnableHypermediaSupport.HypermediaType.HAL).

Каков наилучший способ получения ответа без "_embedded"?

Ответ 1

Как сообщает ,

application/hal + json ответы должны быть отправлены на запросы, которые принимают Применение /JSON

Чтобы опустить _embedded в ответ, вам нужно добавить

spring.hateoas.use-hal-as-default-json-media-type=false

до application.properties.

Ответ 2

Добавление этого заголовка Accept в запрос:

Accept : application/x-spring-data-verbose+json

Ответ 3

Я закрываю функцию HAL, потому что трудно использовать ресурсы/ресурсы с помощью restTemplate. Я отключаю эту функцию с помощью следующего кода:

public class SpringRestConfiguration implements RepositoryRestConfigurer {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {

        config.setDefaultMediaType(MediaType.APPLICATION_JSON);
        config.useHalAsDefaultJsonMediaType(false);
    }
}

Это работает для меня. HAL хорош, если есть больше поддержки с restTemplate.

Ответ 4

Вы можете использовать этот код в сервисе

  constructor(
    private httpClient: HttpClient
  ) { }

  retrieveAllStudents(){
    return this.httpClient.get<any[]>('http://localhost:8080/students');
  }

Это будет иметь дело с _embedded частью Json и извлекать нужные данные.

export class ListStudentsComponent implements OnInit {

 // declaring variables to be used
  student: Student;
  students: Student[];
  message: string;

  // injecting student service into the constuctor
   constructor(
    private studentService: StudentService,
  ) { }

  ngOnInit() {
    this.refreshStudents();
  }
refreshStudents(){
  this.studentService.retrieveAllStudents().subscribe(
     response => {
       console.log(response);
      this.students = response._embedded.students as Student[];
     }
   );
 }

Ответ 5

Для тех, кто использует Spring Data и считает это проблемой, решение - установить

spring.data.rest.defaultMediaType = application/json

в свойствах приложения. Там по-прежнему ссылки будут доступны, но не _включено больше.