2012-06-27 14 views
6

हाइबरनेट के साथ स्प्रिंग डेटा जेपीए का उपयोग करने वाले एक वेब एप्लिकेशन में, हम web pagination कार्यक्षमता का उपयोग इकाइयों की विभिन्न सूचियों में पेजिंग और सॉर्टिंग क्षमताओं को प्रदान करने के लिए करते हैं।स्प्रिंग डेटा जेपीए अमान्य पेज.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); 
} 

यह अनुमति देता है के लिए इकाई गुण गाया html में के रूप में विशेष प्रकार request parameters, जहां page.sort मूल्य वास्तव में जिस पर सॉर्ट करने के लिए इकाई में एक संपत्ति से मेल खाता है परिभाषित किया जाना है।

<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 

समस्या उन URL अमान्य page.sort गुणों का उपयोग करने के लिए संशोधित कर सकते हैं वह यह है कि है कि या तो संदर्भ न के बराबर स्तंभ/संपत्ति के नाम, या बुरा, जो अवैध जेपीए क्वेरी वर्णों का उपयोग करता है जिसके परिणामस्वरूप अमान्य वाक्यविन्यास होता है।

उदाहरण के लिए, यदि 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 

इसी तरह, यदि यूआरएल को अमान्य क्वेरी सिंटैक्स कैरेक्टर में संशोधित किया गया है, जैसे कि "":

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

निम्न त्रुटि या हो जाएगा:

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 स्पष्ट भंडार पद्धति पर परिभाषित किया गया है।)

स्प्रिंग डाटा जेपीए के विवरण दूर सार इन पैरामीटरों को सॉर्टिंग, पेजिंग और हैंडलिंग; हालांकि, यह इन परिदृश्यों को गहन रूप से संभालने में प्रतीत नहीं होता है (यानी जहां एक अमान्य सॉर्ट पैरामीटर निर्दिष्ट है)।

हम कुछ अतिरिक्त कस्टम तर्क में जोड़ सकते हैं ताकि यह सत्यापित किया जा सके कि प्रकार की संपत्ति वास्तव में इकाई पर मौजूद है; हालांकि, मैं सोच रहा हूं कि ऐसा करने के लिए एक क्लीनर अधिक केंद्रीकृत दृष्टिकोण है कि हम स्प्रिंग डेटा जेपीए अबास्ट्रक्शन के लाभ और सादगी को खोना नहीं चाहते हैं। हम कई अलग-अलग इकाइयों के साथ अपने ऐप में इस सॉर्टिंग क्षमता का उपयोग करते हैं, इसलिए आदर्श रूप से, हम अनुरोध किए गए प्रत्येक इकाई पृष्ठ के लिए सॉर्ट गुणों को स्पष्ट रूप से परिभाषित या जांचने के बजाय, एक सामान्य दृष्टिकोण चाहते हैं।

विशेष रूप से, हम वास्तव में PageableArgumentResolver का विस्तार है कि हमारे नियंत्रक (सादगी के लिए कोड उदाहरण में सचित्र नहीं) में प्रदान की जाती है एक एनोटेट तरह डिफ़ॉल्ट मान स्वीकार करने के लिए, तो हम सिर्फ इस डिफ़ॉल्ट सॉर्ट क्रम पर वापस आने के लिए करना चाहते हैं, या अपवाद फेंकने के बजाए, इकाई के लिए सिर्फ डिफ़ॉल्ट सॉर्टिंग ऑर्डर।

कुछ विचार और प्रयास .. मैं क्वेरी निर्माण को रोकने और सॉर्ट पैरामीटर प्राप्त करने के लिए QueryCreationListener का उपयोग कर सकता हूं; हालांकि, मैं वास्तव में उस बिंदु पर क्वेरी को संशोधित नहीं कर सकता। या, मैं पैरामीटर पैरामीटर को पकड़ने के लिए कस्टम PageableArgumentResolver (हम पहले से ही ऐसा कर रहे हैं) का विस्तार और उपयोग कर सकते हैं; हालांकि, मेरे पास उस बिंदु पर इकाई तक पहुंच नहीं है, न ही यह निर्धारित करने की क्षमता है कि इकाई के पास उस नाम से वास्तव में संपत्ति है या नहीं।हम समर्थित गुणों को स्पष्ट रूप से घोषित कर सकते हैं; हालांकि, फिर से, यह केंद्र के विचार को हरा देता है और संस्थाओं के विशिष्ट या घोषित ज्ञान की आवश्यकता के बिना स्वचालित रूप से इस परिदृश्य को संभाला जाता है।

