Bagaimana cara menghindari kode Java dalam file JSP?

1673

Saya baru mengenal Java EE dan saya tahu itu seperti tiga baris berikut

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

adalah cara jadul dari pengkodean dan dalam JSP versi 2 terdapat metode untuk menghindari kode Java dalam file JSP. Bisakah seseorang tolong beri tahu saya alternatif JSP 2 baris, dan apa teknik ini disebut?

pembuat chmoelders
sumber
22
@ Koray Tugay, selama variabel counter dideklarasikan di suatu tempat sebelum penggunaannya, maka itu pasti berlaku ...
Sheldon R.
@SheldonR. Ini valid: <% = counter ++%> atau ini: <%! penghitung int = 0; int x = counter ++; %> tetapi tidak: <%! penghitung int = 0; counter ++; %>
Koray Tugay
@ KorayTugay, apa yang saya maksudkan adalah jika penghitung variabel dideklarasikan dalam blok skrip sebelumnya, seharusnya valid di blok selanjutnya. Tapi pada akhirnya, programmer J2EE hari ini harus menggunakan variabel EL daripada scriptlet, sih ...
Sheldon R.

Jawaban:

1972

Penggunaan scriptlets ( <% %>hal - hal itu) di JSP memang sangat tidak dianjurkan sejak lahirnya taglibs (seperti JSTL ) dan EL ( Bahasa Ekspresi ,${} hal hal itu) pada tahun 2001.

Kerugian utama dari scriptlets adalah:

  1. Dapat digunakan kembali : Anda tidak dapat menggunakan kembali scriptlets.
  2. Replaceability: Anda tidak bisa membuat scriptlets abstrak.
  3. Kemampuan OO: Anda tidak dapat menggunakan warisan / komposisi.
  4. Debuggability: jika scriptlet melempar pengecualian di tengah jalan, yang Anda dapatkan hanyalah halaman kosong.
  5. Testabilitas: skrip tidak dapat diuji unit.
  6. Maintainability: per saldo diperlukan lebih banyak waktu untuk mempertahankan logika kode yang dicampur / berantakan / digandakan.

Sun Oracle sendiri juga merekomendasikan dalam konvensi pengkodean JSP untuk menghindari penggunaan scriptlet kapan pun fungsionalitas yang sama dimungkinkan oleh (tag) kelas. Berikut beberapa kutipan relevansi:

Dari Spesifikasi JSP 1.2, sangat disarankan agar JSP Standard Tag Library (JSTL) digunakan dalam aplikasi web Anda untuk membantu mengurangi kebutuhan skrip JSP di halaman Anda. Halaman yang menggunakan JSTL secara umum lebih mudah dibaca dan dipelihara.

...

Jika memungkinkan, hindari skrip JSP setiap kali pustaka tag menyediakan fungsionalitas yang setara. Ini membuat halaman lebih mudah dibaca dan dipelihara, membantu memisahkan logika bisnis dari logika presentasi, dan akan membuat halaman Anda lebih mudah untuk berevolusi menjadi halaman gaya JSP 2.0 (dukungan Spesifikasi JSP 2.0 tetapi tidak menekankan penggunaan skriplet).

...

Dalam semangat mengadopsi pola desain model-view-controller (MVC) untuk mengurangi sambungan antara tingkat presentasi dari logika bisnis, skrip JSP tidak boleh digunakan untuk menulis logika bisnis. Sebaliknya, skrip JSP digunakan jika perlu untuk mengubah data (juga disebut "objek nilai") yang dikembalikan dari pemrosesan permintaan klien ke dalam format siap-klien yang tepat. Bahkan kemudian, ini akan lebih baik dilakukan dengan servlet pengontrol depan atau tag kustom.


