2012-06-27 5 views
6

Hibernate에서 스프링 데이터 JPA를 사용하는 웹 응용 프로그램에서 web pagination 기능을 사용하여 다양한 엔티티 목록에서 페이징 및 정렬 기능을 제공합니다. 개체 속성이 렌더링 된 HTML에 page.sort 값이 실제로 정렬하는 기준에 따라 엔티티의 속성과 일치 같은 특별한 종류의 request parameters을 정의하는스프링 데이터 JPA 잘못된 page.sort 매개 변수

@Controller 
public class MyEntityController { 
    @RequestMapping(method = RequestMethod.GET) 
    public ModelAndView list(Pageable pageable) { ... } 
} 

@Configuration 
public class MyWebMvcConfig extends WebMvcConfigurationSupport { 
    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 
     super.addArgumentResolvers(argumentResolvers); 
     argumentResolvers.add(new PageableArgumentResolver()); 
    } 
} 

public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, String> { 
    Page<MyEntity> findByPropertyX(String propertyX, Pageable pagable); 
} 

이것은 수 있습니다.

<table> 
    <thead> 
     <tr> 
      <th><a href="?page.sort=propertyX&amp;page.sort.dir=asc">Property X</a></th> 
      <th><a href="?page.sort=propertyY&amp;page.sort.dir=asc">Property Y</a></th> 
     </tr> 
    </thead> 
    <tbody>...</tbody> 
</table> 

이 같은 결과 URL을 생성합니다

http://host/context-root/entities/?page.sort=propertyX&page.sort.dir=asc 

사용자가 유효하지 않은 page.sort 속성을 사용하는 URL을 수정할 수 있다는 것입니다 문제는 그 기준 중 하나가 존재하지 않는 열/속성 이름, 또는 더 나쁜, 구문이 유효하지 않은 잘못된 JPA 쿼리 문자를 사용합니다. URL이 "noSuchProperty"에 정렬 변경되었을 경우

는 예를 들어, :

http://host/context-root/entities/?page.sort=noSuchProperty&page.sort.dir=asc 

을하지만이 속성이 존재하지 않는, 다음과 같은 예외가 발생합니다 :

