java - شرح jsp بالعربي




كيف تتجنب كود جافا في ملفات JSP؟ (19)

JSP 2.0 لديه ميزة تسمى "Tag Files" ، يمكنك كتابة العلامات دون java code و tld . تحتاج إلى إنشاء ملف .tag ووضعه في WEB-INF\tags يمكنك حتى إنشاء بنية دليل .tag .

فمثلا:

/WEB-INF/tags/html/label.tag

<%@tag description="Rensders a label with required css class" pageEncoding="UTF-8"%>
<%@attribute name="name" required="true" description="The label"%>

<label class="control-label control-default"  id="${name}Label">${name}</label>

استخدمها مثل

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/html"%>
<h:label  name="customer name" />

كما يمكنك قراءة هيئة العلامة easly

/WEB-INF/tags/html/bold.tag
<%@tag description="Bold tag" pageEncoding="UTF-8"%>
<b>
  <jsp:doBody/>
</b>

استخدمها

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/bold"%>
<h:bold>Make me bold</h:bold>

The samples are very simple but you can do lots of complicated tasks here. Please consider you can use other tags (eg: JSTL which has controlling tags like if/forEcah/chosen text manipulation like format/contains/uppercase or even SQL tags select/update ), pass all kind parameters, for example Hashmap , access session , request , ... in your tag file too.

Tag File are so easy developed as you did not need to restart the server when changing them, like jsp files. This make them easy for development.

Even if you use a framework like struts 2, which have lots of good tags, you may find that having your own tags can reduce your code a lot. You can pass your tag parameters to struts and this way customize your framework tag.

You can use tag not only to avoid java but also minimize your HTML codes. I myself try to review HTML codes and build tags a lot as soon as see code duplicates start in my pages.

(Even if you end up using the java in you jsp code, which I hope not, you can encapsulate that code in a tag)

أنا جديد في Java EE وأعرف أنه شيء مثل الخطوط الثلاثة التالية

<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>

طريقة مدرسة قديمة للتشفير وفي JSP الإصدار 2 توجد طريقة لتجنب شفرة Java في ملفات JSP. هل يمكن أن يخبرني شخص ما بخطوط JSP 2 البديلة ، وما تسمى هذه التقنية؟


Wicket هو أيضًا بديل يفصل جافا تمامًا عن html ، لذا يمكن للمصمم والمبرمج العمل معًا وعلى مجموعات مختلفة من الشفرات مع فهم ضئيل لبعضهما البعض.

انظر في Wicket.


إذا كنت ترغب ببساطة في تجنب عيوب ترميز Java في JSP ، فيمكنك القيام بذلك حتى مع scriplets. فقط اتبع بعض الانضباط للحصول على الحد الأدنى من جافا في التخطيط الاستراتيجي المشترك وتقريبا أي حساب والمنطق في صفحة JSP.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%//instantiate a JSP controller
MyController clr = new MyController(request, response);

//process action if any
clr.process(request);

//process page forwaring if necessary

//do all variable assignment here
String showMe = clr.getShowMe();%>

<html>
    <head>
    </head>
    <body>
        <form name="frm1">
            <p><%= showMe %>
            <p><% for(String str : clr.listOfStrings()) { %>
            <p><%= str %><% } %>

            // and so on   
        </form>
    </body>
</html>

إن استخدام scriptlets (تلك الأشياء <% %> ٪٪ <% %> ) في JSP هو في الواقع محبط للغاية منذ ولادة taglibs (مثل JSTL ) و EL ( EL ، تلك الأشياء ${} ) على مدى عقد من الزمان.

العيوب الرئيسية لل scriptlets هي:

  1. إعادة الاستخدام: لا يمكنك إعادة استخدام البرامج النصية.
  2. الاستبدال: لا يمكنك جعل البرامج النصية مجردة.
  3. قدرة OO: لا يمكنك الاستفادة من الميراث / التركيب.
  4. قابلية التصحيح: إذا قام البرنامج النصي برمي استثناء في منتصف الطريق ، فكل ما تحصل عليه هو صفحة فارغة.
  5. قابلية الاختبار: scriptlets ليست وحدة قابلة للاختبار.
  6. القابلية للرعاية : لكل صلدو مزيد من الوقت للحفاظ على المنطق الممزوج / المزدحم / المتكرر.

