JSP dosyalarında Java kodu nasıl önlenir?


1673

Java EE'de yeniyim ve aşağıdaki üç satır gibi bir şey olduğunu biliyorum

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

kodlama eski bir okul yoludur ve JSP sürüm 2 JSP dosyalarında Java kodu önlemek için bir yöntem vardır. Birisi bana alternatif JSP 2 satırlarını söyleyebilir ve bu tekniğe ne denir?


22
@Koray Tugay, sayaç değişkeni kullanılmadan önce bir yerde bildirildiği sürece, o zaman kesinlikle geçerlidir ...
Sheldon R.

@SheldonR. Bu geçerlidir: <% = counter ++%> veya şu: <%! int sayacı = 0; int x = sayaç ++; %> ama değil: <%! int sayacı = 0; sayaç ++; %>
Koray Tugay

@KorayTugay, ne demek istediğim değişken sayacı daha önceki bir komut dosyası bloğunda bildirilmişse, daha sonraki bir blokta geçerli olmalıdır. Ama sonuçta, J2EE ... neyse, bu gün scriptlets yerine EL değişkenler kullanarak gerektiğini programcılar
Sheldon R.

Yanıtlar:


1971

Kullanımı scriptlets (bu <% %>işler) JSP gerçekten çok doğumundan beri önerilmez taglibs (gibi JSTL ve) EL ( Expression Dili , o${} şeyler) 2001 yılında şekilde geri.

Senaryoların en büyük dezavantajları şunlardır:

  1. Tekrar Kullanılabilirlik: komut dosyalarını yeniden kullanamazsınız.
  2. Değiştirebilirlik: komut dosyalarını soyut yapamazsınız.
  3. OO-yeteneği: kalıtım / kompozisyondan yararlanamazsınız.
  4. Debuggability: scriptlet yarısına bir istisna atarsa, elde ettiğiniz tek şey boş bir sayfadır.
  5. Testedilebilirlik: scriptletler birim olarak test edilemez.
  6. Sürdürülebilirlik: Saldo başına, karışık / karmaşık / çoğaltılmış kod mantığını korumak için daha fazla zaman gerekir.

Sun Oracle, aynı zamanda (tag) sınıfları tarafından aynı işlevsellik mümkün olduğunda komut dosyalarının kullanılmasını önlemek için JSP kodlama kurallarında da öneride bulunmaktadır . İşte birkaç alaka düzeyi:

JSP 1.2 Spesifikasyonu'ndan, web uygulamanızda JSP Standart Etiket Kitaplığı'nın (JSTL) kullanılması , sayfalarınızdaki JSP komut dosyası ihtiyacını azaltmaya yardımcı olması önemle tavsiye edilir . JSTL kullanan sayfaların genel olarak okunması ve bakımı daha kolaydır.

...

Mümkünse, etiket kitaplıkları eşdeğer işlevsellik sağladığında JSP komut dosyalarından kaçının . Bu, sayfaların okunmasını ve bakımını kolaylaştırır, iş mantığını sunum mantığından ayırmaya yardımcı olur ve sayfalarınızın JSP 2.0 tarzı sayfalara dönüşmesini kolaylaştırır (JSP 2.0 Spesifikasyonu, scriptletlerin kullanımını destekler ancak vurguyu kaldırır).

...

İş mantığından sunum katmanı arasındaki bağlantıyı azaltmak için model-görünüm denetleyicisi (MVC) tasarım desenini benimsemek amacıyla, JSP komut dosyaları iş mantığı yazmak için kullanılmamalıdır . Bunun yerine, istemcinin isteklerinin işlenmesinden döndürülen verileri ("değer nesneleri" olarak da adlandırılır) dönüştürmek için gerekirse JSP komut dosyaları kullanılır. O zaman bile, bu bir ön denetleyici sunucu uygulaması veya özel bir etiketle daha iyi yapılabilir.


