मैं <jsp: getProperty> बिना <jsp: useBean> का उपयोग क्यों नहीं कर सकता?
कहते हैं कि सर्वलेट है जिसमें कोड है:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
foo.Person p = new foo.Person("Evan");
req.setAttribute("person", p);
RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
view.forward(req, resp);
}
, जो result.jsp
दिए गए नाम (इवान) को प्रिंट करने के लिए जाता है । यहाँ यह कैसे दिखेगा की एक तस्वीर है (स्रोत हेड फर्स्ट सर्वलेट्स और JSP):
मुझे पता है कि <jsp:useBean>
एक ही व्यक्ति वस्तु को कॉल करके लौटाता है getAttribute()
- क्योंकि वे एक ही अनुरोध के दायरे में हैं । दूसरी तरफ, वस्तुतः मूल्य "व्यक्ति" की विशेषता खोजने की कोशिश <jsp:getProperty>
करेगा findAttribute()
.. और अंततः इवान को प्रिंट करेगा ।
लेकिन अगर मैं उपयोग नहीं किया तो क्या होगा <jsp:useBean>
? क्या इसका मतलब है कि मैं गुंजाइश अनुरोध पर "व्यक्ति" विशेषता तक नहीं पहुंच सका ? मेरा मतलब है, यह अभी भी वहाँ होगा भी मैं का उपयोग नहीं किया है, तो <jsp:useBean>.
तो क्यों मैं एक ही होना चाहिए मूल्य दोनों के अंदर ( "व्यक्ति") आईडी में <jsp:useBean>
और नाम के अंदर <jsp:getProperty>
? सरल हटाने से <jsp:useBean>
मेरा कार्यक्रम टूट जाता है।
उस <jsp:getProperty>
कॉल को जानने के बाद findAttribute()
, क्या यह अधिक तर्कसंगत नहीं होगा यदि कोई एकल विशेषता (जैसे विशेषता-नाम ) थी, जिसका उपयोग स्कोप्स पृष्ठ> अनुरोध> सत्र> आवेदन में विशेषताओं को खोजने के लिए एक तर्क के रूप में किया जाएगा ? मुझे उन दो टैग्स को "टाई" क्यों करना चाहिए: <jsp:useBean>
और <jsp:getProperty>
?
जवाब
आप निम्नलिखित कोड से क्या समझते हैं?
public class Main {
public static void main(String[] args) {
System.out.println(person);
}
}
आपने पहले ही सही अनुमान लगा लिया होगा कि यह सफलतापूर्वक संकलित नहीं किया जाएगा ।
अब, निम्नलिखित कोड के बारे में क्या?
public class Main {
public static void main(String[] args) {
Person person = new Person();// Declaring person
System.out.println(person);
}
}
बेशक, यह सफलतापूर्वक 1 संकलित किया जाएगा क्योंकि अब संकलक समझता है कि क्या person
है।
इसी तरह, का उपयोग कर
<jsp:getProperty name="person" property="name">
के person
रूप में घोषित किए बिना
<!-- Declaring person -->
<jsp:useBean id="person" class="foo.Person" scope="request" />
सफलतापूर्वक संकलित नहीं किया जाएगा ।
1 मान लिया गया Person.class
है।
टी एल; डॉ: तुम बस याद रखना चाहिए कि आप उपयोग करने की आवश्यकता <jsp:getProperty>
के साथ <jsp:useBean>
विनिर्देश इसलिए कहते हैं क्योंकि। <jsp:useBean>
इससे पहले कि <jsp:getProperty>
यह उपयोग कर सकते हैं , JSP प्रोसेसर के लिए सेम को पेश करने की जरूरत है ।
अब स्पष्टीकरण:
मैं इसके
<jsp:getProperty>
बिना उपयोग क्यों नहीं कर सकता<jsp:useBean>
?
क्योंकि वे "कुछ हद तक" एक साथ काम करने के लिए डिज़ाइन किए गए थे। मुझे नहीं पता कि ऐसा क्यों तय किया गया था (केवल जेएसपी विनिर्देश के डिजाइनर इसका जवाब दे सकते हैं), लेकिन खुद कल्पना ने यह कहना है <jsp:getProperty>
:
नाम द्वारा नामित ऑब्जेक्ट को Jsp का उपयोग करते हुए JSP प्रोसेसर के लिए "पेश" किया गया होगा: इस नाम के लिए संबंधित VariableInfo प्रविष्टि के साथ उपयोग करें बीन कार्रवाई या एक कस्टम क्रिया। यदि ऑब्जेक्ट को इस तरीके से पेश नहीं किया गया था, तो कंटेनर कार्यान्वयन की सिफारिश की जाती है (लेकिन आवश्यक नहीं) अनुवाद त्रुटि को बढ़ाने के लिए, क्योंकि पृष्ठ कार्यान्वयन विनिर्देश के उल्लंघन में है।
मैं कहता हूं कि "कुछ हद तक" एक साथ काम करने के लिए डिज़ाइन किया गया है, क्योंकि कुछ मामलों में आप <jsp:getProperty>
बिना उपयोग कर सकते हैं <jsp:useBean>
, लेकिन आपको JSP.5.3 विनिर्देश नियम (सर्वरों के लिए अनुमति देता है) की अनदेखी करने के लिए JSP प्रोसेसर को कॉन्फ़िगर करना होगा।
यह बहुत स्पष्ट नहीं है, तो आइए देखें कि कुछ कोड के साथ क्या होता है।
मेरे पास निम्नलिखित JSP है:
-------------------------------------------------------------------
<jsp:useBean id="person" class="test.Person" scope="application" />
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<jsp:getProperty name="person" property="name" />
-------------------------------------------------------------------
मैंने उन सीमांकक का उपयोग किया ताकि मैं बाद में उन्हें जेएसपी जनरेट किए गए सर्वलेट में पा सकूँ, जहाँ उनका परिणाम इस कोड में है:
out.write("\t\t-------------------------------------------------------------------\r\n");
out.write("\t\t");
test.Person person = null;
synchronized (application) {
person = (test.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.APPLICATION_SCOPE);
if (person == null){
person = new test.Person();
_jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.APPLICATION_SCOPE);
}
}
out.write("\r\n");
out.write("\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
out.write("\t\t");
out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString((((test.Person)_jspx_page_context.findAttribute("person")).getName())));
out.write("\r\n");
out.write("\t\t-------------------------------------------------------------------\r\n");
यदि आप देखते हैं तो आप देख <jsp:getProperty>
सकते हैं कि यह एक कास्ट करता है test.Person
:
org.apache.jasper.runtime.JspRuntimeLibrary.toString((((test.Person)_jspx_page_context.findAttribute("person")).getName()))
लेकिन वह कहां से आया? अपने में <jsp:getProperty>
आप एक सेम नाम ( person
) और एक संपत्ति का नाम ( name
) निर्दिष्ट करते हैं , लेकिन कोई वर्ग नहीं। तो उन विशेषताओं का परिणाम केवल findAttribute("person")
और फिर अंदर होता है getName()
। कक्षा कहाँ से ली गई थी? और जवाब है, <jsp:useBean>
JSP प्रोसेसर में इसे पेश करने के लिए पिछला कॉल ।
तो आपको <jsp:useBean>
JSP प्रोसेसर में बीन को पेश करने के लिए कॉल करना होगा ताकि जब प्रोसेसर देखता है तो <jsp:getProperty>
यह जानता है कि यह किसके साथ काम कर रहा है। तो मूल रूप से, <jsp:useBean>
इसे परिभाषित करता है, फिर <jsp:getProperty>
इसका उपयोग करता है। यदि आप फोन नहीं करते हैं <jsp:useBean>
, तो <jsp:getProperty>
अनिर्धारित कुछ का उपयोग करने की कोशिश करेंगे, JSP प्रोसेसर शिकायत करेगा, और आपको एक अपवाद वापस मिलेगा:
jsp: बीन के लिए getProperty नाम 'व्यक्ति' के साथ। नाम पहले JSP.5.3 के अनुसार पेश नहीं किया गया था
लेकिन अगर आप चश्मा पढ़ते हैं, तो यह कहता है:
[...] कंटेनर कार्यान्वयन की सिफारिश की जाती है (लेकिन आवश्यक नहीं) अनुवाद त्रुटि को बढ़ाने के लिए [...]
यदि आप टॉमकैट का उपयोग करते हैं, उदाहरण के लिए, एक org.apache.jasper.compiler.Generator.STRICT_GET_PROPERTY
सिस्टम प्रॉपर्टी है जो <jsp:getProperty>
जेएसपी प्रोसेसर को मूल रूप से "शुरू" करने के लिए उपयोग की जाने वाली वस्तु को नियंत्रित करती है (मूल रूप से, JSP.5.3 नियम को लागू करने या नहीं करने के लिए)। उदाहरण के लिए देखें यह टॉमकैट प्रलेखन पृष्ठ ।
इसलिए, अगर मैं अपना टॉमकैट सर्वर सिस्टम चर के साथ शुरू करता हूं:
-Dorg.apache.jasper.compiler.Generator.STRICT_GET_PROPERTY=false
तो फिर मैं <jsp:getProperty>
बिना उपयोग कर सकते हैं <jsp:useBean>
, मुझे लगता है कि person
कुछ अन्य लोगों की तरह (जैसे कि एक सर्वलेट से request.setAttribute()
, session.setAttribute()
या application.setAttribute()
ऐसा किया <jsp:getProperty>
जा सकता है pageContext.findAttribute()
और नाम की एक बीन की person
तलाश में है और यह मिल जाए।
यदि आप उस सिस्टम प्रॉपर्टी का उपयोग करते हैं, तो <jsp:getProperty>
टैग द्वारा उत्पन्न आउटपुट बदल जाता है। यह अब निर्भर नहीं करता है <jsp:useBean>
और कलाकारों को हटा दिया जाता है:
out.write("\t\t+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\n");
out.write("\t\t");
out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString(org.apache.jasper.runtime.JspRuntimeLibrary.handleGetProperty(_jspx_page_context.findAttribute("person"), "name")));
out.write("\r\n");
out.write("\t\t-------------------------------------------------------------------\r\n");
अगर किसी को इस बात की दिलचस्पी है कि यह गड़बड़ी कैसे सामने आती है, तो (टॉमकैट सर्वर के लिए) देखने वाली कक्षाएं हैं: org.apache.jasper.compiler.Validator
और org.apache.jasper.compiler.Generator
।