क्या कोई अन्य प्रकार का इंटरसेप्टर या इसी तरह का निर्माण है जिसका उपयोग मैं पेजेबल सॉर्ट पैरामीटर को केंद्रीय रूप से मान्य करने के लिए उपयोग कर सकता हूं और क्वेरी को आमंत्रित करने से पहले आवश्यक हो सकता हूं? या क्या कोई प्रकार का कॉन्फ़िगरेशन या तरीका है कि स्प्रिंग स्वचालित रूप से इस परिदृश्य को संभाल सकता है जैसे कि यह अजीब तरह से अमान्य सॉर्ट पैरा को संभालता है?

उत्तर

3

मैं कोड पर एक नज़र डाल रहा था और मुझे लगता है कि कुछ और स्टैक ट्रेस उपयोगी होगा। लेकिन मैं जो देख सकता हूं, उससे मुझे लगता है कि अगर आप कुछ स्प्रिंग कोड को फिर से लिखने के मूड में हैं तो आप दो जगहों पर निपटना चाहेंगे।

यहां दो परिदृश्य हैं, पहले आप एक ऐसे क्षेत्र को पार कर रहे हैं जो वस्तु/तालिका में मौजूद नहीं है। आप वास्तव में क्या चाहते हैं कि उस खराब पैरामीटर को हर समय चुपचाप अनदेखा किया जाए, न केवल 1 PageableArgumentResolver] 1 में गुज़रने पर। मुझे लगता है कि यह एक प्रकार पर खराब पैरामीटर को अनदेखा करने के लिए AbstractQueryCreator (और इसलिए, JpaQueryCreator) पर एक विकल्प होना चाहिए।

दूसरा भाग जिसे हल किया जाना चाहिए शायद PageableArgumentResolver है। यदि आप खाली तार या कुछ ऐसा करते हैं जो %20 की तरह समझ में नहीं आता है तो उसे उस पैरामीटर को अनदेखा करना चाहिए और उसे PageRequest पर भेजना नहीं चाहिए।

हैप्पी हैकिंग और शुभकामनाएं। आपकी पोस्ट को पढ़ने से मुझे एहसास हुआ है कि मेरी साइट एक ही समस्या के लिए कमजोर है और मेरे पास वास्तव में कोई अच्छा समाधान नहीं है।

1

मुझे लगता है कि उन परिदृश्यों को गहन रूप से संभालने के लिए PageableArgumentResolver में सुधार करना है। यह String से Sort के रूप में PropertyPath उदाहरण बनाने का प्रयास कर सकता है और इस प्रकार यह सुनिश्चित कर लें कि यह मान्य है। मैं थोड़ा सा फाड़ा हूं कि डिफ़ॉल्ट रूप से अमान्य String को छोड़कर यह समझ में आता है कि परिणाम को क्रमबद्ध नहीं किया जाएगा। यह शायद सबसे निर्बाध अनुभव है, लेकिन यह भी पता लगाने के लिए कठिन प्रयासों का कारण बन सकता है कि परिणाम क्यों हल नहीं किया गया है।

हालांकि, यह। अगर आप स्प्रिंग डेटा कॉमन्स के खिलाफ इसके लिए एक जेआईआरए टिकट बढ़ा सकते हैं और बस इस टिकट को यहां लिंक कर सकते हैं तो अच्छा होगा। यदि आप व्यवहार्य कार्यान्वयन को दूर कर चुके हैं तो पुल अनुरोध खोलने के लिए स्वतंत्र महसूस करें। इसे पहले से ही टेबल पर लाने के लिए धन्यवाद!

संबंधित मुद्दे