Komut dosyalarının nasıl değiştirileceği tamamen kodun / mantığın amacına bağlıdır. Çoğu zaman bu kod tam bir Java sınıfına yerleştirilmelidir:

  • Her istekte aynı Java kodunu çağırmak istiyorsanız , istenen sayfadan bağımsız olarak daha az veya daha fazla, örneğin bir kullanıcının oturum açıp açmadığını kontrol etmek, ardından bir filtre uygulayın ve buna göre kod yazın.doFilter() yönteme . Örneğin:

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

    İlgili <url-pattern>JSP sayfalarını kapsayan uygun bir haritaya eşlendiğinde, aynı kod genel JSP sayfalarını kopyalamanız gerekmez.


  • Bazı Java kodlarını , örneğin bazı sorgu parametrelerine dayanarak gerekirse bir tabloda görüntülemek üzere veritabanından bazı listelerin önceden yüklenmesi gibi bir isteği önceden işlemek için çağırmak istiyorsanız , yönteme uygun olarak bir sunucu uygulaması ve yazma kodu uygulayın doGet(). Örneğin:

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

    Bu şekilde istisnalarla uğraşmak daha kolaydır. DB'ye JSP oluşturma işleminin ortasında değil, JSP'nin görüntülenmesinden çok önce erişilir. DB erişimi bir istisna attığında yanıtı yine de değiştirme olanağınız vardır. Yukarıdaki örnekte, bir <error-page>giriş tarafından özelleştirebileceğiniz varsayılan hata 500 sayfası görüntülenecektir web.xml.


  • Bir isteği göndermek için bazı Java kodlarını çağırmak istiyorsanız , örneğin bir form gönderimini işleme koymak için , yönteme uygun olarak bir sunucu uygulaması ve kod yazın doPost(). Örneğin:

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

    Farklı sonuç sayfası hedeflere uğraşan Bu şekilde daha kolay olur: Bu özel örnekte (bir hata durumunda doğrulama hataları ile formunu yeniden görüntüleme kullanarak tekrar görüntülemek için ${message}de EL ), ya da sadece başarı durumunda istenen hedef sayfasına alarak.


  • İsteğin ve yanıtın yürütme planını ve / veya hedefini denetlemek için bazı Java kodlarını çağırmak istiyorsanız, MVC'nin Ön Denetleyici Modeline göre bir sunucu uygulaması uygulayın . Örneğin:

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

    Veya özel bir sunucu uygulamasına gerek kalmadan sadece JSP / Facelets sayfası ve JavaBean sınıfı ile sonuçlanacak şekilde JSF , Spring MVC , Wicket vb.Gibi bir MVC çerçevesini benimseyin .


  • Bir JSP sayfasındaki akışı kontrol etmek için bazı Java kodlarını çağırmak istiyorsanız, JSTL çekirdeği gibi (mevcut) bir akış denetimi taglib'i almanız gerekir . Örn.List<Product> bir tabloda :

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

    Tüm bu HTML kodlarına çok iyi uyan XML tarzı etiketlerle, kod, çeşitli açılış ve kapanış parantezleri içeren bir grup betiğe göre daha iyi okunabilir (ve dolayısıyla daha iyi korunabilir) ( "Bu kapanış ayracı nereye aittir?" ). Kolay bir yardım, web uygulamanızı, komut dosyaları her kullanıldığında bir istisna oluşturacak şekilde aşağıdaki parçayı ekleyerek yapılandırmaktır web.xml:

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

    In Facelets Java EE parçasıdır JSP'nin halefi MVC framework sağlanan JSF , zaten değil kullanmak mümkün scriptlets . Bu şekilde işleri otomatik olarak "doğru şekilde" yapmak zorunda kalırsınız.


  • Bir JSP sayfasındaki "arka uç" verilerine erişmek ve bunları görüntülemek için bazı Java kodlarını çağırmak istiyorsanız , EL (İfade Dili) kullanmanız gerekir ${}. Örneğin, gönderilen girdi değerlerinin yeniden görüntülenmesi:

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

    Sonuçlarını ${param.foo}görüntülerrequest.getParameter("foo") .


  • Bazı yardımcı program Java kodunu doğrudan JSP sayfasında çağırmak istiyorsanız (genellikle public staticyöntemler), bunları EL işlevleri olarak tanımlamanız gerekir. JSTL'de standart işlevler taglib vardır, ancak işlevleri kendiniz de kolayca oluşturabilirsiniz . İşte JSTL'nin XSS saldırılarınıfn:escapeXml önlemek için ne kadar yararlı olduğunu gösteren bir örnek .

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

    XSS duyarlılığının hiçbir şekilde özellikle Java / JSP / JSTL / EL / ile ilişkili olmadığını unutmayın, bu sorunun geliştirdiğiniz her web uygulamasında dikkate alınması gerekir . Komut dosyalarının sorunu , en azından standart Java API'sini kullanmadan yerleşik önleme yolu sağlamamasıdır. JSP'nin halefi Facelets zaten örtülü HTML çıkışına sahip, bu yüzden Facelets'teki XSS delikleri hakkında endişelenmenize gerek yok.

