web-dev-qa-db-ja.com

Spring HATEOASの「_embedded」プロパティを削除する方法

私は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"
            }
         }
      }
   ]
}

私の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」なしで応答を生成する最良の方法は何ですか?

17
jose_p

documentation が言うように

application/hal + json応答は、application/jsonを受け入れるリクエストに送信する必要があります

応答で_embeddedを省略するには、追加する必要があります

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

application.propertiesへ。

8
Kamill Sokol

このAcceptヘッダーをリクエストに追加します:

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

RestTemplateでResources/Resourceを使用するのは難しいので、HAL機能を閉じます。次のコードでこの機能を無効にします。

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

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

それは私のために働きます。 restTemplateでより多くのサポートがある場合、HALは適切です。

3
shenyu1997

このコードをサービスで使用できます

  constructor(
    private httpClient: HttpClient
  ) { }

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

これは、Jsonの_embedded部分を処理し、必要なデータを抽出します。

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[];
     }
   );
 }
1
Anosh

Spring Dataを使用していて、それを問題と見なしている人のために-解決策は、

spring.data.rest.defaultMediaType = application/json

アプリケーションのプロパティ。リンクはまだ利用可能ですが、もう埋め込まれていません。

0
Stepan Mozyra

生成された結果と期待される結果で説明しているのは、意味的に異なるものです。前者はCollection<Technology>のHAL表現です。後者は、次の表現です。

class Wrapper {
  Resources<Technology> technologies;
}

これが、応答で表示したいトップレベルのtechnologiesプロパティを実際に作成する方法です。後者はコントローラーで作成しません。トップレベルのResourcesinstanceは基本的にはコレクションであり、HALでトップレベルコレクションを表す唯一の方法は_embeddedです。どうやらあなたはそれを望んでいないようですが、それはあなたがあなたのコントローラーメソッドで書いたものです。

あなたがWrapperを持っていると仮定すると、次のようなものが機能するはずです(テストされていません):

Wrapper wrapper = new Wrapper(assembler.toCollectionModel(technologies);
EntityModel<Wrapper> model = EntityModel.of(wrapper);
model.add(linkTo(…));

PS:Spring HATEOAS 1.0以降、ResourcesCollectionModelで、ResourceisはEntityModelです。

0
Oliver Drotbohm