2010-02-02 18 views
32

मुझे बताया गया है कि मेरे जेएसपी पृष्ठों में स्क्रिप्टलेट्स (<% = ...%>) का उपयोग इतना अच्छा विचार नहीं है।मेरे जेएसपी पेज में स्क्रिप्टलेट का उपयोग करने से कैसे बचें?

क्या कोई और जावा/जेएसपी अनुभव वाला कोई व्यक्ति कृपया मुझे कुछ पॉइंटर्स दे सकता है कि इस कोड को कैसे बदला जाए ताकि यह और अधिक 'सर्वोत्तम अभ्यास' हो, जो भी हो सकता है?

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

<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %> 

<html> 
<head> 
    <title>My Events - <decorator:title /></title> 
    <link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 

<div class="tabs"> 
    <a 
    <%= request.getRequestURI().contains("/events/") ? "class='selected'" : "" %> 
    href='<%= request.getContextPath() %>/events/Listing.action'>Events</a> 
    <a 
    <%= request.getRequestURI().contains("/people/") ? "class='selected'" : "" %> 
    href='<%= request.getContextPath() %>/people/Listing.action'>People</a> 
</div> 

<div class="submenu"> 
    <% if(request.getRequestURI().contains("/events/")) { %> 
    <a href="Listing.action">List of Events</a> 
    |<a href="New.action">New Event</a> 
    <% } %> 
    <% if(request.getRequestURI().contains("/people/")) { %> 
    <a href="Listing.action">List of People</a> 
    |<a href="New.action">New Person</a> 
    <% } %> 
    &nbsp; 
</div> 

<div class="body"> 
    <decorator:body /> 
</div> 

</body> 
</html> 

धन्यवाद सभी

+0

एक तरफ के रूप में, '<% = request.getContextPath()%>' उन स्क्रिप्टलेट्स का स्वीकार्य उपयोग है जो इतने पर फंसे नहीं हैं? – Chris

+0

आपको टेम्पलेटिंग के लिए फेसलेट का उपयोग शुरू करना चाहिए। आपको सही ढंग से कोड करने के लिए मजबूर करता है। –

+0

क्या आप साइटमैश के बजाय चेहरे का उपयोग कर रहे हैं? – Chris

उत्तर

40

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

यहाँ दूसरों के बीच की मदद से एक 1 पर 1 पुनर्लेखन JSTL (बस छोड़ /WEB-INF/lib में jstl-1.2.jar) core और functions taglib है:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> 

<html> 
<head> 
    <title>My Events - <decorator:title /></title> 
    <link href="${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 

<div class="tabs"> 
    <a 
    ${fn:contains(pageContext.request.requestURI, '/events/') ? 'class="selected"' : ''} 
    href="${pageContext.request.contextPath}/events/Listing.action">Events</a> 
    <a 
    ${fn:contains(pageContext.request.requestURI, '/people/') ? 'class="selected"' : ''} 
    href="${pageContext.request.contextPath}/people/Listing.action">People</a> 
</div> 

<div class="submenu"> 
    <c:if test="${fn:contains(pageContext.request.requestURI, '/events/')}"> 
    <a href="Listing.action">List of Events</a> 
    |<a href="New.action">New Event</a> 
    </c:if> 
    <c:if test="${fn:contains(pageContext.request.requestURI, '/people/')}"> 
    <a href="Listing.action">List of People</a> 
    |<a href="New.action">New Person</a> 
    </c:if> 
    &nbsp; 
</div> 

यहाँ एक अधिक अनुकूलित पुनर्लेखन है, ध्यान दें कि मैं c:set करने के लिए "कैश" का इस्तेमाल किया पुन: उपयोग के लिए अभिव्यक्ति के परिणाम और मैं प्रत्येक लिंक में संदर्भ पथ डालने से बचने के लिए एचटीएमएल <base> टैग का उपयोग करता हूं (केवल सभी संबंधित यूआरएल को इसके संबंधित वेबपेज में - प्रमुख स्लैश के बिना बनाएं):

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> 