Ayrıca bakınız:


117
+1 Harika cevap. Ama dogmatik gitmeyin, bazen senaryoları kullanmak sorun değil, ama bu kuralı kanıtlayan bir istisna olmalıdır.
svachon

26
@svachon: Komut dosyaları hızlı prototipleme / test için kullanışlıdır. Bildiğim kadarıyla, bir scriptlet'in sadece bir "meşru" üretim kullanımı var, yani webbrowser'daki web sayfası ayrıştırma performansını geliştirmek <% response.getWriter().flush(); %>için </head>ve arasında <body>. Ancak sunucu tarafında çıkış arabellek boyutu düşük olduğunda (1 ~ 2KB) bu kullanım tamamen ihmal edilebilir. Ayrıca bu makaleye bakın .
BalusC

5
@BalusC Birkaç kez getter / setter örüntüsünü takip etmeyen java sınıflarına takılı kaldım. IMHO, bir betik dosyasının işi yaptığı bir durumdur.
svachon

41
@svachon: Bu sınıfları kendi javabean sınıflarıyla sararım ve onun yerine kullanırdım.
BalusC

31
Bu oldukça iyi bir cevaptı, ama doGet ve doPost parçaları yanıltıcı. Bu yöntemler belirli istek (HEAD, GET ve POST) yöntemlerini işlemek içindir ve "önişleme" veya "postişleme" istekleri için değildir!
MetroidFan2002

225

Bir Koruma Olarak: Komut Dosyalarını İyilik İçin Devre Dışı Bırakma

Başka bir soru tartışırken, web.xmlweb uygulaması tanımlayıcınızdaki komut dosyalarını devre dışı bırakabilirsiniz ve her zaman devre dışı bırakabilirsiniz .

Herhangi bir geliştiricinin, özellikle er ya da geç genel bakışınızı kaybedeceğiniz büyük şirketlerde komut dosyası eklemesini önlemek için bunu her zaman yapardım. web.xmlAyarları aşağıdaki gibi görünür:

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

4
Bu, komut dosyası yorumlarını da devre dışı bırakır mı ?: <%-- comment that i don't want in the final HTML --%>. HTML yorumları yerine bunları kullanmanın yararlı olduğunu düşünüyorum.
David Lavender

16
@ MRSpoon sizin için bir cevap buldu. Gereğince bu yanıtı + yorumun , scriptlets kapalı bu dönüşler <% %>, scriptlet ifadeler <%! %>ve komut dosyası bildirimleri <%= %>. Bu, direktiflerin <%@ %>ve yorumların <%-- --%>etkin ve kullanılabilir kaldığı anlamına gelir ; böylece yine de yorum ve içerik ekleyebilirsiniz.
Martin Carney

3
Scriptlet direktiflerinin devre dışı bırakılması korkunç olacaktır - trim beyaz boşluk, ekstra boşlukla korkan eski sistemlerle etkileşim için çok değerlidir.
corsiKa

108

JSTL , koşullu, döngüler, kümeler, almalar vb. İçin etiketler sunar. Örneğin:

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

JSTL isteği nitelikleri ile çalışır - onlar en sık Servlet tarafından talep ayarlanır ileriye JSP için.


2
Neden JSTL'nin istek özellikleriyle çalıştığını söylüyorsunuz? Niteliklerle herhangi bir kapsamda çalışabilirler, değil mi?
Koray Tugay

60

Bunu doğru yapıp yapmadığımdan emin değilim.

