2012-06-27 13 views
6

Hazırda Bekletme ile Spring Data JPA kullanan bir web uygulamasında, çeşitli varlık listelerinde sayfalama ve sıralama yetenekleri sağlamak için web pagination işlevini kullanırız. varlık özellikleri render html page.sort değeri aslında sıralamak için üzerine varlıktaki bir özellik eşleştiği sürece özel tür request parameters, tanımlanması içinYay Verisi JPA Geçersiz sayfa.sort Parametreler

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

Bu izin verir.

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

Bu gibi bir çıkan URL'yi üretir:

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

kullanıcı hatalı page.sort özelliklerini kullanmak için URL'yi değiştirebilir olmasıdır sorun, bir referans ya da olmayan sütun/özellik adları veya daha da kötüsü, geçersiz sözdizimi ile sonuçlanan geçersiz JPA sorgu karakterleri kullanın. URL "noSuchProperty" konulu sıralamak için değiştirilirse

Örneğin,:

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

Ama bu özellik yok, şu istisna atılır:

Keza
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, "" "gibi geçersiz bir sorgu sözdizimi karakteri için değiştirilmişse,

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

Aşağıdaki hata ya da ortaya çıkar:

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) 

(sonuçlanır istisnalar üçüncü tat Ayrıca bir org.hibernate.QueryException @Query açıkça Deposu yöntemi tanımlanır kullanılabilir.)

Yay Verileri JPA ayrıntılarını uzak özetler bu parametrelerin sıralanması, sıralanması ve işlenmesi; ancak, bu senaryoları incelikle ele almıyor gibi görünmektedir (yani geçersiz bir sıralama parametresi belirtildiğinde).

Sıralama özelliğinin varlık üzerinde var olduğunu doğrulamak için bazı ek özel mantıklar ekleyebiliriz; bununla birlikte, Spring Data JPA soyutlamalarının faydalarını ve basitliğini kaybetmeyecek şekilde daha temiz ve merkezi bir yaklaşım var mı diye merak ediyorum. Bu sıralama özelliğini, uygulamalarımızda birçok farklı varlıkla kullanıyoruz. Bu nedenle, ideal olarak, istenen her varlık sayfası için sıralama özelliklerini açıkça tanımlamak veya kontrol etmek yerine genel bir yaklaşımdan daha fazlasını istiyoruz.

Özellikle, bizim denetleyicide sağlanan açıklamalı bir sıralama varsayılan değerini kabul etmek için PageableArgumentResolver'u gerçekten genişletiyoruz (basitlik için kod örneklerinde gösterilmemiştir), bu nedenle yalnızca bu varsayılan sıralama düzenine geri dönmek isteriz, veya Bir istisna atmak yerine, yalnızca varlığın varsayılan sıralama sırasıdır.

Bazı fikirler ve denemeler .. QueryCreationListener sorgu oluşturmayı engellemek ve sort parametresini almak için kullanabilir; Ancak, sorguyu bu noktada değiştiremiyorum. Ya da sıralama parametrelerini almak için özel bir PageableArgumentResolver (bunu zaten yapıyoruz) kullanabilir ve kullanabilirim; Bununla birlikte, bu noktadaki varlığa ve söz konusu işletmenin gerçekte bir mülkiyete sahip olup olmadığına karar veremiyorum.Desteklenen özellikleri açıkça bildirebiliriz; bununla birlikte, yine, bu durum, bu senaryoyu, varlıkların spesifik veya beyan edilmiş bilgisine ihtiyaç duymadan merkezi ve otomatik olarak ele alma fikrini yitirmektedir.

Ben gerekirse merkezi olarak sorgu çağırmadan önce sayfalanabilir sıralama parametrelerini doğrulamak ve değiştirmek için kullanabileceği dinleyici veya benzeri yapının başka türde var mı? Ya da Spring'in bu senaryoyu otomatik olarak geçersiz sıralama paramlarını daha hassas bir şekilde ele alacağı şekilde yapabileceği herhangi bir yapılandırma veya yol var mı?

cevap

3

koda bir göz alıyordu ve ben yığın izlemesi biraz daha yararlı olacağını düşünüyorum. Ama görebildiğim kadarıyla, bazı Bahar kodlarını yeniden yazmak için havasındaysanız, ele almak isteyebileceğiniz iki yer olduğunu düşünüyorum. Eğer nesne/tabloda bulunmayan bir sıralama alanını geçiyoruz ilki iki senaryo, burada var

bulunmaktadır. Gerçekten istediğiniz şey, sadece 1 PageableArgumentResolver] 1'dan geçerken değil, her zaman sessiz bir şekilde yok sayılacak bu kötü parametredir. Ben AbstractQueryCreator (ve böylece, JpaQueryCreator) bir tür üzerinde hatalı parametreleri yoksayılacak bir seçenek olmalıdır düşünüyorum. ele alınması gerektiğini

ikinci bölümü muhtemelen PageableArgumentResolver olduğunu. Boş dizeleri veya %20 gibi mantıklı olmayan bir şey iletirseniz, bu parametreyi yok saymalı ve PageRequest'a göndermemelidir.

Mutlu korsanlığı ve iyi şanslar. Gönderinizi okumak, sitemin aynı soruna karşı savunmasız olduğunu ve gerçekten iyi bir çözümün olmadığını fark ettim.

1

Ben PageableArgumentResolver incelikle bu senaryoları ele iyileştirilmesi düşünüyorum. Sort olarak teslim edilen String adresinden bir PropertyPath örneği oluşturmaya çalışabilir ve bu nedenle geçerli olduğundan emin olun. Geçersiz String değerini varsayılan olarak düşürmenin mantıklı olup olmadığına bakılmaksızın biraz kesintiye uğruyorum. Bu muhtemelen en kusursuz deneyimdir, ancak sonucun neden sıralanmadığını bulmak için sıkıcı girişimlere de yol açabilir. Bununla birlikte, bu, bu. Spring Data Commons'a karşı bir JIRA bileti alabilecekseniz ve sadece bu bileti buraya bağlarsanız harika olur. Uygulanabilir bir uygulama ortaya çıkarmış olmanız durumunda çekme talebinde bulunmaya çekinmeyin. Bunu masaya getirdiğin için teşekkürler!

İlgili konular