<c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, '/events/')}" /> 
<c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, '/people/')}" /> 

<html> 
<head> 
    <title>My Events - <decorator:title /></title> 
    <base href="${pageContext.request.contextPath}"> 
    <link href="assets/styles.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 

<div class="tabs"> 
    <a ${isEvents ? 'class="selected"' : ''} href="events/Listing.action">Events</a> 
    <a ${isPeople ? 'class="selected"' : ''} href="people/Listing.action">People</a> 
</div> 

<div class="submenu"> 
    <c:if test="${isEvents}"> 
    <a href="Listing.action">List of Events</a>|<a href="New.action">New Event</a> 
    </c:if> 
    <c:if test="${isPeople}"> 
    <a href="Listing.action">List of People</a>|<a href="New.action">New Person</a> 
    </c:if> 
    &nbsp; 
</div> 

यह वास्तव में अधिक अनुकूलित किया जा सकता है अगर आप आवेदन दायरे में एक Map में events और people और लिंक ग्रंथों की तरह उन सभी "हार्डकोडेड" मूल्यों को इकट्ठा करने और प्रत्येक JSTL <c:forEach> के तहत का उपयोग टैब प्रदर्शित करने के लिए।

अपने वास्तविक प्रश्न के रूप में, आप कर सकते हैं अक्षम scriptlets (और यह उपयोग करने के बारे क्रम त्रुटियों मिल) वेब ऐप्लिकेशन की web.xml में निम्नलिखित प्रविष्टि जोड़कर। यह विदेशी लिपियों को खोजने में मदद कर सकता है।

<jsp-config> 
    <jsp-property-group> 
     <url-pattern>*.jsp</url-pattern> 
     <scripting-invalid>true</scripting-invalid> 
    </jsp-property-group> 
</jsp-config> 

ईएल के बारे में अधिक जानने के लिए, Java EE tutorial part II chapter 5 देखें। लागू ईएल ऑब्जेक्ट्स, जैसे ${pageContext} को here वर्णित किया गया है। जेएसटीएल के बारे में और जानने के लिए, Java EE tutorial part II chapter 7 देखें। ध्यान दें कि जेएसटीएल और ईएल दो अलग-अलग चीजें हैं। जेएसटीएल मानक टैगलिब है और ईएल बस बैकएंड डेटा को प्रोग्रामेटिक रूप से एक्सेस करने में सक्षम बनाता है। यद्यपि यह आमतौर पर जेएसटीएल जैसे टैगलिब्स में प्रयोग किया जाता है, लेकिन इसका उपयोग टेम्पलेट टेक्स्ट में स्टैंडअलोन भी किया जा सकता है।

+5

यदि आप "पहले" और "बाद" टेम्पलेट की तुलना करते हैं, तो आप देखेंगे कि वे काफी समान हैं। मैं नहीं देखता कि उत्तरार्द्ध पूर्व की तुलना में स्वचालित रूप से बेहतर कैसे होता है (एक छोटा सा क्लीनर देखने के अलावा)। – Ree

+3

@Ree - ईमानदारी से, मुझे लगता है कि जेएसटीएल की सबसे बड़ी संपत्ति यह है कि यह आपको जेएसपी में जो भी कोड आती है उसे लिखने की स्वतंत्रता नहीं देता है। जेएसटीएल आपको उन सभी उपकरणों को देता है जिन्हें आपको टेम्पलेट्स लिखने की आवश्यकता होती है, नियंत्रक नहीं, व्यवसाय तर्क प्रबंधक या डेटा एक्सेस ऑब्जेक्ट्स। – RustyTheBoyRobot

2

आप कुछ वेब रूपरेखा का उपयोग करना होगा। या कम से कम कुछ सुविधाजनक टैगलिब। या एक टेम्पलेटिंग एंजिंग फ्रीमार्कर