Bagaimana cara mengganti scriptlets sepenuhnya tergantung pada tujuan tunggal dari kode / logika. Lebih sering kode ini ditempatkan di kelas Java yang layak:

  • Jika Anda ingin menjalankan kode Java yang sama pada setiap permintaan, kurang atau lebih terlepas dari halaman yang diminta, misalnya memeriksa apakah pengguna login, maka implementasikan filter dan tulis kode sesuai dengan doFilter()metode. Misalnya:

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

    Ketika dipetakan pada yang sesuai yang <url-pattern>mencakup halaman JSP yang menarik, maka Anda tidak perlu menyalin bagian yang sama dari kode keseluruhan halaman JSP.


  • Jika Anda ingin memohon beberapa kode Java untuk preprocess permintaan, misalnya preloading beberapa daftar dari database ke layar dalam beberapa tabel, jika perlu berdasarkan beberapa parameter query, kemudian menerapkan servlet dan menulis kode sesuai dalam doGet()metode. Misalnya:

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

    Cara ini menangani pengecualian lebih mudah. DB tidak diakses di tengah-tengah rendering JSP, tetapi jauh sebelum JSP ditampilkan. Anda masih memiliki kemungkinan untuk mengubah respons setiap kali akses DB melempar pengecualian. Dalam contoh di atas, default halaman error 500 akan ditampilkan yang Anda tetap dapat menyesuaikan oleh <error-page>di web.xml.


  • Jika Anda ingin memohon beberapa kode Java untuk postprocess permintaan, misalnya memproses formulir submit, kemudian menerapkan servlet dan menulis kode sesuai dalam doPost()metode. Misalnya:

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

    Dengan cara ini berurusan dengan tujuan halaman hasil yang berbeda lebih mudah: redisplaying bentuk dengan kesalahan validasi dalam kasus kesalahan (dalam contoh khusus ini Anda dapat menampilkan kembali menggunakan ${message}di EL ), atau hanya mengambil ke halaman target yang diinginkan dalam hal keberhasilan.


  • Jika Anda ingin memohon beberapa kode Java untuk mengontrol rencana eksekusi dan / atau tujuan permintaan dan respons, maka implementasikan servlet sesuai dengan Pola Pengontrol Depan MVC . Misalnya:

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

    Atau hanya mengadopsi kerangka kerja MVC seperti JSF , Spring MVC , Wicket , dll sehingga Anda hanya berakhir dengan halaman JSP / Facelets dan kelas JavaBean tanpa perlu servlet kustom.


  • Jika Anda ingin memanggil beberapa kode Java untuk mengontrol aliran di dalam halaman JSP, maka Anda perlu mengambil taglib kontrol aliran (yang ada) seperti inti JSTL . Misalnya menampilkan List<Product>dalam tabel:

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

    Dengan tag gaya XML yang cocok dengan semua HTML itu, kodenya lebih mudah dibaca (dan dengan demikian lebih baik dikelola) daripada sekelompok skrip dengan berbagai kurung buka dan tutup ( "Di mana sih kurung penutup ini milik?" ). Sebuah bantuan mudah adalah mengonfigurasi aplikasi web Anda untuk membuat pengecualian kapan pun scriptlets masih digunakan dengan menambahkan bagian berikut ke web.xml:

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

    Dalam Facelets , penerus JSP, yang merupakan bagian dari Java EE yang menyediakan kerangka kerja MVC JSF , sudah tidak mungkin menggunakan skriplet . Dengan cara ini Anda secara otomatis dipaksa untuk melakukan hal-hal "dengan cara yang benar".


  • Jika Anda ingin memohon beberapa kode Java untuk mengakses dan menampilkan data "backend" di dalam halaman JSP, maka Anda perlu menggunakan EL (Bahasa Ekspresi), ${}hal - hal itu. Misalnya menampilkan ulang nilai input yang dikirimkan:

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

    The ${param.foo}menampilkan hasil request.getParameter("foo").


  • Jika Anda ingin menjalankan beberapa kode Java utilitas langsung di halaman JSP (biasanya public staticmetode), maka Anda perlu mendefinisikannya sebagai fungsi EL. Ada fungsi taglib standar di JSTL, tetapi Anda juga dapat dengan mudah membuat fungsi sendiri . Berikut adalah contoh bagaimana JSTL fn:escapeXmlberguna untuk mencegah serangan XSS .

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

    Perhatikan bahwa sensitivitas XSS sama sekali tidak terkait dengan Java / JSP / JSTL / EL / apa pun, masalah ini perlu diperhitungkan di setiap aplikasi web yang Anda kembangkan. Masalah scriptlets adalah ia tidak menyediakan cara pencegahan bawaan, setidaknya tidak menggunakan Java API standar. Pengganti JSP Facelets telah secara implisit melepaskan HTML, jadi Anda tidak perlu khawatir tentang lubang XSS di Facelets.