MVC hakkında bir şeyler okumalısınız. Spring MVC & Struts 2 en yaygın iki çözümdür.


29
MVC, Springlet veya Struts olmadan yukarıdaki tekniklerin birçoğunu kullanarak sunucu uygulamaları / jsp ile uygulanabilir.
stepanian

18
Soruyu nasıl cevaplıyor?
xyz

54

Java ve HTML kodunu karıştırmamak için JSTL etiketlerini EL ifadeleriyle birlikte kullanabilirsiniz:

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

34

Wicket gibi sizin için çok fazla HTML üreten bileşen tabanlı çerçeveler de vardır . HTML ile sonuçlanan etiketler son derece basittir ve neredeyse karışan bir mantık yoktur. Sonuç, tipik HTML öğeleri içeren neredeyse boş benzeri HTML sayfalarıdır. Dezavantajı, Wicket API'sında öğrenilecek çok sayıda bileşen olması ve bu kısıtlamalar altında bazı şeylerin başarılması zor olabilir.


33

MVC Mimari modelinde, JSP'ler Görünüm katmanını temsil eder. Java kodunun JSP'lere yerleştirilmesi kötü bir uygulama olarak kabul edilir. "Şablon motoru" olarak JSP ile JSTL , freeMarker , hız kullanabilirsiniz . Bu etiketlerin veri sağlayıcısı , uğraştığınız çerçevelere bağlıdır . Struts 2ve webworkMVC Pattern için bir uygulama olarak OGNL "Fasulye Özellikleri JSP maruz göstermek için çok ilginç bir teknik" kullanır .


27

Deneyimler, JSP'lerin bazılarının eksikliklere sahip olduğunu gösterdi, bunlardan biri, biçimlendirmeyi gerçek kodla karıştırmaktan kaçınmak zor.

Yapabiliyorsanız, yapmanız gerekenler için özel bir teknoloji kullanmayı düşünün. Java EE 6'da, Java çekirdeklerini #{bean.method(argument)}yaklaşımla JSF sayfalarıyla yapıştırmak da dahil olmak üzere birçok güzel özellik sağlayan JSF 2.0 var .


3
Eski cevap ama JSF'nin Java uzayındaki en korkunç buluşlardan biri olduğunu söylemeye dayanamıyorum. Tek bir (HTTP GET benzeri) bağlantı oluşturmaya çalışın ve nedenini anlayacaksınız.
Alex

@Alex ama yine de daha iyi. Daha iyi bir şey tavsiye etmekten çekinmeyin.
Thorbjørn Ravn Andersen

26

JSP'de Java kodlamasının dezavantajlarından kaçınmak istiyorsanız, bunu komut dosyalarıyla bile yapabilirsiniz. JSP'de minimum Java'ya ve JSP sayfasında neredeyse hiç hesaplama ve mantığa sahip olmak için bazı disiplinleri takip edin.

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

26

JSTL kullanarak kendi etiketlerinizi özelleştirmeyi ve yazmayı öğrenin

Not EL olduğunu EviL (çalışma zamanı istisnaları üstlenmeden)
Wicket çok kötü (küçük uygulamalar veya basit görünüm katmanı için performans, meşakkatli) olabilir

Örnek java2s ,

Bu, web uygulamasının web.xml dosyasına eklenmelidir

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

/ WEB-INF / içinde Dosya: java2s.tld oluştur

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

aşağıdaki kodu WEB-INF \ classes \ com \ java2s içine derleyin

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

Sunucuyu başlatın ve bodyContent.jsp dosyasını tarayıcıya yükleyin

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

bileşenlerin yeniden kullanılabilirliği iyi olsa da, bazı alanları hedefliyor
Ağustos'ta

25

Wicket ayrıca java'yı html'den tamamen ayıran bir alternatiftir, bu nedenle bir tasarımcı ve programcı birbirlerini çok az anlayarak birlikte ve farklı kod kümelerinde çalışabilir.

Wicket'e bak.


23

