programing

Spring Data의 Paged Resources Assembler를 올바르게 사용하는 방법은 무엇입니까?

sourcejob 2023. 10. 1. 19:25
반응형

Spring Data의 Paged Resources Assembler를 올바르게 사용하는 방법은 무엇입니까?

Spring 4.0.0을 사용하고 있습니다.릴리즈, Spring Data Commons 1.7.0.M1, Spring Hateoas 0.8.0풀어주다

제 자원은 간단한 POJO입니다.

public class UserResource extends ResourceSupport { ... }

내 리소스 어셈블러는 사용자 개체를 사용자 리소스 개체로 변환합니다.

@Component
public class UserResourceAssembler extends ResourceAssemblerSupport<User, UserResource> { 
    public UserResourceAssembler() {
        super(UserController.class, UserResource.class);
    }

    @Override
    public UserResource toResource(User entity) {
        // map User to UserResource
    }
}

Controller() Page<User>할 수 해요PagedResources<UserResource>PagedResourcesAssembler, 여기에 표시된 것처럼: https://stackoverflow.com/a/16794740/1321564

@RequestMapping(value="", method=RequestMethod.GET)
PagedResources<UserResource> get(@PageableDefault Pageable p, PagedResourcesAssembler assembler) {
    Page<User> u = service.get(p)
    return assembler.toResource(u);
}

은 라고 UserResourceAssembler 단순히용의 .User음 됩니다.UserResource.

단일 리소스를 반환하면 작동:

@Autowired
UserResourceAssembler assembler;

@RequestMapping(value="{id}", method=RequestMethod.GET)
UserResource getById(@PathVariable ObjectId id) throws NotFoundException {
    return assembler.toResource(service.getById(id));
}

PagedResourcesAssembler만,못 T toResource(T)Page<User>.PagedResources<User> , , User는 POJO이며 리소스는 없습니다.

그래서 질문은 다음과 같습니다.어떻게 작동합니까?

편집:

My WebMvc 구성 지원:

@Configuration
@ComponentScan
@EnableHypermediaSupport
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(pageableResolver());
        argumentResolvers.add(sortResolver());
        argumentResolvers.add(pagedResourcesAssemblerArgumentResolver());
    }

    @Bean
    public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
        return new HateoasPageableHandlerMethodArgumentResolver(sortResolver());
    }

    @Bean
    public HateoasSortHandlerMethodArgumentResolver sortResolver() {
        return new HateoasSortHandlerMethodArgumentResolver();
    }

    @Bean
    public PagedResourcesAssembler<?> pagedResourcesAssembler() {
        return new PagedResourcesAssembler<Object>(pageableResolver(), null);
    }

    @Bean
    public PagedResourcesAssemblerArgumentResolver pagedResourcesAssemblerArgumentResolver() {
        return new PagedResourcesAssemblerArgumentResolver(pageableResolver(), null);
    }

    /* ... */
}

해결책:

@Autowired
UserResourceAssembler assembler;

@RequestMapping(value="", method=RequestMethod.GET)
PagedResources<UserResource> get(@PageableDefault Pageable p, PagedResourcesAssembler pagedAssembler) {
    Page<User> u = service.get(p)
    return pagedAssembler.toResource(u, assembler);
}

적절한 사용법에 대해서는 이미 알아보신 것 같은데, 다른 분들도 찾을 수 있도록 여기에 자세히 좀 더 자세히 설명해주세요.저는 그와 비슷한 것에 대해 자세히 설명했습니다.PagedResourceAssembler이 대답에서

표현 모형

Spring HATEOAS는 링크가 장착된 표현을 쉽게 만들 수 있는 표현 모델을 위한 다양한 기본 클래스를 제공합니다.별도로 제공되는 클래스는 세 가지 유형입니다.

  • Resource- 품목 자원단일 항목을 캡처하여 링크로 풍부하게 만드는 일부 DTO 또는 엔티티를 효과적으로 둘러쌀 수 있습니다.
  • Resources 것의수원,원의 입니다.Resource들면
  • PagedResources장의 Resources총 페이지 수 등과 같은 추가 페이지 정보를 캡처합니다.

는 합니다.ResourceSupport은 입니다의 입니다.Link들면

리소스 어셈블러

A ResourceAssembler이제 도메인 개체 또는 DTO를 이러한 리소스 인스턴스로 변환하는 데 필요한 완화 구성 요소입니다.여기서 중요한 부분은 하나의 소스 객체를 하나의 타겟 객체로 바꾼다는 것입니다.

.PagedResourcesAssembler는 Data Spring Data다를 .Page다합니다.PagedResources으로써,어를 합니다.Page것을 낼 수 있습니다.PageMetadata만 아니라prev그리고.next페이지를 탐색하는 링크.이 일 수 이 다를 합니다. 평원을 사용합니다.SimplePagedResourceAssembler(내부 부류의)PRA) 페이지의 개별 요소를 중첩으로 변환합니다.Resource예를 들면

이를 사용자 정의할 수 있도록 하기 위해,PRA추가로 있습니다.toResource(…)대리인을 두는 방법ResourceAssembler개별 항목을 처리할 수 있습니다.결국 이런 일이 벌어지게 됩니다.

 class UserResource extends ResourceSupport { … }

 class UserResourceAssembler extends ResourceAssemblerSupport<User, UserResource> { … }