Lihat juga:

BalusC
sumber
117
+1 Jawaban bagus. Tapi jangan menjadi dogmatis, kadang-kadang menggunakan skriplet memang ok, tapi itu harus menjadi pengecualian yang membuktikan aturan.
svachon
26
@svachon: Scriptlets berguna untuk prototyping / pengujian cepat. Sejauh yang saya tahu, hanya ada satu penggunaan scriptlet "sah" produksi, yaitu <% response.getWriter().flush(); %>antara </head>dan <body>untuk meningkatkan kinerja parsing halaman web di browser web. Tetapi penggunaan ini pada gilirannya benar-benar diabaikan ketika ukuran buffer output di sisi server rendah (1 ~ 2KB). Lihat juga artikel ini .
BalusC
5
@ BalusC Beberapa kali saya terjebak dengan kelas java yang tidak mengikuti pola pengambil / penyetel. IMHO itu adalah kasus di mana scripltet melakukan pekerjaan.
svachon
41
@svachon: Saya akan membungkus kelas-kelas itu dengan kelas javabean sendiri dan menggunakannya.
BalusC
31
Itu adalah jawaban yang cukup bagus, tetapi bagian doGet dan doPost menyesatkan. Metode-metode itu untuk menangani metode permintaan khusus (HEAD, GET dan POST) dan bukan untuk permintaan "preprocessing" atau "postprocessing"!
MetroidFan2002
225

Sebagai Safeguard: Nonaktifkan Scriptlets For Good

Saat pertanyaan lain sedang dibahas, Anda dapat dan selalu harus menonaktifkan scriptlets di web.xmldeskriptor aplikasi web Anda .

Saya akan selalu melakukan itu untuk mencegah pengembang menambahkan skriplet, terutama di perusahaan besar di mana Anda akan kehilangan gambaran cepat atau lambat. The web.xmlpengaturan terlihat seperti ini:

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
     <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>
Stefan Schubert-Peters
sumber
4
Apakah ini juga menonaktifkan komentar scriptlet ?: <%-- comment that i don't want in the final HTML --%>. Saya merasa berguna untuk menggunakan ini daripada komentar HTML.
David Lavender
16
@ MrSpoon melacak jawaban untuk Anda. Sesuai jawaban + komentar ini, ini menonaktifkan scriptlets <% %>, ekspresi scriptlet <%! %>, dan deklarasi scriptlet <%= %>. Itu berarti arahan <%@ %>dan komentar <%-- --%>tetap diaktifkan dan dapat digunakan, sehingga Anda masih dapat melakukan komentar dan memasukkan.
Martin Carney
3
Menonaktifkan arahan scriptlet akan mengerikan - ruang kosong trim sangat berharga untuk berinteraksi dengan sistem lama yang panik dengan spasi tambahan ekstra.
corsiKa
108

JSTL menawarkan tag untuk kondisional, loop, set, get, dll. Misalnya:

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

JSTL bekerja dengan atribut permintaan - mereka paling sering ditetapkan dalam permintaan oleh Servlet, yang meneruskan ke JSP.

Bozho
sumber
2
Mengapa Anda mengatakan JSTL berfungsi dengan atribut permintaan? Mereka dapat bekerja dengan atribut dalam ruang lingkup apa pun, bukan?
Koray Tugay
60

Saya tidak yakin apakah ini benar.

Anda harus membaca sesuatu tentang MVC. Spring MVC & Struts 2 adalah dua solusi paling umum.