İyi bir soru sordunuz ve iyi cevaplar almanıza rağmen JSP'den kurtulmanızı öneririm. Sonunda ölecek olan modası geçmiş bir teknolojidir. Şablon motorları gibi modern bir yaklaşım kullanın. İş ve sunum katmanlarının çok net bir şekilde ayrılmasına ve şablonlarda kesinlikle Java koduna sahip olmayacaksınız, böylece çoğu durumda WYSIWYG'den yararlanarak doğrudan web sunumu düzenleme yazılımından şablonlar oluşturabilirsiniz.

Ve kesinlikle filtrelerden ve ön ve son işlemlerden uzak durun, aksi takdirde değişkenin değeri nereden aldığını her zaman bilmediğiniz için destek / hata ayıklama zorluklarıyla başa çıkabilirsiniz.


9

1
-1 - Filtreleri, ön işlemcileri ve son işlemcileri kullanmak için tamamen geçerli birçok neden vardır. Evet, gizemli görünen değerlerle sonuçlanabilir, ancak mimarinizi anlarsanız değil.
RustyTheBoyRobot

21

java kodu JSP dosyalarında önlemek için java şimdi JSTL gibi etiket kitaplıkları sağlar da java u içine tüm programlama yapıları etiketleri şeklinde yazabilirsiniz JSF ile geldi


21

Ne kadar kaçınmaya çalışırsanız çalışın, diğer geliştiricilerle çalışırken, bazıları hala scriptlet'i tercih edecek ve daha sonra kötü kodu projeye ekleyecektir. Bu nedenle, komut dosyası kodunu gerçekten azaltmak istiyorsanız, projeyi ilk işarette ayarlamak çok önemlidir. Bunun üstesinden gelmek için birkaç teknik vardır (diğerlerinin bahsettiği birkaç çerçeve dahil). Ancak, saf JSP yolunu tercih ediyorsanız, JSTL etiket dosyasını kullanın. Bununla ilgili güzel olan şey, projeniz için kalıp sayfalar da ayarlayabilmenizdir, böylece diğer sayfalar kalıp sayfaları devralabilir

Aşağıdaki içeriğe sahip WEB-INF / etiketlerinizin altında base.tag adlı bir ana sayfa oluşturun

<%@tag description="Overall Page template" pageEncoding="UTF-8"%>

<%@attribute name="title" fragment="true" %>

<html>
  <head>
    <title>  
       <jsp:invoke fragment="title"></jsp:invoke>
    </title>

  </head>
  <body>
    <div id="page-header">
       ....
    </div>
    <div id="page-body">
      <jsp:doBody/>
    </div>
    <div id="page-footer">
      .....
    </div>
  </body>
</html>

Bu mater sayfasında, "title" adlı bir parça oluşturdum, böylece alt sayfada ana sayfanın bu yerine daha fazla kod ekleyebilirim. Ayrıca, etiketin <jsp:doBody/>yerini alt sayfanın içeriği alır

WebContent klasörünüzde alt sayfa (child.jsp) oluşturun:

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:base>
    <jsp:attribute name="title"> 
        <bean:message key="hello.world" />
    </jsp:attribute>

    <jsp:body>
    [Put your content of the child here]
    </jsp:body>   
</t:base>

<t:base>, kullanmak istediğiniz kalıp sayfayı belirtmek için kullanılır (şu anda base.tag). <jsp:body>Buradaki etiketin içindeki tüm içerik <jsp:doBody/>kalıp sayfanızdaki yerini alacaktır . Alt sayfanız ayrıca herhangi bir etiket kitaplığı içerebilir ve normalde yukarıda belirtilenler gibi kullanabilirsiniz. Ancak, burada herhangi bir komut dosyası kodu kullanırsanız ( <%= request.getParameter("name") %>...) ve bu sayfayı çalıştırmayı denerseniz, bir JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Bu nedenle, diğer insanların kötü kodu jsp dosyasına ekleyebilmesinin hiçbir yolu yoktur

Bu sayfayı kumandanızdan arıyor:

Child.jsp dosyasını kumandanızdan kolayca çağırabilirsiniz. Bu ayrıca payandalar çerçevesiyle de iyi çalışır