그리고 클라이언트 코드는 이렇게 보입니다.

 PagedResourcesAssembler<User> parAssembler = … // obtain via DI
 UserResourceAssembler userResourceAssembler = … // obtain via DI

 Page<User> users = userRepository.findAll(new PageRequest(0, 10));

 // Tell PAR to use the user assembler for individual items.
 PagedResources<UserResource> pagedUserResource = parAssembler.toResource(
   users, userResourceAssembler);

아웃룩

다가오는 Spring Data Commons 1.7 RC1 (그리고 Spring HATEOAS 0.9) 현재prev그리고.next링크는 RFC6540 준수 URI 템플릿으로 생성되어 에 구성된 페이지화 요청 매개 변수를 노출합니다.HandlerMethodArgumentResolvers위해서Pageable그리고.Sort.

위에서 보여준 구성은 다음과 같이 구성 클래스에 주석을 달면 단순화할 수 있습니다.@EnableSpringDataWebSupport모든 명백한 콩 선언을 없앨 수 있을 겁니다

Resources 목록을 페이지로 변환하고 싶었습니다.그러나 Paged Resources Assembler를 제공할 때 내부 링크를 다 먹어 치웠습니다.

그러면 목록이 호출됩니다.

 public class JobExecutionInfoResource extends ResourceSupport {
    private final JobExecutionInfo jobExecution;

    public JobExecutionInfoResource(final JobExecutionInfo jobExecution) {
        this.jobExecution = jobExecution;        
        add(ControllerLinkBuilder.linkTo(methodOn(JobsMonitorController.class).get(jobExecution.getId())).withSelfRel()); // add your own links.          
    }

    public JobExecutionInfo getJobExecution() {
        return jobExecution;
    }
}

Paged resource Providing ResourceAssembler가 Paged resource에 사용을 지시합니다. 그러면 이미 전달된 리소스 목록이기 때문에 아무것도 반환되지 않습니다.

    private final PagedResourcesAssembler<JobExecutionInfoResource> jobExecutionInfoResourcePagedResourcesAssembler;
    public static final PageRequest DEFAULT_PAGE_REQUEST = new PageRequest(0, 20);
    public static final ResourceAssembler<JobExecutionInfoResource, JobExecutionInfoResource> SIMPLE_ASSEMBLER = entity -> entity;

@GetMapping("/{clientCode}/{propertyCode}/summary")
    public PagedResources<JobExecutionInfoResource> getJobsSummary(@PathVariable String clientCode, @PathVariable String propertyCode,
                                                                   @RequestParam(required = false) String exitStatus,
                                                                   @RequestParam(required = false) String jobName,
                                                                   Pageable pageRequest) {
        List<JobExecutionInfoResource> listOfResources = // your code to generate the list of resource;
        int totalCount = 10// some code to get total count;
        Link selfLink = linkTo(methodOn(JobsMonitorController.class).getJobsSummary(clientCode, propertyCode, exitStatus, jobName, DEFAULT_PAGE_REQUEST)).withSelfRel();
        Page<JobExecutionInfoResource> page = new PageImpl<>(jobExecutions, pageRequest, totalCount);
        return jobExecutionInfoResourcePagedResourcesAssembler.toResource(page, SIMPLE_ASSEMBLER, selfLink);
    }

대체 방법

다른 방법은 Range HTTP 헤더를 사용하는 것입니다(RFC 7233에서 자세히 읽음).HTTP 헤더는 다음과 같은 방법으로 정의할 수 있습니다.

Range: resources=20-41

즉, 20에서 41 사이의 리소스를 확보하려는 것입니다.이렇게 하면 API의 소비자가 정확하게 정의된 리소스를 받을 수 있습니다.

그것은 단지 대안적인 방법일 뿐입니다.범위는 종종 다른 단위(바이트 등)와 함께 사용됩니다.

권장 방법

pagination 관련 작업을 하고 정말로 적용 가능한 API(hypermedia / HATEOAS 포함)가 있다면, 당신의 URL에 Page and PageSize를 추가하는 것을 추천합니다. 예:

http://host.loc/articles?Page=1&PageSize=20

그런 다음 BaseApiController에서 이 데이터를 읽고 모든 요청에 QueryFilter 개체를 만들 수 있습니다.

{
    var requestHelper = new RequestHelper(Request);

    int page = requestHelper.GetValueFromQueryString<int>("page");
    int pageSize = requestHelper.GetValueFromQueryString<int>("pagesize");

    var filter = new QueryFilter
    {
        Page = page != 0 ? page : DefaultPageNumber,
        PageSize = pageSize != 0 ? pageSize : DefaultPageSize
    };

    return filter;
}

당신의 api는 아이템의 개수에 대한 정보와 함께 일부 특별한 컬렉션을 반환해야 합니다.

public class ApiCollection<T>
{
    public ApiCollection()
    {
        Data = new List<T>();
    }

    public ApiCollection(int? totalItems, int? totalPages)
    {
        Data = new List<T>();
        TotalItems = totalItems;
        TotalPages = totalPages;
    }

    public IEnumerable<T> Data { get; set; }

    public int? TotalItems { get; set; }
    public int? TotalPages { get; set; }
}

모델 클래스는 페이지화 지원을 통해 일부 클래스를 상속할 수 있습니다.

public abstract class ApiEntity
{
    public List<ApiLink> Links { get; set; }
}

public class ApiLink
{
    public ApiLink(string rel, string href)
    {
        Rel = rel;
        Href = href;
    }

    public string Href { get; set; }

    public string Rel { get; set; }
}

언급URL : https://stackoverflow.com/questions/21346387/how-to-correctly-use-pagedresourcesassembler-from-spring-data

반응형