توصي شركة Sun Oracle نفسها أيضًا في اتفاقيات JSP الخاصة بالتشفير لتجنب استخدام البرامج النصية كلما كانت الوظيفة نفسها ممكنة بواسطة فئات (tag). فيما يلي العديد من الاستشهادات ذات الصلة:

من مواصفات JSP 1.2 ، يوصى بشدة باستخدام JSP Standard Tag Library (JSTL) في تطبيق الويب الخاص بك للمساعدة في تقليل الحاجة إلى البرامج النصية JSP في صفحاتك. الصفحات التي تستخدم JSTL ، بشكل عام ، أسهل في القراءة والصيانة.

...

حيثما أمكن ، تجنب JSP scriptlets كلما توفر مكتبات العلامات وظيفة مكافئة. هذا يجعل من السهل قراءة الصفحات وصيانتها ، ويساعد على فصل منطق الأعمال من منطق العرض التقديمي ، وسيسهل على الصفحات أن تتطور إلى صفحات ذات نمط JSP 2.0 (تدعم مواصفات JSP 2.0 ولكن لا يعيد تفسير استخدام البرامج النصية).

...

انطلاقاً من روح اعتماد نموذج تصميم جهاز عرض نموذج (MVC) لتقليل اقتران بين طبقة العرض التقديمية من منطق الأعمال ، لا يجب استخدام سكربتات JSP لكتابة منطق الأعمال. بدلاً من ذلك ، يتم استخدام البرامج النصية JSP إذا لزم الأمر لتحويل البيانات (تسمى أيضاً "كائنات القيمة") التي يتم إرجاعها من معالجة طلبات العميل إلى تنسيق جاهز للعميل جاهز. حتى ذلك الحين ، من الأفضل القيام بذلك من خلال جهاز تحكم خاص بـ front frontlet أو علامة مخصصة.

