복붙노트

[SPRING] 스프링 데이터에서 PagedResourcesAssembler를 올바르게 사용하는 방법은 무엇입니까?

SPRING

스프링 데이터에서 PagedResourcesAssembler를 올바르게 사용하는 방법은 무엇입니까?

나는 Spring 4.0.0을 사용하고있다. RELEASE, Spring Data Commons 1.7.0.M1, Spring Hateoas 0.8.0.RELEASE

내 리소스는 간단한 POJO입니다.

public class UserResource extends ResourceSupport { ... }

내 리소스 어셈블러는 User 객체를 UserResource 객체로 변환합니다.

@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
    }
}

내 UserController 내부에서 내 서비스에서 Page 를 검색 한 다음 여기에 표시된 것과 같이 PagedResourcesAssembler를 사용하여 PagedResources 로 변환하려고합니다. 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를 호출하지 않고 단순히 내 사용자 정의 UserResource 대신에 User의 내용 만 반환합니다.

단일 리소스 반환은 작동합니다.

@Autowired
UserResourceAssembler assembler;

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

PagedResourcesAssembler는 몇 가지 일반적인 인수를 원하지만 사용자가 POJO 및 Resource가 아니기 때문에 My Page 를 PagedResources 로 변환하지 않으므로 T toResource (T)를 사용할 수 없습니다.

그래서 질문은 : 어떻게 작동합니까?

나의 WebMvcConfigurationSupport :

@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);
}

해결법

  1. ==============================

    1.당신은 이미 올바른 사용법을 발견 한 것 같지만 다른 사람들이 찾을 수있는 약간의 세부 사항으로 들어가고 싶습니다. 이 답변에서 PagedResourceAssembler에 대한 비슷한 세부 사항을 살펴 보았습니다.

    당신은 이미 올바른 사용법을 발견 한 것 같지만 다른 사람들이 찾을 수있는 약간의 세부 사항으로 들어가고 싶습니다. 이 답변에서 PagedResourceAssembler에 대한 비슷한 세부 사항을 살펴 보았습니다.

    Spring HATEOAS는 링크가 포함 된 표현을 쉽게 만들 수있는 표현 모델을위한 다양한 기본 클래스를 제공합니다. 다음과 같은 세 가지 유형의 클래스가 제공됩니다.

    이 모든 클래스는 ResourceSupport에서 파생됩니다. ResourceSupport는 Link 인스턴스의 기본 컨테이너입니다.

    ResourceAssembler는 이제 도메인 오브젝트 또는 DTO를 이러한 자원 인스턴스로 변환하는 완화 요소입니다. 여기에서 중요한 부분은 하나의 소스 객체를 하나의 대상 객체로 변환한다는 것입니다.

    따라서 PagedResourcesAssembler는 Spring Data Page 인스턴스를 가져 와서 Page를 평가하고 필요한 PageMetadata를 생성하고 페이지를 탐색하기위한 이전 및 다음 링크를 생성하여 PagedResources 인스턴스로 변환합니다. 기본적으로 여기서는 흥미로운 부분 일 것입니다. 즉, 페이지의 개별 요소를 중첩 된 Resource 인스턴스로 변환하기 위해 일반 SimplePagedResourceAssembler (PRA의 내부 클래스)를 사용합니다.

    이를 사용자 정의 할 수 있도록 PRA에는 개별 항목을 처리하기 위해 대리인 ResourceAssembler를 사용하는 toResource (...) 메소드가 추가로 있습니다. 그래서 당신은 이런 식으로 끝납니다 :

     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 transitively) 이전과 다음 링크는 RFC6540을 준수하는 URI 템플릿으로 생성되어 페이지 가능 및 정렬을 위해 HandlerMethodArgumentResolvers에 구성된 페이지 매김 요청 매개 변수를 노출합니다.

    위에 표시된 구성은 @EnableSpringDataWebSupport로 구성 클래스에 주석을 달아 단순화 할 수 있습니다. 그러면 모든 명시 적 bean 선언을 제거 할 수 있습니다.

  2. ==============================

    2.대체 방법

    대체 방법

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

    Range: resources=20-41
    

    즉, 리소스를 20에서 41 (포함)까지 얻으려는 것입니다. 이 방법을 사용하면 API 사용자가 정확하게 정의 된 리소스를 수신 할 수 있습니다.

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

    권장 방법

    페이지 매김 작업을하고 실제로 적용 할 수있는 API (하이퍼 미디어 / HATEOAS 포함)를 원할 경우 URL에 Page 및 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; }
    }
    
  3. from https://stackoverflow.com/questions/21346387/how-to-correctly-use-pagedresourcesassembler-from-spring-data by cc-by-sa and MIT license