"Ne kadar kaçınmaya çalışırsanız çalışın, diğer geliştiricilerle çalışırken, bazıları hala scriptlet'i tercih edecek ve daha sonra kötü kodu projeye ekleyecektir." Bkz.
Lluis Martinez



17

Birisi gerçekten birden fazla dilde programlamaya karşıysa, GWT'yi öneririm, teorik olarak tüm JS ve HTML öğelerinden kaçınabilirsiniz, çünkü Google Toolkit tüm istemciyi ve paylaşılan kodu JS'ye dönüştürür, bu nedenle sorun yaşamayacaksınız, bu yüzden başka bir dilde kodlama yapmadan bir web servisiniz var. Hatta bazı varsayılan CSS'leri uzantılardan (smartGWT veya Vaadin) verdiği gibi bir yerden kullanabilirsiniz. Düzinelerce ek açıklama öğrenmenize gerek yoktur.

Tabii isterseniz, kendinizi kodun derinliklerine hackleyebilir ve JS enjekte edebilir ve HTML sayfanızı zenginleştirebilirsiniz, ancak gerçekten isterseniz bunu önleyebilirsiniz ve sonuç diğer çerçevelerde yazıldığı gibi iyi olacaktır. Denemeye değer diyorum ve temel GWT iyi belgelenmiş.

Ve elbette birçok diğer programcı burada başka çözümler önerdi veya önerdi. GWT, gerçekten web bölümü ile uğraşmak veya minimalize etmek istemeyen insanlar içindir.


1
OP'nin sorusuna gerçekten cevap vermiyor.
Evan Donovan

1
@EvanDonovan iyi, pratikte bir cevap veriyor. Diğer dillerle karışan Java kodlarını karıştırmanıza gerek yoktur. Kodlama için Java kullandığını itiraf ediyorum, ancak Java çağrıları olmadan JS'ye çevrilecek. Ancak sorunun kapsamı, klasik JSP'nin kaosundan nasıl kaçınılacağıdır. Ve GWT teknolojisi bunu çözer. Kimseden bahsetmediği için bu cevabı ekledim, ancak JSP'ye bir alternatif olduğu için ilgili. Sorunun tüm kapsamını cevaplamak istemedim, ancak alternatifleri arayan insanlar için değerli bir bilgi eklemek istedim.
CsBalazsHungary

16

Python dünyasından güzel bir fikir Şablon özellik dilleri ; TAL, Zope tarafından tanıtıldı (bu nedenle "Zope Sayfa Şablonları", ZPT) ve PHP, XSLT ve Java uygulamalarıyla da bir standarttır (Python / Zope ve PHP enkarnasyonlarını kullandım). Bu şablonlama dilleri sınıfında yukarıdaki örneklerden biri şöyle görünebilir:

<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name">Example product</td>
        <td tal:content="product/description">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

Kod, sıradan HTML (veya XHTML) artı bir XML ad alanındaki bazı özel özelliklere benzer; bir tarayıcı ile görüntülenebilir ve bir tasarımcı tarafından güvenle değiştirilebilir. Makrolar ve i18n için de destek var:

<h1 i18n:translate="">Our special offers</h1>
<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name"
            i18n:translate="">Example product</td>
        <td tal:content="product/description"
            i18n:translate="">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

İçeriğin çevirileri mevcutsa kullanılırlar.

Java uygulaması hakkında çok fazla bilgim yok .


1
JSP, Aralık 2009'dan bu yana bunu destekleyen Facelets tarafından yerine getirilmiştir. Facelets ayrıca XML tabanlıdır. Ayrıca , Java EE 6 eğitimindeki Facelets bölümüne ve ui:xxxFacelts VDL'deki etiketler bölümüne de bakın .
BalusC

Facelets'i çok iyi tanımıyorum, ancak IIRC, özel XML öğelerini uygulayan sınıflar yazmakla ilgilidir. TAL / ZPT yolu, orijinal öğeleri dolduran veya değiştiren özel niteliklere sahip gerçek (X) HTML içeren şablonlara sahip olmaktır; böylece, çalışma şablonunu görüntüleyebilir ve hoş sahte içerikli bir prototip görebilirsiniz. Facelets, özel nitelikleri kullanarak orijinal HTML öğelerini (ek bir ad alanı olmadan) değiştirmeye izin verdiğinden emin değilim.
Tobias