كيفية استبدال scriptlets يعتمد بالكامل على الغرض الوحيد من رمز / المنطق. أكثر من كثير من الأحيان يتم وضع هذا الكود في فئة Java كاملة:

  • إذا كنت تريد استدعاء نفس شفرة Java على كل طلب ، أقل أو أكثر بغض النظر عن الصفحة المطلوبة ، مثل التحقق مما إذا كان المستخدم قد قام بتسجيل الدخول ، قم بتطبيق filter وكتابة التعليمات البرمجية وفقًا لذلك في طريقة doFilter() . على سبيل المثال:

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
            ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page.
        } else {
            chain.doFilter(request, response); // Logged in, just continue request.
        }
    }
    

    عند تعيينها على <url-pattern> مناسبة تغطي صفحات JSP المهمة ، فإنك لا تحتاج إلى نسخ نفس الشفرة على جميع صفحات JSP.

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية للقيام بطلب مسبق ، على سبيل المثال تحميل بعض القوائم من قاعدة بيانات لعرضها في بعض الجداول ، إذا لزم الأمر ، استنادًا إلى بعض معلمات الاستعلام ، قم بتطبيق servlet وكتابة التعليمات البرمجية وفقًا لذلك في طريقة doGet() . على سبيل المثال:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            List<Product> products = productService.list(); // Obtain all products.
            request.setAttribute("products", products); // Store products in request scope.
            request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table.
        } catch (SQLException e) {
            throw new ServletException("Retrieving products failed!", e);
        }
    }
    

    هذه الطريقة في التعامل مع الاستثناءات هي أسهل. لا يتم الوصول إلى DB في منتصف عرض JSP ، ولكن قبل عرض JSP. لا يزال لديك إمكانية تغيير الاستجابة عندما يلقي الوصول DB استثناء. في المثال أعلاه ، سيتم عرض صفحة الخطأ الافتراضي 500 والتي يمكنك تخصيصها على أي حال بواسطة <error-page> في web.xml .

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية لإجراء طلب ما بعد المعالجة ، على سبيل المثال معالجة نموذج إرسال ، doPost() بتطبيق servlet وكتابة التعليمات البرمجية وفقًا لذلك في طريقة doPost() . على سبيل المثال:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);
    
        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            response.sendRedirect("home"); // Redirect to home page.
        } else {
            request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope.
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error.
        }
    }
    

    هذه الطريقة في التعامل مع وجهات الصفحات المختلفة للنتائج هي أسهل: إعادة عرض النموذج مع أخطاء التحقق في حالة حدوث خطأ (في هذا المثال بالذات يمكنك إعادة عرضه باستخدام ${message} في EL ) ، أو مجرد الانتقال إلى الصفحة المستهدفة المطلوبة في حالة من النجاح.

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية للتحكم في خطة التنفيذ و / أو وجهة الطلب والاستجابة ، servlet بتطبيق servlet وفقًا لنموذج وحدة التحكم الأمامية في MVC . على سبيل المثال:

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Action action = ActionFactory.getAction(request);
            String view = action.execute(request, response);
    
            if (view.equals(request.getPathInfo().substring(1)) {
                request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
            } else {
                response.sendRedirect(view);
            }
        } catch (Exception e) {
            throw new ServletException("Executing action failed.", e);
        }
    }
    

    أو اعتمد فقط إطار MVC مثل JSF ، Spring MVC ، Wicket ، إلخ ، بحيث ينتهي بك الأمر مع صفحة JSP / Fails وصفصة Javabean دون الحاجة إلى servlet مخصص.

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية للتحكم في التدفق داخل صفحة JSP ، فإنك تحتاج إلى الحصول على taglib للتحكم في تدفق (موجود) مثل JSTL core . مثلا ، عرض List<Product> في جدول:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    ...
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.name}</td>
                <td>${product.description}</td>
                <td>${product.price}</td>
            </tr>
        </c:forEach>
    </table>
    

    مع علامات نمط XML التي تناسب بشكل جيد بين كل تلك HTML ، يمكن قراءة الكود بشكل أفضل (وبالتالي أفضل للصيانة) من مجموعة من البرامج النصية مع مختلف الأقواس الفتحة والإغلاق ( "أين هيك ينفذ هذا قوس إغلاق؟" ). من السهل المساعدة في تكوين تطبيق الويب الخاص بك لرمي استثناء عندما لا يزال يتم استخدام scriptlets عن طريق إضافة القطعة التالية إلى web.xml :

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

    في Facelets ، كان خليفة JSP ، الذي هو جزء من Java EE الذي يوفر إطار عمل JSF MVC ، ليس من الممكن بالفعل استخدام البرامج النصية . بهذه الطريقة تضطر تلقائياً للقيام بالأشياء "بالطريقة الصحيحة".

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية للدخول إلى بيانات "الواجهة الخلفية" وعرضها داخل صفحة JSP ، فأنت بحاجة إلى استخدام EL (لغة التعبير) ، تلك الأشياء ${} . على سبيل المثال ، إعادة عرض قيم الإدخال المقدمة:

    <input type="text" name="foo" value="${param.foo}" />
    

    يعرض ${param.foo} نتائج request.getParameter("foo") .

  • إذا كنت تريد استدعاء بعض تعليمات Java البرمجية مباشرة في صفحة JSP (عادة ما تكون طرق public static ) ، فأنت بحاجة إلى تعريفها كدالات EL. هناك توصيف وظائف قياسية في JSTL ، ولكن يمكنك أيضًا إنشاء الوظائف بنفسك بسهولة . فيما يلي مثال على كيفية استخدام JSTL fn:escapeXml لمنع attacks XSS .

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    ...
    <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
    

    لاحظ أن حساسية XSS لا تتعلق على وجه التحديد بجافا / JSP / JSTL / EL / مهما كانت ، يجب أخذ هذه المشكلة بعين الاعتبار في كل تطبيق ويب تقوم بتطويره. مشكلة scriptlets هو أنه لا يوفر أي وسيلة لمنع عمليات البناء ، على الأقل عدم استخدام API جافا القياسية. وقد خلفت Facelets التي خلفتها JSP ضمنيًا هروب HTML ، لذا لا داعي للقلق بشأن ثقوب XSS في Facelets.