tzim
sumber
29
MVC dapat diimplementasikan dengan servlets / jsp menggunakan banyak teknik di atas tanpa Spring atau Struts.
stepanian
18
Bagaimana cara menjawab pertanyaan?
xyz
54

Anda dapat menggunakan tag JSTL bersama-sama dengan ekspresi EL untuk menghindari pencampuran kode Java dan 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>
Behrang Saeedzadeh
sumber
34

Ada juga kerangka kerja berbasis komponen seperti Wicket yang menghasilkan banyak HTML untuk Anda. Tag yang berakhir di HTML sangat mendasar dan hampir tidak ada logika yang tercampur. Hasilnya hampir seperti halaman HTML kosong dengan elemen HTML biasa. Kelemahannya adalah bahwa ada banyak komponen dalam API Wicket untuk dipelajari dan beberapa hal mungkin sulit dicapai di bawah kendala tersebut.

tsand
sumber
33

Dalam pola Arsitektur MVC, JSP mewakili lapisan Lihat. Menanamkan kode java di JSP dianggap praktik yang buruk. Anda dapat menggunakan JSTL , freeMarker , kecepatan dengan JSP sebagai "mesin template". Penyedia data untuk tag tersebut tergantung pada kerangka kerja yang Anda hadapi. Struts 2dan webworksebagai implementasi untuk Pola MVC menggunakan OGNL "teknik yang sangat menarik untuk mengekspos Properti Kacang ke JSP".

Sami Jmii
sumber
27

Pengalaman menunjukkan bahwa JSP memiliki beberapa kekurangan, salah satunya sulit untuk menghindari pencampuran markup dengan kode aktual.

Jika Anda bisa, maka pertimbangkan untuk menggunakan teknologi khusus untuk apa yang perlu Anda lakukan. Di Java EE 6 ada JSF 2.0, yang menyediakan banyak fitur bagus termasuk menempelkan kacang Jawa bersama-sama dengan halaman JSF melalui #{bean.method(argument)}pendekatan.

Thorbjørn Ravn Andersen
sumber
3
Jawaban lama tapi saya tidak bisa menolak untuk mengatakan bahwa JSF adalah salah satu penemuan paling mengerikan di ruang Jawa. Cobalah untuk membuat satu tautan (seperti HTTP GET) dan Anda akan mengerti alasannya.
Alex
@Alex tapi masih lebih baik. Jangan ragu untuk merekomendasikan sesuatu yang lebih baik.
Thorbjørn Ravn Andersen
26

jika Anda hanya ingin menghindari kelemahan Java coding di JSP Anda dapat melakukannya bahkan dengan skrip. Cukup ikuti beberapa disiplin untuk memiliki Java minimal di JSP dan hampir tidak ada perhitungan dan logika di halaman 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>
dipu
sumber
26

Belajarlah untuk menyesuaikan dan menulis tag Anda sendiri menggunakan JSTL

Perhatikan bahwa EL adalah EviL (pengecualian runtime, refactoring).
Wicket mungkin jahat juga (kinerja, sulit untuk aplikasi kecil atau tingkat tampilan sederhana)

Contoh dari java2s ,

Ini harus ditambahkan ke web.xml aplikasi web

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

buat File: java2s.tld di / 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>

kompilasi kode berikut ke dalam WEB-INF \ class \ 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;
    }
}

Mulai server dan muat bodyContent.jsp di browser

<%@ 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>
tomasb
sumber
meskipun dapat digunakan kembali komponen baik-baik saja menargetkan beberapa bidang
tomasb
25

Wicket juga merupakan alternatif yang sepenuhnya memisahkan java dari html, sehingga seorang perancang dan pemrogram dapat bekerja bersama dan pada set kode yang berbeda dengan sedikit pemahaman satu sama lain.

Lihatlah Wicket.

msj121
sumber
23