Bu Facelets malzemelerine bir kez daha baktım. Her türlü onaylama tesisini vb. İçerir ve bu nedenle TAL'den tamamen farklı bir felsefeyi takip eder. TAL yolu, "Mantığı şablondan olabildiğince temiz bir şekilde uzak tutun; tüm karmaşık şeyleri besleyen denetleyici tarafından yapılsın." Bir tasarımcıya onu düzeltmesi için bir Facelets şablonu vermeyeceksiniz; bu mümkün değil. Oluşturulan içerikle ilgili olarak - tıpkı tal:replace="structure (expression)"nitelikleri her zaman kullanmak gibidir .
Tobias


14

Elbette, <%! counter++; %>iş katmanının sayacı arttırma ihtiyacı hakkında bilgilendirildiği bir etkinlik üreticisi-tüketici mimarisi ile değiştirilir , buna göre tepki verir ve sunum yapanları görünümleri güncellemeleri için bilgilendirir. Bir dizi veritabanı işlemi söz konusudur, çünkü gelecekte sayacın yeni ve eski değerini, kimin arttığını ve hangi amaçla akılda bulunduğunu bilmemiz gerekecek. Tabii ki serileştirme söz konusudur, çünkü katmanlar tamamen ayrılmıştır. Sayacınızı RMI, IIOP, SOAP üzerinden artırabilirsiniz. Ancak bu kadar sıradan bir durum olduğu için uygulamadığınız yalnızca HTML gereklidir. Yeni hedefiniz, yeni parlak E7, 64GB RAM sunucunuzda saniyede 250 artışa ulaşmaktır.

Programlamada 20 yıldan fazla süredir var, projelerin çoğu sextet'ten önce başarısız oluyor: Yeniden Kullanılabilirlik Değiştirilebilirlik OO yeteneği Hata Ayıklanabilirliği Test Edilebilirlik Sürdürülebilirlik bile gereklidir. Sadece işlevselliği önemseyen insanlar tarafından yürütülen diğer projeler son derece başarılıydı. Ayrıca, projede çok erken uygulanan sert nesne yapısı, kodun spesifikasyonlardaki (diğer adıyla çevik) ciddi değişikliklere adapte edilememesini sağlar.

Bu yüzden erteleme olarak, projenin başlangıcında veya özel olarak gerekli olmadığında "katmanları" veya artık veri yapılarını tanımlama etkinliğini dikkate alıyorum.  


11

Teknik olarak, JSP'nin tamamı çalışma zamanı sırasında Servlet'lere dönüştürülür . JSP başlangıçta MVC modelini izleyerek iş mantığını ve tasarım mantığını ayırmak amacıyla oluşturuldu. Yani JSP, çalışma sırasında teknik olarak tüm java kodlarıdır. Ancak soruyu cevaplamak için Tag Libraries genellikle JSP sayfalarına mantık (Java kodlarını kaldırarak) uygulamak için kullanılır.


8

Bir java web uygulamasında aşağıdaki şeyleri kullanırsak, java kodu JSP'nin ön planından kaldırılabilir.

  1. Web uygulaması için MVC mimarisini kullanma

  2. JSP Etiketlerini Kullan

    a. Standart Etiketler

    b. Özel Etiketler

  3. Anlatım Dili


8

JSP dosyalarında Java kodu nasıl önlenir?

İfade Dili'ne ( EL ) ek olarak JSTL gibi sekme kitaplığı etiketlerini kullanabilirsiniz . Ancak EL, JSP ile iyi çalışmaz. Bu yüzden JSP'yi tamamen bırakmak ve Facelets'i kullanmak daha iyidir .

Facelets , JSF ile karşılaştırıldığında JSF geliştiricilerine daha basit ve daha güçlü bir programlama modeli sağlayan , JSF (Java Sunucu Yüzleri) için tasarlanmış ilk JSP olmayan sayfa bildirim dilidir . Web uygulamalarının geliştirilmesi için JSP'de oluşan farklı sorunları çözer.

resim açıklamasını buraya girin

Kaynak