أنظر أيضا:


استخدم JSTL Tag libraries في JSP ، التي ستعمل بشكل مثالي.


بالتأكيد ، استبدل <%! counter++; %> <%! counter++; %> <%! counter++; %> بواسطة بنية منتج-مستهلك حدث ، حيث يتم إعلام طبقة الأعمال عن الحاجة إلى زيادة العداد ، فإنه يتفاعل وفقًا لذلك ، ويقوم بإعلام المقدمين بحيث يقومون بتحديث طرق العرض. يتم تضمين عدد من معاملات قواعد البيانات ، لأننا في المستقبل سوف نحتاج إلى معرفة القيمة الجديدة والقديمة للعداد ، الذي قام بتزايده ومع أي غرض في ذهنه. من الواضح أن التسلسل متضمن ، حيث يتم فصل الطبقات تمامًا. ستتمكن من زيادة العداد على RMI و IIOP و SOAP. لكن HTML فقط هو المطلوب ، وهو ما لا تقوم بتطبيقه ، حيث إنه حالة عادية. هدفك الجديد هو الوصول إلى 250 وحدة في الثانية على خادم E7 الجديد اللامع وذاكرة RAM سعة 64 جيجابايت.

لدي أكثر من 20 سنة في البرمجة ، معظم المشاريع تفشل قبل sextet: Reusability Replaceability OO -قدرة قابلية تصحيح قابلية التحقق. مشاريع أخرى ، يديرها أشخاص لا يهتمون إلا بالوظائف ، كانوا ناجحين للغاية. أيضا ، بنية جسم قاسية ، نفذت في وقت مبكر جدا من المشروع ، يجعل الكود غير قادر على التكيف مع التغيرات الجذرية في المواصفات (الملقبة رشيقة).

لذلك أعتبر أن التسويف هو نشاط تعريف "الطبقات" أو هياكل البيانات الزائدة سواء في وقت مبكر من المشروع أو عندما لا تكون مطلوبة بشكل محدد.


تقدم JSTL علامات للشروط ، والحلقات ، والمجموعات ، ويحصل ، إلخ. على سبيل المثال:

<c:if test="${someAttribute == 'something'}">
   ...
</c:if>

تعمل JSTL مع سمات الطلب - يتم تعيينها غالبًا في الطلب بواسطة Servlet ، والتي يتم توجيهها إلى JSP.


فقط استخدم علامة JSTL والتعبير EL.


في النمط المعماري MVC ، تمثل JSPs طبقة العرض. يعتبر تضمين كود جافا في JSPs ممارسة سيئة. يمكنك استخدام JSTL ، freeMarker ، velocity مع JSP "محرك القوالب". يعتمد مزود البيانات لهذه العلامات على الأطر التي تتعامل معها. Struts 2 والعمل على شبكة webwork لنمط MVC يستخدم OGNL "تقنية مثيرة جدا لفضح Beans Properties to JSP".


لست متأكدا مما اذا كان هذا صحيح.

يجب عليك قراءة شيء ما عن MVC. Spring MVC & Struts 2 هما الحلان الأكثر شيوعًا.


لقد أظهرت التجربة أن JSP لديها بعض العيوب ، من الصعب تجنب خلط الترميز مع الكود الفعلي.

إذا كنت تستطيع ، فكر في استخدام تقنية متخصصة لما تحتاج إلى القيام به. في Java EE 6 يوجد JSF 2.0 ، الذي يوفر الكثير من الميزات #{bean.method(argument)} بما في ذلك لصق الفاصوليا Java مع صفحات JSF عبر #{bean.method(argument)} .