마찬가지로
java.lang.IllegalArgumentException: No property noSuchProperty found for type class com.my.company.MyEntity 
    at org.springframework.data.repository.query.parser.Property.<init>(Property.java:76) 
    . . . 
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:86) 
    . . . 
    at $Proxy68.findByPropertyX(Unknown Source) 
    at com.my.company.MyEntityRepository.findByPropertyX(MyEntityRepository.java:17 

, URL이 같은 "" "로, 잘못된 쿼리 구문 문자로 변경되는 경우 :

http://host/context-root/entities/?page.sort=%22&page.sort.dir=asc 

다음 ERR 또는 발생할 것이다

java.lang.StackOverflowError 
    java.util.regex.Pattern$GroupTail.match(Pattern.java:4227) 
    . . . 
    org.springframework.data.repository.query.parser.Property.create(Property.java:326) 
    org.springframework.data.repository.query.parser.Property.create(Property.java:326) 
    org.springframework.data.repository.query.parser.Property.create(Property.java:326) 
    org.springframework.data.repository.query.parser.Property.create(Property.java:326) 

(결과 예외 제 맛도이다 org.hibernate.QueryException @Query 명시 적 저장소 방법에서 정의 될 때).

스프링 데이터 JPA는 세부 정보를 얻어 추상화 이러한 매개 변수의 정렬, 페이징 및 처리; 그러나 이러한 시나리오 (즉, 잘못된 정렬 매개 변수가 지정된 위치)를 정상적으로 처리하지 못하는 것 같습니다.

정렬 속성이 엔티티에 실제로 존재하는지 확인하는 몇 가지 추가 사용자 지정 논리를 추가 할 수 있습니다. 그러나 Spring Data JPA 추상화의 이점과 단순성을 잃지 않도록 더 깨끗하고 집중화 된 접근 방법이 있는지 궁금합니다. 우리는 많은 엔티티들과 함께이 정렬 기능을 사용하기 때문에 요청 된 모든 엔티티 페이지에 대한 정렬 속성을 명시 적으로 정의하거나 확인하지 않아도되는 이상적인 방식을 원합니다.

구체적으로 컨트롤러 (단순화를 위해 코드 예제에 표시되지 않음)에서 제공되는 주석이 지정된 정렬 기본값을 허용하도록 확장하므로이 기본 정렬 순서로 대체하거나 예외를 throw하는 것이 아니라 엔티티의 기본 정렬 순서.

몇 가지 아이디어와 시도. QueryCreationListener을 사용하여 쿼리 생성을 가로 채서 정렬 매개 변수를 얻을 수 있습니다. 그러나, 나는 그 시점에서 실제로 쿼리를 수정할 수 없습니다. 또는 정렬 매개 변수를 얻기 위해 사용자 정의 PageableArgumentResolver (이미이 작업을 수행 중입니다)을 확장하여 사용할 수 있습니다. 그러나 나는 그 시점에서 엔티티에 액세스 할 수 없으며 엔티티가 실제로 그 이름으로 등록 정보를 가지고 있는지 여부를 결정할 수 없습니다.지원되는 속성을 명시 적으로 선언 할 수 있습니다. 그러나 이것은 엔티티에 대한 특정 또는 선언 된 지식을 필요로하지 않고이 시나리오를 중앙에서 자동으로 처리한다는 아이디어를 무효화합니다.

페이지 유형 정렬 매개 변수의 유효성을 중앙에서 확인하고 필요하면 쿼리를 호출하기 전에 수정할 수있는 다른 유형의 인터셉터 또는 유사한 구문이 있습니까? 아니면 Spring이 자동으로이 시나리오를 처리하여 잘못된 정렬 매개 변수를보다 정상적으로 처리하도록하는 모든 유형의 구성이나 방식이 있습니까?

답변

3

코드를 살펴 보았고 스택 추적이 도움이 될 것이라고 생각합니다. 그러나 내가 볼 수 있듯이, Spring 코드를 다시 작성하려는 분위기에 있다면 두 가지를 생각해 볼 수 있습니다.

두 가지 시나리오가 있습니다. 첫 번째 시나리오에서는 개체/테이블에 존재하지 않는 정렬 필드를 전달합니다. 정말로 원하는 것은 그 나쁜 매개 변수가 항상 1 PageableArgumentResolver1을 전달할 때뿐만 아니라 항상 무시되도록하는 것입니다. 나는 AbstractQueryCreator (따라서, JpaQueryCreator)의 옵션이 나쁜 매개 변수를 무시해야한다고 생각하고 있습니다.

두 번째 부분은 아마도 PageableArgumentResolver입니다. 빈 문자열이나 %20과 같은 의미가없는 문자열을 전달하면 해당 매개 변수를 무시하고 PageRequest으로 보내지 않아야합니다.

행복한 해킹과 행운. 귀하의 게시물을 읽으면 내 사이트가 동일한 문제에 취약하다는 사실을 깨닫게되었으며 실제로 좋은 해결책이 없습니다.

1

PageableArgumentResolver을 개선하여 이러한 시나리오를 적절하게 처리한다고 생각합니다. String에서 PropertyPath 인스턴스를 생성하여 Sort으로 전달할 수 있으므로 올바른 인스턴스인지 확인해야합니다. 나는 기본적으로 유효하지 않은 값을 단순히 떨어 뜨리는 것이 합리적인지 여부에 대해 약간 찢겨져있다. 결과는 전혀 정렬되지 않은 채로 반환 될 것이다. 이것은 아마도 가장 완벽한 경험이지만 결과가 정렬되지 않은 이유를 찾는 지루한 시도로 이어질 수도 있습니다.

그러나, 그것. Spring Data Commons와의 JIRA 티켓을 올리고 여기에이 티켓을 링크하면 멋질 것입니다. 실행 가능한 구현을 완성한 경우에 대비하여 언제든지 끌어 오기 요청을 열어보십시오. 이것을 이미 테이블에 가져 주셔서 감사합니다!

관련 문제