Bu cevabı kesinlikle ikinci olarak verdim. Facelets ile veya Facelets olmadan JSF. JSP'de gelişmenin 10 yıldan fazla bir süre önce sona erdiğini düşündüm. En son 2000 yılında JSP yazdım!
casgage

4

Komut Dosyalarını kullanmak çok eski bir yöntemdir ve Önerilmez. JSP sayfalarınızda doğrudan bir şey çıktısını almak istiyorsanız , JSTL ile birlikte İfade Dili'ni (EL) kullanın .

Ayrıca Velocity, Freemarker, Thymeleaf vb.

Ayrıca, görünüm katmanında iş mantığı yapmanın en iyi uygulama olmadığını, iş mantıklarınızı Hizmet katmanında gerçekleştirmeniz ve çıktı sonucunu bir Denetleyici aracılığıyla görünümlerinize iletmeniz gerektiğini unutmayın.


3

Hiçbir şey artık arkadaşım kullanılır, benim tavsiyem görünümü (css, html, javascript, vb) sunucudan ayırmaktır.

Benim durumumda, görünümleri Angular ile işleyen sistemlerimi yapıyorum ve gerekli tüm veriler sunucudan dinlenme hizmetleri kullanılarak getiriliyor.

İnan bana, bu tasarım şeklini değiştirecek


3

UI tasarımı için javascript çerçevesi gibi açısal omurga kullanın ve dinlenme api kullanarak veri getirin. Bu, java bağımlılığını kullanıcı arayüzünden tamamen kaldıracaktır.


3

JSP 2.0 "Etiket Dosyaları" adlı bir özelliğe sahiptir , etiketleri harici javakod olmadan yazabilirsiniz tld. Bir .tagdosya oluşturmanız ve içine koymanız gerekir WEB-INF\tags, etiketlerinizi paketlemek için bir dizin yapısı bile oluşturabilirsiniz.

Örneğin:

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

Gibi kullanın

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

Ayrıca, etiket gövdesini kolayca okuyabilirsiniz

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

Kullanın

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

Örnekler çok basit, ancak burada birçok karmaşık görev yapabilirsiniz. Başka etiketlerini kullanabilirsiniz düşünün: (örn JSTLgibi etiketler kontrol etti if/forEcah/chosengibi metin manipülasyon format/contains/uppercaseve hatta SQL etiketler select/update, örneğin her türlü parametrelerini geçirmek,) Hashmap, erişim session, request... senin etiketi, dosyadaki de.

Etiket Dosyası JSP dosyaları gibi sunucuyu değiştirirken yeniden başlatmanız gerekmediği için çok kolay geliştirilmiştir. Bu onları geliştirme için kolaylaştırır.

Struts 2 gibi çok sayıda iyi etiketi olan bir çerçeve kullansanız bile, kendi etiketlerinizin kodunuzu çok azaltabileceğini görebilirsiniz. Etiket parametrelerinizi payandalara aktarabilir ve bu şekilde çerçeve etiketinizi özelleştirebilirsiniz.

Etiketi yalnızca java'yı önlemek için değil, aynı zamanda HTML kodlarınızı da en aza indirmek için kullanabilirsiniz. Ben kendim HTML kodları gözden geçirmek ve kod yinelenen sayfalarıma başlar görmez etiketleri çok inşa etmeye çalışın.

(JSP kodunuzda java'yı kullansanız bile, umarım ki, bu kodu bir etikette kapsülleyebilirsiniz)


1

Birçok yanıtın dediği gibi, JSTL kullanın veya kendi özel etiketlerinizi oluşturun. İşte özel etiketler oluşturma hakkında iyi bir açıklama


1
  1. Değerlerinizi ve parametrelerinizi sunucu uygulaması sınıflarınızda yapın
  2. JSTL / Taglib kullanarak JSP'nizdeki bu değerleri ve parametreleri alın

Bu yaklaşımla ilgili iyi olan şey, kodunuzun HTML gibi bir kod olmasıdır!


0

JSTL etiketlerini EL ifadesi ile birlikte kullanarak bunu önleyebilirsiniz. Jsp sayfanıza şu şeyleri koyun:

<%@ 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" %>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.