من أجل تجنب شفرة جافا في ملفات JSP ، توفر java الآن مكتبات العلامات مثل JSTL كما أن java قد ظهرت مع JSF حيث يمكنك كتابة جميع تراكيب البرمجة في شكل علامات


يمكنك استخدام علامات JSTL مع تعبيرات EL لتجنب اختلاط كود Java و HTML:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
    <head>
    </head>
    <body>

        <c:out value="${x + 1}" />
        <c:out value="${param.name}" />
    // and so on

    </body>
</html>

كيف تتجنب كود جافا في ملفات JSP؟

يمكنك استخدام علامات مكتبة علامات التبويب مثل JSTL بالإضافة إلى لغة التعبير ( EL ). لكن EL لا تعمل بشكل جيد مع JSP. لذلك ربما يكون من الأفضل إسقاط JSP تمامًا واستخدام Facelets .

تعتبر Facelets أول لغة إعلان غير مرتبط ببرنامج JSP تم تصميمها لـ JSF (Java Server Faces) والتي توفر نموذج برمجة أبسط وأكثر قوة لمطوري JSF مقارنة مع JSP. أنه يحل قضايا مختلفة تحدث في JSP لتطوير تطبيقات الويب.


تعلم كيفية تخصيص وكتابة علاماتك الخاصة باستخدام JSTL

لاحظ أن EL هي EviL (استثناءات وقت التشغيل ، إعادة بيع ديون)
قد يكون Wicket شريرًا أيضًا (أداءً ، مملوءًا للتطبيقات الصغيرة أو طبقة عرض بسيطة)

مثال من java2s ،

يجب إضافة هذا إلى web.xml لتطبيق الويب

<taglib>
    <taglib-uri>/java2s</taglib-uri>
    <taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>

create file: java2s.tld in the / WEB-INF /

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>Java2s Simple Tags</short-name>

    <!-- this tag manipulates its body content by converting it to upper case
    -->
    <tag>
        <name>bodyContentTag</name>
        <tag-class>com.java2s.BodyContentTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
          <name>howMany</name>
        </attribute>
    </tag>
</taglib>

ترجمة التعليمات البرمجية التالية إلى WEB-INF \ classes \ com \ java2s

package com.java2s;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyContentTag extends BodyTagSupport{
    private int iterations, howMany;

    public void setHowMany(int i){
        this.howMany = i;
    }

    public void setBodyContent(BodyContent bc){
        super.setBodyContent(bc);
        System.out.println("BodyContent = '" + bc.getString() + "'");
    }

    public int doAfterBody(){
        try{    
            BodyContent bodyContent = super.getBodyContent();
            String bodyString  = bodyContent.getString();
            JspWriter out = bodyContent.getEnclosingWriter();

            if ( iterations % 2 == 0 ) 
                out.print(bodyString.toLowerCase());
            else
                out.print(bodyString.toUpperCase());

            iterations++;
            bodyContent.clear(); // empty buffer for next evaluation
        }
        catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
            e.printStackTrace();
        } // end of catch

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

بدء الخادم وتحميل bodyContent.jsp في المستعرض

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>

كضمانة: تعطيل Scriptlets من أجل الخير

نظرًا لمناقشة سؤال آخر ، يمكنك دائمًا تعطيل scriptlets في واصف تطبيق الويب web.xml .

سأفعل ذلك دائمًا من أجل منع أي مطور يضيف برامج نصية ، خاصة في الشركات الأكبر حيث ستفقد النظرة العامة عاجلاً أم آجلاً. تبدو إعدادات web.xml :

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

As many answers says, use JSTL or create your own custom tags. Here is good explanation about creating custom tags


Nothing of that is used anymore my friend, my advice is to decouple the view(css, html, javascript, etc) from the server.

In my case I do my systems handling the view with Angular and any data needed is brought from the server using rest services.

Believe me, this will change the way you design


باستخدام علامات JSTL مع تعبير EL يمكنك تجنب ذلك. ضع الأشياء التالية في صفحة jsp الخاصة بك:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>




scriptlet