The actual migration Spring Release 5 the part of the code HATEOAS Spring Spring HATEOAS 1.0

       In reading the recent Spring combat the fifth edition of the Chinese version, in Chapter 6 on Spring HATEOAS part of the code using the Spring HATEOAS version 0.25, but the latest Spring HATEOAS 1.0 to your legacy API that do the upgrade, resulting in the use of the new Spring Boot (as of articles published the latest version of day Spring Boot 2.2.4) loaded Spring HATEOAS 1.0.3 code is not running in the book, so I decided on this migration upgrade the code book.

Read this part of the book online: https://potoyang.gitbook.io/spring-in-action-v5/di-6-zhang-chuang-jian-rest-fu-wu/6.2-qi-yong-chao-mei -ti

 

Spring HATEOAS 1.0 version of the change

The biggest change package structure by introducing hypermedia type registration API is implemented to support other media types in Spring HATEOAS. This causes the client API and server API (named package) package and a clear separation of media types implemented  mediatype.

The biggest change is the original resource represented as a model, specific changes are as follows.

In ResourceSupportResourceResourcesPagedResourcesgroup class never really feel appropriately named. After all, in fact, does not mean that these types of resources, but rather models that can enrich them by hypermedia information and content provided. This is the new name mapped to the old name of ways:

  • ResourceSupport It's now RepresentationModel

  • Resource It's now EntityModel

  • Resources It's now CollectionModel

  • PagedResources It's now PagedModel

Thus, ResourceAssemblerit has been renamed RepresentationModelAssemblerand method thereof toResource(…), and eachtoResources(…) was renamed toModel(…)and toCollectionModel(…). Name change is also reflected in the class containedTypeReferences .

  • RepresentationModel.getLinks()Now discloses an Linksexample of (through List<Link>), the examples disclosed in the API of the other, to Linksuse various strategies to connect and merge a different instance. Similarly, it has become a generic type from binding to approach allows to add links to the instance returns an instance of itself.

  • The LinkDiscovererAPI is moved to the clientpackage.

  • In LinkBuilderand EntityLinksAPI have been moved to the serverpackage.

  • ControllerLinkBuilderHas been moved server.mvc, it is not recommended to replace WebMvcLinkBuilder.

  • RelProviderIt has been renamed LinkRelationProviderand returned LinkRelationinstance instead String.

  • VndErrorIt has been moved to mediatype.vnderrorsuite.

Spring HATEOAS more changes please refer to the documentation: https://spring.io/projects/spring-hateoas

Code Migration Upgrade

The book Listing 6.4 add hyperlinks to resources

    @GetMapping("/recent")
    public CollectionModel<EntityModel<Taco>> recentTacos() {
        PageRequest page = PageRequest.of(
                0, 12, Sort.by("createdAt").descending());

        List<Taco> tacos = tacoRepo.findAll(page).getContent();
        CollectionModel<EntityModel<Taco>> recentResources = CollectionModel.wrap(tacos);

        recentResources.add(
                new Link("http://localhost:8080/design/recent", "recents"));
        return recentResources;
    }

Eliminate hard-coded URL

    @GetMapping("/recent")
    public CollectionModel<EntityModel<Taco>> recentTacos() {
        PageRequest page = PageRequest.of(
                0, 12, Sort.by("createdAt").descending());

        List<Taco> tacos = tacoRepo.findAll(page).getContent();
        CollectionModel<EntityModel<Taco>> recentResources = CollectionModel.wrap(tacos);

        recentResources.add(
                linkTo(methodOn(DesignTacoController.class).recentTacos()).withRel("recents"));
        return recentResources;
    }
Listing 6.5 is capable of carrying data fields and a list of hyperlinks taco resources
public class TacoResource extends RepresentationModel<TacoResource> {

    @Getter
    private String name;

    @Getter
    private Date createdAt;

    @Getter
    private List<Ingredient> ingredients;

    public TacoResource(Taco taco) {
        this.name = taco.getName();
        this.createdAt = taco.getCreatedAt();
        this.ingredients = taco.getIngredients();
    }
}
Listing 6.6 assembly taco resources of the resource assembler
public class TacoResourceAssembler extends RepresentationModelAssemblerSupport<Taco, TacoResource> {
    /**
     * Creates a new {@link RepresentationModelAssemblerSupport} using the given controller class and resource type.
     *
     * @param controllerClass DesignTacoController {@literal DesignTacoController}.
     * @param resourceType    TacoResource {@literal TacoResource}.
     */
    public TacoResourceAssembler(Class<?> controllerClass, Class<TacoResource> resourceType) {
        super(controllerClass, resourceType);
    }

    @Override
    protected TacoResource instantiateModel(Taco taco) {
        return new TacoResource(taco);
    }


    @Override
    public TacoResource toModel(Taco entity) {
        return createModelWithId(entity.getId(), entity);
    }
}

After adjusting for recentTacos () of