विज्ञापन चौखटे:

आप कोडिंग के JSP तरह से पसंद करते हैं, तो मैं सुझाव देंगे Struts 2

<s:if test="%{false}"> 
    <div>Will Not Be Executed</div> 
</s:if> 
<s:elseif test="%{true}"> 
    <div>Will Be Executed</div> 
</s:elseif> 
<s:else> 
    <div>Will Not Be Executed</div> 
</s:else> 

तो फिर वहाँ घटक उन्मुख JSF है।

आप OOP और जावा में कोडिंग सब कुछ पसंद है, Apache Wicket (मेरी पसंदीदा) या गूगल वेब टूलकिट प्रयास करें।

+0

का संभावित डुप्लिकेट यदि मैं मदद करता हूं तो स्ट्रैट्स 2 का उपयोग कर रहा हूं। – Chris

+0

अब इसे विन्सेंट द्वारा सुझाए गए जेएसटीएल जैसे टैग लाइब्रेरीज़ के साथ संयोजित करें, और आप स्क्रिप्टलेट से मुक्त हैं। यहां देखें: http://struts.apache.org/2.1.8.1/docs/tag-reference.html और वहां आप पाएंगे, दूसरों के बीच, http://struts.apache.org/2.1.8.1/docs /text.html –

3

आप टैग पुस्तकालयों का उपयोग करके शुरू करना चाह सकते हैं। आप सामान्य टैग लाइब्रेरी JSTL का उपयोग उन सामान्य चीजों को करने के लिए कर सकते हैं जिनके लिए आपको स्क्रिप्लेट की आवश्यकता है। कई अन्य समृद्ध टैग लाइब्रेरीज़ हैं जिनका उपयोग स्ट्रूट 2 फ्रेमवर्क या अपाचे से किया जाता है।

उदा।

<c:if test="${your condition}"> 
     Your Content 
    </c:if> 

आपके विवरणों को प्रतिस्थापित करेगा।

3

लिपियों के पसंदीदा विकल्प जेएसटीएल अभिव्यक्ति भाषा है; here एक अच्छा अवलोकन है। तुम इतनी तरह taglib जोड़ने की आवश्यकता होगी:

<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c' %> 

उदाहरण के लिए, JSTL अंतर्निहित वस्तुओं है कि आप सामान आप की जरूरत दे का एक समूह प्रदान करता है; जो आप चाहते हैं वह pageContext.request है।

तो आप <%request.getRequestURI%>${pageContext.request.requestURI} के साथ प्रतिस्थापित कर सकते हैं।

आप <c:if> टैग का उपयोग कर सशर्त कर सकते हैं।

+0

जेएसटीएल! = अभिव्यक्ति भाषा। जेएसटीएल एक मानक टैगलिब है http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/ अभिव्यक्ति भाषा उन '$ {}' चीजें हैं http://java.sun.com/javaee/5 /docs/tutorial/doc/bnahq.html – BalusC

+1