Anda mengajukan pertanyaan yang bagus dan meskipun Anda mendapat jawaban yang baik, saya sarankan Anda menyingkirkan JSP. Ini adalah teknologi usang yang pada akhirnya akan mati. Gunakan pendekatan modern, seperti mesin templat. Anda akan memiliki pemisahan bisnis dan lapisan presentasi yang sangat jelas, dan tentunya tidak ada kode Java dalam templat, sehingga Anda dapat membuat templat langsung dari perangkat lunak pengedit presentasi web, dalam banyak kasus meningkatkan WYSIWYG.

Dan tentu saja menjauh dari filter dan pemrosesan sebelum dan sesudah, jika tidak, Anda mungkin menghadapi kesulitan dukungan / debugging karena Anda selalu tidak tahu dari mana variabel mendapatkan nilai.

Dmitriy R
sumber
9
JSP sendiri adalah mesin templat
WarFox
1
-1 - Ada banyak alasan yang sepenuhnya valid untuk menggunakan filter, pra-prosesor, dan pasca-prosesor. Ya, Anda bisa berakhir dengan nilai-nilai yang tampak misterius, tetapi tidak jika Anda memahami arsitektur Anda.
RustyTheBoyRobot
21

untuk menghindari kode java dalam file JSP java sekarang menyediakan perpustakaan tag seperti JSTL juga java telah datang dengan JSF di mana Anda dapat menulis semua struktur pemrograman dalam bentuk tag

mahesh
sumber
21

Tidak peduli berapa banyak Anda mencoba untuk menghindari, ketika Anda bekerja dengan pengembang lain, beberapa dari mereka masih akan lebih suka scriptlet dan kemudian memasukkan kode jahat ke dalam proyek. Oleh karena itu, menyiapkan proyek pada tanda pertama sangat penting jika Anda benar-benar ingin mengurangi kode skrip. Ada beberapa teknik untuk mengatasi hal ini (termasuk beberapa kerangka kerja yang disebutkan lainnya). Namun, jika Anda lebih suka cara JSP murni, maka gunakan file tag JSTL. Yang menyenangkan tentang ini adalah Anda juga dapat mengatur halaman master untuk proyek Anda, sehingga halaman lain dapat mewarisi halaman master

Buat halaman master yang disebut base.tag di bawah WEB-INF / tag Anda dengan konten berikut

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

Di halaman mater ini, saya membuat sebuah fragmen yang disebut "title", sehingga di halaman child, saya bisa memasukkan lebih banyak kode ke tempat halaman master ini. Selain itu, tag <jsp:doBody/>akan diganti oleh konten halaman anak

Buat halaman anak (child.jsp) di folder Konten Web Anda:

<%@ 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>digunakan untuk menentukan halaman master yang ingin Anda gunakan (yang base.tag saat ini). Semua konten di dalam tag di <jsp:body>sini akan menggantikan <jsp:doBody/>pada halaman master Anda. Halaman anak Anda juga dapat menyertakan tag lib dan Anda dapat menggunakannya secara normal seperti yang disebutkan lainnya. Namun, jika Anda menggunakan kode skrip apa pun di sini ( <%= request.getParameter("name") %>...) dan mencoba menjalankan halaman ini, Anda akan mendapatkan JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Karena itu, tidak mungkin orang lain bisa memasukkan kode jahat ke dalam file jsp

Memanggil halaman ini dari pengontrol Anda:

Anda dapat dengan mudah memanggil file child.jsp dari controller Anda. Ini juga berfungsi baik dengan kerangka struts

Thai Tran
sumber
"Tidak peduli berapa banyak Anda mencoba untuk menghindari, ketika Anda bekerja dengan pengembang lain, beberapa dari mereka masih akan lebih suka scriptlet dan kemudian memasukkan kode jahat ke dalam proyek." Lihat "Sebagai Safeguard: Nonaktifkan Scriptlets For Good" jawabannya.
Lluis Martinez
19

Gunakan JSTL Tag librariesdi JSP, itu akan bekerja dengan sempurna.

Chandra Sekhar
sumber
18

Cukup gunakan tag JSTL dan ekspresi EL.

tanglei
sumber
17