@GetMapping("/recentNew")
    public CollectionModel<TacoResource> recentTacos() {
        PageRequest page = PageRequest.of(
                0, 12, Sort.by("createdAt").descending());
        List<Taco> tacos = tacoRepo.findAll(page).getContent();

        CollectionModel<TacoResource> tacoResources =
                new TacoResourceAssembler(DesignTacoController.class, TacoResource.class).toCollectionModel(tacos);

        tacoResources.add(linkTo(methodOn(DesignTacoController.class)
                .recentTacos())
                        .withRel("recents"));
        return tacoResources;
    }

 

Objects created IngredientResource

@Data
public class IngredientResource extends RepresentationModel<IngredientResource> {
    public IngredientResource(Ingredient ingredient) {
        this.name = ingredient.getName();
        this.type = ingredient.getType();
    }

    private final String name;
    private final Ingredient.Type type;
}
IngredientResourceAssembler objects
public class IngredientResourceAssembler extends RepresentationModelAssemblerSupport<Ingredient, IngredientResource> {
    /**
     * Creates a new {@link RepresentationModelAssemblerSupport} using the given controller class and resource type.
     *
     * @param controllerClass IngredientController {@literal IngredientController}.
     * @param resourceType    IngredientResource {@literal IngredientResource}.
     */
    public IngredientResourceAssembler(Class<?> controllerClass, Class<IngredientResource> resourceType) {
        super(controllerClass, resourceType);
    }

    @Override
    protected IngredientResource instantiateModel(Ingredient entity) {
        return new IngredientResource(entity);
    }

    @Override
    public IngredientResource toModel(Ingredient entity) {
        return createModelWithId(entity.getId(), entity);
    }
}

 

Modification of the object TacoResource

public class TacoResource extends RepresentationModel<TacoResource> {
    private static final IngredientResourceAssembler
            ingredientAssembler = new IngredientResourceAssembler(IngredientController.class, IngredientResource.class);

    @Getter
    private String name;

    @Getter
    private Date createdAt;

    @Getter
    private CollectionModel<IngredientResource> ingredients;

    public TacoResource(Taco taco) {
        this.name = taco.getName();
        this.createdAt = taco.getCreatedAt();
        this.ingredients = ingredientAssembler.toCollectionModel(taco.getIngredients());

    }
}

 Listing 6.7

@RepositoryRestController
 public  class RecentTacosController {
     Private TacoRepository tacoRepo; 

    public RecentTacosController (TacoRepository tacoRepo) {
         the this .tacoRepo = tacoRepo; 
    } 

    / ** 
     * While @GetMapping mapped to "/ tacos / recent" path, but the class level @Repository RestController annotations ensure that the path to add 
     the base path * Spring Data REST as a prefix. According to our configuration, recentTacos () method will handle the request GET for "/ api / tacos / recent" is. 
     * * / 
    @GetMapping (path = "/ Tacos / Recent", Produces = "file application / JSON + HAL" )
     public ResponseEntity <CollectionModel <TacoResource >>  recentTacos () {
        PageRequest Page = PageRequest.of(
                0, 12, Sort.by("createdAt").descending());
        List<Taco> tacos = tacoRepo.findAll(page).getContent();

        CollectionModel<TacoResource> tacoResources =
                new TacoResourceAssembler(DesignTacoController.class, TacoResource.class).toCollectionModel(tacos);

        tacoResources.add(
                linkTo(methodOn(RecentTacosController.class).recentTacos())
                        .withRel("recents"));
        return new ResponseEntity<>(tacoResources, HttpStatus.OK);
    }

}

 

Another way

If you think the use of the resource assembler to write a little trouble, then you can also adopt this approach.

    @GetMapping("/employees")
    public ResponseEntity<CollectionModel<EntityModel<Taco>>> findAll() {
        PageRequest page = PageRequest.of(
                0, 12, Sort.by("createdAt").descending());
        List<EntityModel<Taco>> employees = StreamSupport.stream(tacoRepo.findAll(page).spliterator(), false)
                .map(employee -> new EntityModel<>(employee,
                        linkTo(methodOn(DesignTacoController.class).findOne(employee.getId())).withSelfRel(),
                        linkTo (methodOn (DesignTacoController.class).findAll()).withRel("employees")))
                .collect(Collectors.toList());

        return ResponseEntity.ok(
                new CollectionModel<>(employees,
                        linkTo(methodOn(DesignTacoController.class).findAll()).withSelfRel()));
    }
@GetMapping("/employees/{id}")
    public ResponseEntity<EntityModel<Taco>> findOne(@PathVariable long id) {

        return tacoRepo.findById(id)
                .map(employee -> new EntityModel<>(employee,
                        linkTo(methodOn(DesignTacoController.class).findOne(employee.getId())).withSelfRel(), //
                        linkTo(methodOn(DesignTacoController.class).findAll()).withRel("employees"))) //
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

Reference Source: https://github.com/spring-projects/spring-hateoas-examples/tree/master/simplified

 

END

Guess you like

Origin www.cnblogs.com/puzhiwei/p/12333471.html