봄 HATEOAS 버전 0.25를 사용하여 코드의 봄 HATEOAS 부분에 제 6 장에서, 최근 봄 전투를 중국어 버전의 5 판을 읽는하지만, 최신 새로운 봄 부팅의 사용의 결과로, 업그레이드를 수행 기존 API에 봄 HATEOAS 1.0 (기사로 일 봄 부팅 2.2.4의 최신 버전을 발표했다) 내가 코드 책을 업그레이드이 마이그레이션 결정 그래서 봄 HATEOAS 1.0.3 코드는,이 책에서 실행되지로드.
온라인 책의이 부분을 읽어 https://potoyang.gitbook.io/spring-in-action-v5/di-6-zhang-chuang-jian-rest-fu-wu/6.2-qi-yong-chao-mei -ti
변화의 봄 HATEOAS 1.0 버전
하이퍼 미디어 형식 등록 API를 도입하여 가장 큰 변화 패키지 구조는 봄 HATEOAS에서 다른 미디어 형식을 지원하도록 구현되어있다. 이것은 클라이언트 API 및 서버 API (라는 이름의 패키지) 패키지 및 구현 미디어 유형의 명확한 분리가 발생합니다 mediatype
.
가장 큰 변화는 모델로 표현 원래 자원, 특정 변경은 다음이다.
에서 ResourceSupport
/ Resource
/ Resources
/ PagedResources
그룹 클래스 정말 적절라는 느낌이 없다. 결국, 사실, 제공하는 하이퍼 미디어 정보와 내용으로 그들을 풍요롭게 할 수있는 이러한 리소스의 유형이 아니라 모델을 의미하지 않는다. 이 방법의 이전 이름에 매핑 새 이름입니다 :
-
ResourceSupport
그것은 지금RepresentationModel
-
Resource
그것은 지금EntityModel
-
Resources
그것은 지금CollectionModel
-
PagedResources
그것은 지금PagedModel
따라서, ResourceAssembler
그 변경 한 내용 RepresentationModelAssembler
및 그 방법 toResource(…)
, 및 각각toResources(…)
개명 toModel(…)
하고 toCollectionModel(…)
. 이름 변경도 포함 된 클래스에 반영됩니다TypeReferences
.
-
RepresentationModel.getLinks()
이제 개시Links
(예를 통해List<Link>
상기) 예 하기의 다른 API에 개시된Links
다양한 전략을 사용 연결하고 다른 합류 인스턴스. 마찬가지로, 접근 방식에 바인딩에서 제네릭 형식 인스턴스 반환에 대한 링크 자체의 인스턴스를 추가 할 수 있습니다되고있다. -
LinkDiscoverer
API는로 이동client
패키지. -
에서
LinkBuilder
와EntityLinks
API는 이동되었습니다server
패키지. -
ControllerLinkBuilder
이동 한server.mvc
, 대체하지 않는 것이 좋습니다WebMvcLinkBuilder
. -
RelProvider
그것은 이름이 변경되었습니다LinkRelationProvider
반환LinkRelation
하는 대신 인스턴스를String
. -
VndError
그것은 이동되었습니다mediatype.vnderror
스위트.
봄 HATEOAS 많은 변화가 설명서를 참조하십시오 : https://spring.io/projects/spring-hateoas
코드 마이그레이션 업그레이드
이 책 자원에 6.4 추가 하이퍼 링크 목록
@GetMapping ( "/ 최근" ) 공공 CollectionModel <EntityModel <타코 >> recentTacos () { PageRequest 페이지 = PageRequest.of ( 0, 12, Sort.by ( "createdAt" ) .descending ()); 목록 <타코> 타코 = tacoRepo.findAll (페이지) .getContent (); CollectionModel <EntityModel <타코 >> recentResources = CollectionModel.wrap (타코); recentResources.add ( 새로운 링크 (에 "http : // localhost를 : 8080 / 디자인 / 최근", "최근 사용" )); 반환 recentResources을; }
하드 코딩 된 URL을 제거
@GetMapping ( "/ 최근" ) 공공 CollectionModel <EntityModel <타코 >> recentTacos () { PageRequest 페이지 = PageRequest.of ( 0, 12, Sort.by ( "createdAt" ) .descending ()); 목록 <타코> 타코 = tacoRepo.findAll (페이지) .getContent (); CollectionModel <EntityModel <타코 >> recentResources = CollectionModel.wrap (타코); recentResources.add ( LINKTO (. methodOn (DesignTacoController 클래스 ) .recentTacos ()) withRel ( "최근 사용." )); 반환 recentResources을; }
공공 클래스 TacoResource는 확장 RepresentationModel <TacoResource을> { @얻는 사람 개인 문자열 이름; @얻는 사람 개인 날짜 createdAt; @얻는 사람 개인 목록 <성분> 재료; 공개 TacoResource (타코 타코) { 이 .name과는 = taco.getName을 (); 이 .createdAt = taco.getCreatedAt (); 이 .ingredients = taco.getIngredients (); } }
공용 클래스 TacoResourceAssembler는 연장 RepresentationModelAssemblerSupport <타코 TacoResource> { / ** *는 {신규 작성 @link 사용 RepresentationModelAssemblerSupport} 지정된 컨트롤러 클래스 자원 유형. * * @param controllerClass DesignTacoController { @literal DesignTacoController}. * @param resourceType에서 TacoResource { @literal TacoResource}. * / 공용 TacoResourceAssembler (클래스 controllerClass 클래스 <TacoResource> <?> resourceType에서) { 슈퍼 (controllerClass, resourceType에서); } @우세하다 보호 TacoResource instantiateModel (타코 타코) { 반환 새 TacoResource (타코); } @우세하다 공개 TacoResource toModel (타코 엔티티) { 복귀 createModelWithId (entity.getId () 엔티티); } }
의 ()을 보정 한 후 recentTacos
@GetMapping ( "/ recentNew" ) 공중 CollectionModel <TacoResource> recentTacos () { PageRequest 페이지 = PageRequest.of ( 0, 12, Sort.by ( "createdAt" ) .descending ()); 목록 <타코> 타코 = tacoRepo.findAll (페이지) .getContent (); CollectionModel <TacoResource> = tacoResources 새로운 TacoResourceAssembler (DesignTacoController. 클래스 , TacoResource. 등급 ) .toCollectionModel (타코); tacoResources.add (LINKTO (methodOn (DesignTacoController. 클래스 ) .recentTacos ()) .withRel ( "최근 사용" )); 반환 tacoResources을; }
객체는 IngredientResource를 생성
@Data 공용 클래스 IngredientResource이 연장 RepresentationModel <IngredientResource> { 공개 IngredientResource (성분 성분) { 이 .name을 = ingredient.getName을 (); 이 .type는 = ingredient.getType을 (); } 민간 최종 문자열 이름; 민간 최종 Ingredient.Type 유형; }
공용 클래스 IngredientResourceAssembler는 연장 RepresentationModelAssemblerSupport <성분이 IngredientResource> { / ** * 만드는 새로운 { @link 지정된 컨트롤러 클래스 자원 유형을 사용 RepresentationModelAssemblerSupport}. * * @Param {controllerClass IngredientController @literal IngredientController}. * @param {resourceType에서 IngredientResource @literal IngredientResource}. * / 공용 IngredientResourceAssembler (클래스 controllerClass 클래스 <IngredientResource> <?> resourceType에서) { 슈퍼 (controllerClass, resourceType에서); } @우세하다 보호 IngredientResource instantiateModel {(성분 엔티티) 반환 새로운 IngredientResource (법인); } @우세하다 공개 IngredientResource toModel (성분 엔티티) { 복귀 createModelWithId (entity.getId () 엔티티); } }
객체 TacoResource의 변경
공공 클래스 TacoResource는 확장 RepresentationModel <TacoResource> { 개인 정적 최종 IngredientResourceAssembler을 ingredientAssembler는 = 새로운 IngredientResourceAssembler (. IngredientController 클래스 ., IngredientResource 클래스 ); @얻는 사람 개인 문자열 이름; @얻는 사람 개인 날짜 createdAt; @얻는 사람 개인 CollectionModel <IngredientResource> 재료; 공개 TacoResource (타코 타코) { 이 .name과는 = taco.getName을 (); 이 .createdAt = taco.getCreatedAt (); 이 .ingredients = ingredientAssembler.toCollectionModel (taco.getIngredients ()); } }
6.7 목록
@RepositoryRestController 공공 클래스 RecentTacosController { 개인 TacoRepository tacoRepo; 공개 RecentTacosController (TacoRepository tacoRepo) { 이 .tacoRepo = tacoRepo; } / ** * @GetMapping가 "/ 타코 / 최근"경로하지만, 클래스 레벨에 매핑 있지만 @Repository RestController 노트는 반드시이 경로를 추가하는 것입니다 * 접두사로 봄 데이터 REST의 기본 경로. 우리의 구성에 따르면, recentTacos () 메소드가 요청 GET을 처리 할 것 "/ API / 타코 / 최근"입니다. * * / @GetMapping (경로 = "/ 타코 / 최근"생산 = "애플리케이션 / HAL + JSON" ) 공중 ResponseEntity <CollectionModel <TacoResource >> recentTacos () { PageRequest 페이지 = PageRequest.of ( 0, 12, Sort.by ( "createdAt" ) .descending ()); 목록 <타코> 타코 = tacoRepo.findAll (페이지) .getContent (); CollectionModel <TacoResource> = tacoResources 새로운 TacoResourceAssembler (DesignTacoController. 클래스 , TacoResource. 등급 ) .toCollectionModel (타코); tacoResources.add ( LINKTO (methodOn (RecentTacosController. 클래스 ) .recentTacos ()) .withRel ( "최근 사용" )); 돌아가 새로운 ResponseEntity를 <> (tacoResources, HttpStatus.OK); } }
또 다른 방법
당신이 자원 어셈블러의 사용은 약간의 문제를 작성하는 생각한다면, 당신은 또한이 방법을 채택 할 수있다.
( "/ 직원"@GetMapping ) 공공 ResponseEntity을 <CollectionModel <EntityModel <타코 >>> findall은 () { PageRequest 페이지 = PageRequest.of ( 0, 12, Sort.by ( "createdAt" ) .descending ()); 목록 <EntityModel <타코 >> 직원 = StreamSupport.stream (tacoRepo.findAll (페이지) .spliterator (), 거짓 ) .MAP (직원 -> 새 EntityModel <> (직원, LINKTO (methodOn (DesignTacoController. 클래스 ) .findOne (employee.getId ())). withSelfRel () LINKTO (methodOn (DesignTacoController. 클래스 ) .findAll ()). withRel ( "직원" ))) .collect (Collectors.toList ()); 반환 ResponseEntity.ok ( 새 CollectionModel <> (직원, LINKTO (methodOn (DesignTacoController. 등급 ) .findAll ()) withSelfRel ())).; }
@GetMapping ( "/ 직원 / {ID}" ) 공공 ResponseEntity <EntityModel <타코 >> findOne (@PathVariable 긴 ID) { 반환 tacoRepo.findById (ID) .MAP (직원 -> 새 EntityModel <> (직원, LINKTO (methodOn (DesignTacoController. 클래스 ) .findOne (employee.getId ())). withSelfRel (), // LINKTO (methodOn (DesignTacoController. 클래스 ) .findAll ()). withRel ( "직원"))) // . 지도 (ResponseEntity :: OK) .orElse (ResponseEntity.notFound () 빌드 ().); }
참고 자료 : https://github.com/spring-projects/spring-hateoas-examples/tree/master/simplified
종료