Jika seseorang benar-benar menentang pemrograman dalam lebih dari satu bahasa , saya sarankan GWT, secara teoritis Anda dapat menghindari semua elemen JS dan HTML, karena Google Toolkit mengubah semua klien dan kode bersama ke JS, Anda tidak akan memiliki masalah dengan mereka, jadi Anda memiliki layanan web tanpa coding dalam bahasa lain. Bahkan Anda dapat menggunakan beberapa CSS default dari suatu tempat karena diberikan oleh ekstensi (smartGWT atau Vaadin). Anda tidak perlu mempelajari lusinan anotasi.

Tentu saja jika Anda mau, Anda dapat meretas diri Anda ke kedalaman kode dan menyuntikkan JS dan memperkaya halaman HTML Anda, tetapi Anda benar-benar dapat menghindarinya jika mau, dan hasilnya akan bagus seperti yang tertulis dalam kerangka kerja lainnya. Saya katakan patut dicoba, dan GWT dasar didokumentasikan dengan baik.

Dan tentu saja banyak programmer sesama dengan ini menggambarkan atau merekomendasikan beberapa solusi lain. GWT adalah untuk orang-orang yang benar-benar tidak ingin berurusan dengan komponen web atau untuk meminimalkannya.

CsBalazsHungary
sumber
1
Tidak benar-benar menjawab pertanyaan OP.
Evan Donovan
1
@ EvanDonovan baik, praktis itu memang memberikan jawaban. Anda tidak perlu dipusingkan dengan kode Java yang bercampur dengan bahasa lain. Saya akui menggunakan Java untuk pengkodean, tetapi akan diterjemahkan ke JS tanpa panggilan Java. Tapi ruang lingkup pertanyaannya adalah bagaimana menghindari kekacauan JSP klasik. Dan teknologi GWT memecahkan itu. Saya menambahkan jawaban ini karena tidak ada yang menyebutkannya, tetapi relevan karena merupakan alternatif untuk JSP. Saya tidak ingin menjawab seluruh cakupan pertanyaan, tetapi untuk menambahkan informasi yang berharga bagi orang-orang yang mencari alternatif.
CsBalazsHungary
16

Ide bagus dari dunia Python adalah bahasa atribut Templat ; TAL diperkenalkan oleh Zope (oleh karena itu disebut "Zope Page Templates", ZPT) dan merupakan standar, dengan implementasi dalam PHP, XSLT dan Java juga (Saya telah menggunakan inkarnasi Python / Zope dan PHP). Di kelas bahasa templating ini, satu contoh di atas dapat terlihat seperti ini:

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

Kode tersebut terlihat seperti HTML biasa (atau XHTML) ditambah beberapa atribut khusus dalam ruang nama XML; itu dapat dilihat dengan browser dan aman di-tweak oleh seorang desainer. Ada dukungan untuk makro dan untuk i18n juga:

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

Jika terjemahan konten tersedia, mereka digunakan.

Saya tidak tahu banyak tentang implementasi Java .

Tobias
sumber
1
JSP sejak Desember 2009 telah digantikan oleh Facelet yang mendukung hal ini. Facelet juga berbasis XML. Lihat juga antara lain bab Facelets di Java EE 6 tutorial dan ui:xxxtag di Facelts VDL .
BalusC
Saya tidak tahu Facelet dengan baik, tapi IIRC itu semua tentang menulis kelas yang mengimplementasikan elemen XML kustom. Cara TAL / ZPT adalah memiliki templat yang berisi true (X) HTML dengan atribut khusus yang mengisi atau mengganti elemen asli; dengan demikian, Anda dapat melihat template yang berfungsi dan melihat prototipe dengan konten dummy yang bagus. Saya tidak yakin Facelets mengizinkan untuk mengubah elemen HTML asli (tanpa ruang nama tambahan) menggunakan atribut khusus.
Tobias
Saya baru saja melihat hal-hal Facelet ini. Ini berisi semua jenis fasilitas validasi dll. Dan dengan demikian mengikuti filosofi yang sama sekali berbeda dari TAL. Cara TAL adalah, "Jauhkan logika dari template sebersih mungkin; buat semua hal rumit dilakukan oleh pengontrol yang memberinya makan." Anda tidak akan pernah memberikan templat Facelet kepada seorang desainer untuk membuatnya mengubahnya; itu tidak mungkin. Mengenai konten yang dihasilkan - itu seperti menggunakan tal:replace="structure (expression)"atribut setiap saat.
Tobias
14