भविष्य के संदर्भ के लिए: मेरे टैगलिब यूरी में 'http://java.sun.com/jsp/jstl/core' के साथ मुझे और अधिक भाग्य मिला है (http: // के बजाय java.sun.com/jstl/core) – Chris

+0

/jsp/-less uri वास्तव में एक दशक पुराने जेएसटीएल 1.0 का हिस्सा है। इसका इस्तेमाल न करें। – BalusC

9

एक तरफ के रूप में, <%= request.getContextPath() %> ऐसे स्क्रिप्टलेट का एक स्वीकार्य उपयोग है जो इतने पर फंसे नहीं है?

यह एक अलोकप्रिय राय हो सकती है, लेकिन यदि आप सब कुछ सरल सशर्त और टेक्स्ट सम्मिलन हैं, तो मुझे स्क्रिप्टलेट के उपयोग में बहुत अधिक गलती नहीं मिल सकती है।(नोट अगर) JSTL और अभिव्यक्ति भाषा

मैं शायद का उपयोग करेंगे, लेकिन ज्यादातर क्योंकि यह कम लिख कर किया जा सकता है, और आईडीई समर्थन बेहतर हो सकता है (लेकिन एक अच्छा JSP आईडीई भी समापन कोष्ठक लापता पा सकते हैं और इस तरह के सामान)।

लेकिन मौलिक रूप से (के रूप में "टेम्पलेट्स से बाहर तर्क रख") मैं

<% if(request.getRequestURI().contains("/events/")) { %> 

और

${fn:contains(pageContext.request.requestURI, '/events/') 
+3

ठीक है! मैंने सोचा कि मैं इस राय के साथ एकमात्र था! – Chris

+0

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

6

यह आपके सवाल का सीधा जवाब नहीं है (और वहाँ पहले से ही कई अच्छे हैं, तो मैं यह करने के लिए जोड़ने का प्रयास नहीं होगा), लेकिन आप उल्लेख किया:

किसी के साथ कर सकते हैं बिट और जावा/जेएसपी अनुभव कृपया मुझे पॉइंटर्स दें इस कोड को कैसे बदलें तो इसकी अधिक 'सर्वोत्तम अभ्यास', जो हो सकता है?

मेरी राय में, सबसे अच्छा अभ्यास, JSP के संबंध में, कि यह एक templating इंजन के रूप में सख्ती से इस्तेमाल किया जाना चाहिए, और है कोई और अधिक (यानी, कोई व्यापार तर्क वहाँ में)।जेएसटीएल का उपयोग करके, जैसा कि कई ने बताया है, निश्चित रूप से आपको वहां पहुंचने में मदद करता है, लेकिन जेएसटीएल के साथ भी, जेएसपी में बहुत कुछ करना आसान है।

जेएसपी में विकास करते समय मैं टेरेंस पार द्वारा Enforcing Strict Model-View Separation in Templating Engines में निर्धारित नियमों का पालन करना पसंद करता हूं। पेपर टेम्पलेटिंग इंजन (मॉडल और दृश्य को अलग करने), और एक अच्छा टेम्पलेटिंग इंजन की विशेषताओं के उद्देश्य का उल्लेख करता है। यह जेएसपी पर एक अच्छा नज़र डालने लगता है और यह बताता है कि यह एक अच्छा टेम्पलेटिंग इंजन नहीं है। आश्चर्य की बात नहीं है, जेएसपी मूल रूप से बहुत शक्तिशाली है और डेवलपर्स को बहुत अधिक करने की अनुमति देता है। मैं दृढ़ता से इस पेपर को पढ़ने की सलाह देता हूं, और यह आपको जेएसपी के "अच्छे" हिस्सों तक सीमित रखने में मदद करेगा।

  1. दृश्य या तो सीधे मॉडल डेटा वस्तुओं में फेरबदल करके या लागू द्वारा मॉडल को संशोधित नहीं कर सकते हैं:

    आपको लगता है कि समाचार पत्र में केवल एक अनुभाग पढ़ते हैं, अध्याय 7, जो निम्नलिखित नियम भी शामिल पढ़ पर विधियां जो दुष्प्रभाव का कारण बनती हैं। यही है, एक टेम्पलेट मॉडल से डेटा तक पहुंच सकता है और विधियों का आह्वान कर सकता है, लेकिन ऐसे संदर्भ साइड-इफेक्ट मुक्त होना चाहिए। यह नियम आंशिक रूप से उत्पन्न होता है क्योंकि डेटा संदर्भ ऑर्डर-असंवेदनशील होना चाहिए। धारा 7.1 देखें।

  2. दृश्य निर्भर डेटा पर संगणना प्रदर्शन नहीं कर सकते मूल्यों क्योंकि संगणना हो सकता है भविष्य में परिवर्तन और वे बड़े करीने से किसी भी मामले में मॉडल में समझाया जाना चाहिए। उदाहरण के लिए, दृश्य "$ मूल्य * .90" के रूप में पुस्तक बिक्री की कीमतों की गणना नहीं कर सकता है। मॉडल से स्वतंत्र होने के लिए, दृश्य डेटा के अर्थ के बारे में मान्यताओं को नहीं बना सकता है।
  3. दृश्य निर्भर डेटा को महत्व देता तुलना नहीं कर सकते, लेकिन इस तरह उपस्थिति/अनुपस्थिति या एक बहु-मान डेटा मान की लंबाई के रूप में डेटा की गुणों का परीक्षण कर सकते हैं। $ टेस्ट जैसे रक्तचाप < 120 को पर ले जाया जाना चाहिए क्योंकि डॉक्टर को अधिकतम सिस्टोलिक दबाव को घटाकर रखना चाहते हैं। ध्यान में रखते हुए भाव रूप $ bloodPressureOk एक बूलियन ऐसे ing simulat- एक मूल्य की उपस्थिति के लिए एक परीक्षण के साथ प्रतिस्थापित किया जाना चाहिए! = अशक्त खाका उत्पादन मॉडल डेटा और कॉम putations पर सशर्त हो सकता है, सशर्त सिर्फ है मॉडल में गणना करने के लिए। यहां तक ​​कि साधारण परीक्षण जो नकारात्मक मूल्य लाल मॉडल की गणना की जानी चाहिए; अमूर्त का सही स्तर usu- है सहयोगी कुछ उच्च स्तर जैसे दृश्य डेटा प्रकार मान्यताओं नहीं कर सकते हैं "विभाग एक्स पैसे खो रहा है।"
  4. । एक टेम्पलेट मान लिया गया है, तो $ userID एक पूर्णांक है, प्रो- व्याकरण नहीं कर सकते हैं: कुछ प्रकार मान्यताओं स्पष्ट जब दृश्य मान लिया गया एक डेटा मूल्य उदाहरण के लिए, एक तारीख है, लेकिन अधिक सूक्ष्म प्रकार मान्यताओं एपी नाशपाती हैं इस मान को टेम्पलेट को तोड़ने के बिना मॉडल में गैर-न्यूमेरिक होने के लिए बदलें।यह नियम इस तरह के colorCode [$ विषय] और $ नाम के रूप में मनाही सरणी अनुक्रमण [$ आईडी] दृश्य आगे तर्क के साथ नहीं कॉल तरीकों कारण है- सकता है (स्थिर या गतिशील) है एक ग्रहण तर्क जाहिर प्रकार, जब तक एक मॉडल विधि की गारंटी दे सकता है केवल उन्हें ऑब्जेक्ट्स के रूप में माना जाता है। ग्राफिक्स डिजाइनर के अलावा प्रोग्रामर नहीं हैं; उन्हें विधियों का आह्वान करने की उम्मीद है और पता है कि अवास्तविक क्या है।
  5. मॉडल से डेटा में प्रदर्शन या लेआउट जानकारी नहीं होनी चाहिए। मॉडल किसी भी प्रदर्शन डेटा मानों के रूप में छिपे हुए दृश्य को सूचित नहीं कर सकता है। इसमें अन्य डेटा मानों पर लागू करने के लिए टेम्पलेट का नाम पास नहीं किया जा रहा है।

संयोग से, टेरेंस अपने ही templating इंजन String Template जो माना जाता है कि इन नियमों को लागू करने में एक बहुत अच्छा काम करता है कहा जाता है बनाया गया है। मेरे पास इसका कोई व्यक्तिगत अनुभव नहीं है, लेकिन मुझे अपनी अगली परियोजना पर जांचना अच्छा लगेगा।

6

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

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

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