Tentu, ganti <%! counter++; %> dengan arsitektur acara produsen-konsumen, di mana lapisan bisnis diberitahu tentang perlunya menambah penghitung, bereaksi sesuai, dan memberi tahu presenter sehingga mereka memperbarui pandangan. Sejumlah transaksi basis data terlibat, karena di masa depan kita perlu mengetahui nilai baru dan lama dari penghitung, yang telah menambahnya dan dengan tujuan apa yang dipikirkan. Jelas serialisasi terlibat, karena lapisan sepenuhnya dipisahkan. Anda akan dapat menambah penghitung Anda di atas RMI, IIOP, SOAP. Tetapi hanya HTML yang diperlukan, yang tidak Anda terapkan, karena ini adalah kasus biasa. Tujuan baru Anda adalah untuk mencapai peningkatan 250 detik di server E7, 64GB RAM Anda yang baru mengkilap.

Saya memiliki lebih dari 20 tahun dalam pemrograman, sebagian besar proyek gagal sebelum sextet: Reusability Replaceability OO-kemampuan Debuggability Testability Maintainability bahkan diperlukan. Proyek lain, dijalankan oleh orang-orang yang hanya peduli dengan fungsionalitas, sangat sukses. Juga, struktur objek yang kaku, yang diterapkan terlalu dini dalam proyek, membuat kode tidak dapat disesuaikan dengan perubahan drastis dalam spesifikasi (alias gesit).

Jadi saya menganggap sebagai menunda kegiatan mendefinisikan "lapisan" atau struktur data yang berlebihan baik di awal proyek atau ketika tidak secara khusus diperlukan.  

Razvan
sumber
11

Secara teknis, JSP semua dikonversi ke Servlets selama runtime . JSP awalnya dibuat untuk tujuan decoupling logika bisnis dan logika desain, mengikuti pola MVC. Jadi JSP secara teknis semua kode java selama runtime. Tetapi untuk menjawab pertanyaan, Tag Libraries biasanya digunakan untuk menerapkan logika (menghapus kode Java) ke halaman JSP.

mel3kings
sumber
8

Jika kita menggunakan hal-hal berikut dalam aplikasi web java, kode java dapat dihilangkan dari latar depan JSP.

  1. Gunakan arsitektur MVC untuk aplikasi web

  2. Gunakan Tag JSP

    Sebuah. Tag Standar

    b. Tag Kustom

  3. Bahasa Ekspresi

Ajay Takur
sumber
8

Bagaimana cara menghindari kode Java dalam file JSP?

Anda dapat menggunakan tag pustaka tab seperti JSTL di samping Bahasa Ekspresi ( EL ). Tetapi EL tidak bekerja dengan baik dengan JSP. Jadi mungkin lebih baik untuk melepaskan JSP sepenuhnya dan menggunakan Facelet .

Facelets adalah bahasa deklarasi halaman non JSP pertama yang dirancang untuk JSF (Java Server Faces) yang memberikan model pemrograman yang lebih sederhana dan lebih kuat untuk pengembang JSF dibandingkan dengan JSP. Ini mengatasi berbagai masalah yang terjadi di JSP untuk pengembangan aplikasi web.

masukkan deskripsi gambar di sini

Sumber

Yster
sumber
Saya pasti yang kedua menanggapi ini. JSF dengan atau tanpa Facelet. Saya pikir pengembangan di JSP sebagian besar telah berhenti lebih dari 10 tahun yang lalu. Saya terakhir menulis JSP pada tahun 2000!
casgage
4

Menggunakan Scriptlets adalah cara yang sangat lama dan Tidak disarankan. Jika Anda ingin langsung menampilkan sesuatu di halaman JSP Anda cukup gunakan Bahasa Ekspresi (EL) bersama dengan JSTL .

Ada juga pilihan lain seperti menggunakan mesin templating seperti Velocity, Freemarker, Thymeleaf dll. Tetapi menggunakan JSP polos dengan EL dan JSTL melayani tujuan saya sebagian besar waktu dan juga tampaknya paling sederhana untuk pemula.

Juga, perhatikan bahwa ini bukan praktik terbaik untuk melakukan logika bisnis di lapisan tampilan, Anda harus melakukan logika bisnis Anda di lapisan Layanan, dan meneruskan hasil keluaran ke tampilan Anda melalui Pengontrol.

dan.911
sumber
3

Tidak ada yang digunakan lagi teman saya, saran saya adalah untuk memisahkan pandangan (css, html, javascript, dll) dari server.

Dalam kasus saya, saya melakukan sistem saya menangani tampilan dengan Angular dan setiap data yang dibutuhkan dibawa dari server menggunakan layanan lainnya.

Percayalah, ini akan mengubah cara Anda mendesain

Eduardo
sumber
3

Gunakan backbone, kerangka javascript seperti sudut untuk desain UI dan ambil data menggunakan api sisanya. Ini akan menghapus ketergantungan java dari UI sepenuhnya.

Sumesh TG
sumber
3

JSP 2.0 memiliki fitur yang disebut "Tag Files" , Anda dapat menulis tag tanpa javakode eksternal dan tld. Anda perlu membuat .tagfile dan memasukkannya ke dalam WEB-INF\tagsAnda bahkan dapat membuat struktur direktori untuk mengemas tag Anda.

Sebagai contoh:

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

Gunakan seperti

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

Anda juga dapat membaca badan tag dengan mudah

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

Gunakan

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

Sampel sangat sederhana tetapi Anda dapat melakukan banyak tugas rumit di sini. Silakan mempertimbangkan Anda dapat menggunakan tag lain (misalnya: JSTLyang telah mengendalikan tag seperti if/forEcah/chosenmanipulasi teks seperti format/contains/uppercaseatau bahkan tag SQL select/update), lulus semua parameter jenis, misalnya Hashmap, akses session, request, ... dalam file tag Anda juga.

File Tag sangat mudah dikembangkan karena Anda tidak perlu me-restart server saat mengubahnya, seperti file JSP. Ini membuatnya mudah untuk dikembangkan.

Bahkan jika Anda menggunakan kerangka kerja seperti Struts 2, yang memiliki banyak tag bagus, Anda mungkin menemukan bahwa memiliki tag Anda sendiri dapat mengurangi banyak kode Anda. Anda dapat meneruskan parameter tag Anda ke struts dan dengan cara ini menyesuaikan tag kerangka Anda.

Anda dapat menggunakan tag tidak hanya untuk menghindari java tetapi juga meminimalkan kode HTML Anda. Saya sendiri mencoba meninjau kode HTML dan banyak membuat tag segera setelah melihat duplikat kode mulai di halaman saya.

(Bahkan jika Anda akhirnya menggunakan java dalam kode JSP Anda, yang saya harap tidak, Anda dapat merangkum kode itu dalam tag)

Alireza Fattahi
sumber
1

Seperti yang banyak jawaban katakan, gunakan JSTL atau buat tag khusus Anda sendiri. Berikut ini penjelasan yang bagus tentang membuat tag khusus

Code_Mode
sumber
1
  1. Buat nilai dan parameter Anda di dalam kelas servlet Anda
  2. Ambil nilai-nilai dan parameter dalam JSP Anda menggunakan JSTL / Taglib

Hal yang baik tentang pendekatan ini adalah bahwa kode Anda juga merupakan kode seperti HTML!

Mehdi
sumber
0

Dengan menggunakan tag JSTL bersama dengan ekspresi EL Anda dapat menghindari ini. Letakkan hal-hal berikut di halaman jsp Anda:

<%@ 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" %>
bhanwar rathore
sumber