Làm cách nào để tránh mã Java trong tệp JSP, sử dụng JSP 2?

Jul 05 2010

Tôi mới làm quen với Java EE và tôi biết rằng ba dòng sau

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

là một cách viết mã cũ và trong JSP phiên bản 2 có một phương pháp để tránh mã Java trong các tệp JSP. JSP 2 dòng thay thế là gì và kỹ thuật này được gọi là gì?

Trả lời

1987 BalusC Jul 05 2010 at 21:19

Việc sử dụng scriptlet (những <% %>thứ đó) trong JSP thực sự không được khuyến khích kể từ khi ra đời của taglibs (như JSTL ) và EL ( Expression Language , những ${}thứ đó) vào năm 2001.

Những nhược điểm chính của scriptlets là:

  1. Khả năng tái sử dụng : bạn không thể sử dụng lại các script.
  2. Khả năng thay thế: bạn không thể làm cho các script trở nên trừu tượng.
  3. Khả năng OO: bạn không thể sử dụng tính kế thừa / cấu tạo.
  4. Khả năng gỡ lỗi: nếu scriptlet ném một ngoại lệ giữa chừng, tất cả những gì bạn nhận được là một trang trống.
  5. Khả năng kiểm tra : các tập lệnh không thể kiểm tra đơn vị.
  6. Khả năng bảo trì: mỗi saldo cần thêm thời gian để duy trì logic mã hỗn hợp / lộn xộn / trùng lặp.

Bản thân Sun Oracle cũng khuyến nghị trong quy ước mã hóa JSP tránh sử dụng các script bất cứ khi nào các lớp (tag) có cùng chức năng. Dưới đây là một số trích dẫn về mức độ liên quan:

Từ Đặc điểm kỹ thuật JSP 1.2, chúng tôi khuyên bạn nên sử dụng Thư viện thẻ chuẩn JSP (JSTL) trong ứng dụng web của bạn để giúp giảm nhu cầu về tập lệnh JSP trong các trang của bạn. Nhìn chung, các trang sử dụng JSTL dễ đọc và dễ bảo trì hơn.

...

Nếu có thể, hãy tránh các tập lệnh JSP bất cứ khi nào các thư viện thẻ cung cấp chức năng tương đương. Điều này làm cho các trang dễ đọc và dễ bảo trì hơn, giúp tách logic nghiệp vụ khỏi logic trình bày và sẽ làm cho các trang của bạn dễ dàng phát triển thành các trang kiểu JSP 2.0 (Đặc tả JSP 2.0 hỗ trợ nhưng không nhấn mạnh việc sử dụng script).

...

Trên tinh thần áp dụng mẫu thiết kế model-view-controller (MVC) để giảm sự ghép nối giữa các tầng trình bày khỏi logic nghiệp vụ, không nên sử dụng các kịch bản lệnh JSP để viết logic nghiệp vụ. Thay vào đó, các tập lệnh JSP được sử dụng nếu cần thiết để chuyển đổi dữ liệu (còn được gọi là "các đối tượng giá trị") được trả về từ việc xử lý các yêu cầu của khách hàng thành một định dạng sẵn sàng cho khách hàng thích hợp. Thậm chí sau đó, điều này sẽ được thực hiện tốt hơn với một servlet bộ điều khiển phía trước hoặc một thẻ tùy chỉnh.


Cách thay thế các script hoàn toàn phụ thuộc vào mục đích duy nhất của mã / logic. Thông thường, mã này được đặt trong một lớp Java đầy đủ:

  • Nếu bạn muốn gọi cùng một mã Java trên mọi yêu cầu, ít hơn hoặc nhiều hơn bất kể trang được yêu cầu, ví dụ: kiểm tra xem người dùng đã đăng nhập chưa, sau đó triển khai bộ lọc và viết mã tương ứng trong doFilter()phương thức. Ví dụ:

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

    Khi được ánh xạ trên một trang thích hợp <url-pattern>bao gồm các trang JSP quan tâm, thì bạn không cần phải sao chép cùng một đoạn mã trên các trang JSP tổng thể.


  • Nếu bạn muốn gọi một số mã Java để xử lý trước một yêu cầu, ví dụ như tải trước một số danh sách từ cơ sở dữ liệu để hiển thị trong một số bảng, nếu cần dựa trên một số tham số truy vấn, sau đó triển khai một servlet và viết mã tương ứng trong doGet()phương thức. Ví dụ:

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

    Cách này giải quyết các trường hợp ngoại lệ dễ dàng hơn. DB không được truy cập trong quá trình hiển thị JSP, nhưng trước khi JSP được hiển thị. Bạn vẫn có khả năng thay đổi phản hồi bất cứ khi nào quyền truy cập DB ném ra một ngoại lệ. Trong ví dụ trên, mặc định trang lỗi 500 sẽ được hiển thị mà bạn anyway có thể tùy chỉnh bằng một <error-page>trong web.xml.


  • Nếu bạn muốn gọi một số mã Java để xử lý sau một yêu cầu, ví dụ: xử lý một biểu mẫu gửi, sau đó triển khai một servlet và viết mã tương ứng trong doPost()phương thức. Ví dụ:

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

    Bằng cách này đối phó với các điểm đến trang kết quả khác nhau là dễ dàng hơn: redisplaying mẫu với lỗi xác nhận trong trường hợp một lỗi (trong ví dụ cụ này bạn có thể hiển thị lại nó bằng cách sử ${message}trong EL ), hoặc chỉ dùng để trang mục tiêu mong muốn trong trường hợp thành công.


  • Nếu bạn muốn gọi một số mã Java để kiểm soát kế hoạch thực thi và / hoặc đích của yêu cầu và phản hồi, thì hãy triển khai một servlet theo Mẫu điều khiển phía trước của MVC . Ví dụ:

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

    Hoặc chỉ cần áp dụng một khung công tác MVC như JSF , Spring MVC , Wicket , v.v. để bạn kết thúc chỉ với một trang JSP / Khuôn mặt và một lớp JavaBean mà không cần đến một servlet tùy chỉnh.


  • Nếu bạn muốn gọi một số mã Java để điều khiển luồng bên trong trang JSP, thì bạn cần lấy một thẻ taglib điều khiển luồng (hiện có) như lõi JSTL . Ví dụ: hiển thị List<Product>trong một bảng:

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

    Với các thẻ kiểu XML vừa khít với tất cả HTML đó, mã có thể đọc được tốt hơn (và do đó có thể bảo trì tốt hơn) so với một loạt các script với các dấu ngoặc nhọn mở và đóng khác nhau ( "Cái quái gì mà dấu ngoặc nhọn này thuộc về?" ). Một sự trợ giúp dễ dàng là định cấu hình ứng dụng web của bạn để đưa ra một ngoại lệ bất cứ khi nào script vẫn được sử dụng bằng cách thêm đoạn sau vào web.xml:

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

    Trong Facelet , phiên bản kế thừa của JSP, là một phần của khuôn khổ MVC được cung cấp bởi Java EE JSF , không thể sử dụng script . Bằng cách này, bạn sẽ tự động bị buộc phải làm mọi thứ "đúng cách".


  • Nếu bạn muốn gọi một số mã Java để truy cập và hiển thị dữ liệu "phụ trợ" bên trong trang JSP, thì bạn cần sử dụng EL (Ngôn ngữ biểu thức), những ${}thứ đó. Ví dụ: hiển thị lại các giá trị đầu vào đã gửi:

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

    Các ${param.foo}hiển thị kết quả của request.getParameter("foo").


  • Nếu bạn muốn gọi một số mã Java tiện ích trực tiếp trong trang JSP (thường là public staticcác phương thức), thì bạn cần xác định chúng dưới dạng các hàm EL. Có một taglib các hàm tiêu chuẩn trong JSTL, nhưng bạn cũng có thể dễ dàng tự tạo các hàm . Đây là một ví dụ về cách JSTL fn:escapeXmlhữu ích để ngăn chặn các cuộc tấn công XSS .

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

    Lưu ý rằng độ nhạy XSS không liên quan cụ thể đến Java / JSP / JSTL / EL / bất cứ điều gì, vấn đề này cần được tính đến trong mọi ứng dụng web bạn phát triển. Vấn đề của scriptlets là nó không cung cấp cách ngăn chặn nội trang, ít nhất là không sử dụng API Java tiêu chuẩn. Khuôn mặt kế nhiệm của JSP đã có tính năng thoát HTML ngầm, vì vậy bạn không cần phải lo lắng về các lỗ hổng XSS trong Khoen.

Xem thêm:

  • Sự khác biệt giữa JSP, Servlet và JSF là gì?
  • Servlet, ServletContext, HttpSession và HttpServletRequest / Response hoạt động như thế nào?
  • Ví dụ về MVC cơ bản với JSP, Servlet và JDBC
  • Các mẫu thiết kế trong các ứng dụng web Java
  • Các tính năng ẩn của JSP / Servlet
228 StefanSchubert-Peters Aug 15 2011 at 04:59

Như một biện pháp bảo vệ: Vô hiệu hóa Scriptlets vì điều tốt

Như một câu hỏi khác đang thảo luận, bạn có thể và luôn luôn nên vô hiệu hóa script trong bộ web.xmlmô tả ứng dụng web của mình .

Tôi sẽ luôn làm điều đó để ngăn chặn bất kỳ nhà phát triển nào thêm script, đặc biệt là trong các công ty lớn hơn, nơi bạn sớm hay muộn sẽ mất tổng quan. Các web.xmlcài đặt trông như thế này:

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
     <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>
109 Bozho Jul 05 2010 at 14:28

JSTL cung cấp các thẻ cho điều kiện, vòng lặp, bộ, được, v.v. Ví dụ:

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

JSTL hoạt động với các thuộc tính yêu cầu - chúng thường được đặt trong yêu cầu bởi một Servlet, chuyển tiếp đến JSP.

61 tzim Jul 05 2010 at 14:29

Tôi không chắc liệu tôi có hiểu chính xác không.

Bạn nên đọc vài điều về MVC. Spring MVC & Struts 2 là hai giải pháp phổ biến nhất.

54 βξhrαng Jul 05 2010 at 15:45

Bạn có thể sử dụng các thẻ JSTL cùng với các biểu thức EL để tránh trộn lẫn mã Java và 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>
34 tsand Mar 23 2011 at 01:24

Ngoài ra còn có các khuôn khổ dựa trên thành phần, chẳng hạn như Wicket , tạo ra rất nhiều HTML cho bạn.

Các thẻ kết thúc trong HTML cực kỳ cơ bản và hầu như không có logic nào bị trộn lẫn vào. Kết quả là các trang HTML gần như trống rỗng với các phần tử HTML điển hình. Nhược điểm là có rất nhiều thành phần trong API Wicket để tìm hiểu và một số thứ có thể khó đạt được dưới những ràng buộc đó.

33 SamiJmii Feb 04 2011 at 17:41

Trong mô hình kiến ​​trúc MVC, các JSP đại diện cho lớp xem. Nhúng mã Java trong JSP được coi là một thực hành không tốt.

Bạn có thể sử dụng JSTL , Freemarker , và vận tốc với JSP như là một "mẫu động cơ".

Nhà cung cấp dữ liệu cho các thẻ đó phụ thuộc vào các khuôn khổ mà bạn đang xử lý. Struts 2 và WebWork như một triển khai cho mẫu MVC sử dụng OGNL "kỹ thuật rất thú vị để hiển thị các thuộc tính Beans cho JSP".

27 ThorbjørnRavnAndersen Jul 05 2010 at 15:30

Kinh nghiệm cho thấy JSP có một số thiếu sót, một trong số đó là khó tránh khỏi việc trộn lẫn đánh dấu với mã thực tế.

Nếu bạn có thể, hãy xem xét sử dụng một công nghệ chuyên biệt cho những gì bạn cần làm. Trong Java EE 6 có JSF 2.0, cung cấp rất nhiều tính năng hay bao gồm việc dán các hạt Java lại với các trang JSF thông qua #{bean.method(argument)}cách tiếp cận.

26 dipu May 11 2012 at 23:45

Nếu bạn chỉ muốn tránh những hạn chế của mã hóa Java trong JSP, bạn có thể làm như vậy ngay cả với các tập lệnh. Chỉ cần tuân theo một số kỷ luật để có Java tối thiểu trong JSP và hầu như không có tính toán và logic trong trang 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 forwarding, 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 tomasb Aug 18 2011 at 03:02

Học cách tùy chỉnh và viết các thẻ của riêng bạn bằng JSTL

Lưu ý rằng EL là EviL (ngoại lệ thời gian chạy và tái cấu trúc).

Wicket cũng có thể xấu (hiệu suất và khó khăn đối với các ứng dụng nhỏ hoặc cấp chế độ xem đơn giản).

Ví dụ từ java2s

Điều này phải được thêm vào web.xml của ứng dụng web

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

Tạo tệp java2s.tld trong / 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>

Biên dịch mã sau thành 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;
    }
}

Khởi động máy chủ và tải tệp bodyContent.jsp trong trình duyệt:

<%@ 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>
25 msj121 May 21 2011 at 03:42

Wicket cũng là một giải pháp thay thế hoàn toàn tách biệt Java khỏi HTML, vì vậy một nhà thiết kế và lập trình viên có thể làm việc cùng nhau và trên các bộ mã khác nhau mà không cần hiểu nhiều về nhau.

Hãy nhìn Wicket.

23 DmitriyR Jul 13 2011 at 03:20

Bạn đã đưa ra một câu hỏi hay và mặc dù bạn nhận được câu trả lời tốt, nhưng tôi khuyên bạn nên loại bỏ JSP. Đó là công nghệ lạc hậu và cuối cùng sẽ chết. Sử dụng một cách tiếp cận hiện đại, như công cụ mẫu. Bạn sẽ có sự phân tách rất rõ ràng giữa các lớp nghiệp vụ và bản trình bày, và chắc chắn không có mã Java trong các mẫu, vì vậy bạn có thể tạo các mẫu trực tiếp từ phần mềm chỉnh sửa bản trình bày web, trong hầu hết các trường hợp, sử dụng WYSIWYG.

Và chắc chắn tránh xa các bộ lọc và xử lý trước và sau, nếu không bạn có thể gặp khó khăn trong việc hỗ trợ / gỡ lỗi vì bạn luôn không biết biến nhận giá trị ở đâu.

21 ThaiTran Jan 27 2013 at 01:07

Cho dù bạn cố gắng tránh bao nhiêu, khi bạn làm việc với các nhà phát triển khác, một số người trong số họ vẫn sẽ thích scriptlet hơn và sau đó chèn mã độc vào dự án. Vì vậy, thiết lập dự án ở dấu hiệu đầu tiên là rất quan trọng nếu bạn thực sự muốn giảm mã scriptlet. Có một số kỹ thuật để vượt qua điều này (bao gồm một số khuôn khổ đã được đề cập khác). Tuy nhiên, nếu bạn thích cách JSP thuần túy, thì hãy sử dụng tệp thẻ JSTL. Điều thú vị về điều này là bạn cũng có thể thiết lập các trang chính cho dự án của mình, vì vậy các trang khác có thể kế thừa các trang chính

Tạo một trang chính được gọi là base.tag dưới WEB-INF / thẻ của bạn với nội dung sau

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

Trên trang cũ này, tôi đã tạo một phân đoạn được gọi là "tiêu đề", để trong trang con, tôi có thể chèn thêm mã vào vị trí này của trang chính. Ngoài ra, thẻ <jsp:doBody/>sẽ được thay thế bằng nội dung của trang con

Tạo trang con (child.jsp) trong thư mục WebContent của bạn:

<%@ 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>được sử dụng để chỉ định trang chính mà bạn muốn sử dụng (lúc này là base.tag). Tất cả nội dung bên trong thẻ <jsp:body>ở đây sẽ thay thế nội dung <jsp:doBody/>trên trang chính của bạn. Trang con của bạn cũng có thể bao gồm bất kỳ thẻ lib nào và bạn có thể sử dụng nó bình thường như trang khác được đề cập. Tuy nhiên, nếu bạn sử dụng bất kỳ mã scriptlet nào ở đây ( <%= request.getParameter("name") %>...) và cố gắng chạy trang này, bạn sẽ nhận được một JasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here. Do đó, không có cách nào người khác có thể đưa mã ác vào tệp jsp

Gọi trang này từ bộ điều khiển của bạn:

Bạn có thể dễ dàng gọi tệp child.jsp từ bộ điều khiển của mình. Điều này cũng hoạt động tốt với khuôn khổ thanh chống

21 mahesh Feb 23 2011 at 13:14

Để tránh mã Java trong các tệp JSP, Java hiện cung cấp các thư viện thẻ, như JSTL.

Ngoài ra, Java đã đưa ra JSF để bạn có thể viết tất cả các cấu trúc lập trình dưới dạng thẻ.

19 ChandraSekhar Jun 05 2011 at 11:23

Sử dụng các thư viện thẻ JSTL trong JSP. Điều đó sẽ hoạt động hoàn hảo.

18 tanglei Jul 11 2011 at 13:59

Chỉ cần sử dụng thẻ JSTL và biểu thức EL.

17 CsBalazsHungary Jan 21 2013 at 23:04

Nếu ai đó thực sự chống lại việc lập trình bằng nhiều ngôn ngữ hơn một , tôi đề xuất GWT. Về mặt lý thuyết, bạn có thể tránh tất cả các phần tử JavaScript và HTML, vì Bộ công cụ của Google chuyển đổi tất cả ứng dụng khách và mã chia sẻ thành JavaScript. Bạn sẽ không gặp vấn đề với chúng, vì vậy bạn có một dịch vụ web mà không cần viết mã bằng bất kỳ ngôn ngữ nào khác. Bạn thậm chí có thể sử dụng một số CSS mặc định từ một nơi nào đó vì nó được cung cấp bởi các tiện ích mở rộng (smartGWT hoặc Vaadin ). Bạn không cần phải học hàng tá chú thích.

Tất nhiên, nếu bạn muốn, bạn có thể tự mình thâm nhập vào độ sâu của mã và đưa JavaScript vào và làm phong phú thêm trang HTML của bạn, nhưng thực sự bạn có thể tránh nó nếu bạn muốn và kết quả sẽ tốt như được viết trong bất kỳ khuôn khổ nào khác . Tôi nói rằng nó đáng để thử và GWT cơ bản được ghi chép đầy đủ.

Và tất nhiên nhiều lập trình viên đồng nghiệp theo đây đã mô tả hoặc đề xuất một số giải pháp khác. GWT dành cho những người thực sự không muốn xử lý phần web hoặc giảm thiểu nó.

16 Tobias May 21 2012 at 14:51

Một ý tưởng gọn gàng từ thế giới Python là các ngôn ngữ thuộc tính Mẫu ; TAL được giới thiệu bởi Zope (do đó còn được gọi là "Zope Page Templates", ZPT) và là một tiêu chuẩn, với các triển khai trong PHP, XSLT và Java (tôi đã sử dụng Python / Zope và PHP). Trong lớp ngôn ngữ tạo khuôn mẫu này, một trong các ví dụ trên có thể trông giống như sau:

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

Mã trông giống như HTML thông thường (hoặc XHTML) cộng với một số thuộc tính đặc biệt trong không gian tên XML; nó có thể được xem bằng trình duyệt và được nhà thiết kế tinh chỉnh một cách an toàn.

Có hỗ trợ cho macro và cả quốc tế hóa và bản địa hóa :

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

Nếu bản dịch của nội dung có sẵn, chúng sẽ được sử dụng.

Tuy nhiên, tôi không biết nhiều về việc triển khai Java .

15 kapildas Jul 22 2013 at 12:59

Sử dụng script trong JSP không phải là một thực tiễn tốt.

Thay vào đó, bạn có thể sử dụng:

  1. Thẻ JSTL
  2. Biểu thức EL
  3. Thẻ tùy chỉnh- bạn có thể xác định các thẻ của riêng mình để sử dụng.

Vui lòng tham khảo trước:

  1. http://docs.oracle.com/javaee/1.4/tutorial/doc/JSTL3.html
  2. EL
14 Razvan Mar 16 2014 at 00:17

Chắc chắn, hãy thay thế <%! counter++; %>bằng kiến ​​trúc nhà sản xuất - người tiêu dùng sự kiện, trong đó lớp nghiệp vụ được thông báo về sự cần thiết phải tăng bộ đếm, nó phản ứng tương ứng và thông báo cho người trình bày để họ cập nhật các chế độ xem. Một số giao dịch cơ sở dữ liệu có liên quan, vì trong tương lai chúng ta sẽ cần biết giá trị mới và cũ của bộ đếm, ai đã gia tăng nó và với mục đích gì. Rõ ràng là liên quan đến tuần tự hóa, vì các lớp hoàn toàn được tách rời. Bạn sẽ có thể tăng bộ đếm của mình qua RMI, IIOP, SOAP. Nhưng chỉ HTML là bắt buộc, mà bạn không thực hiện, vì nó là một trường hợp bình thường. Mục tiêu mới của bạn là đạt được 250 bước mỗi giây trên máy chủ RAM 64GB, E7 sáng bóng mới của bạn.

Tôi có hơn 20 năm trong lĩnh vực lập trình, hầu hết các dự án đều thất bại trước sextet: Khả năng tái sử dụng Khả năng thay thế OO Khả năng kiểm tra khả năng gỡ lỗi thậm chí còn cần thiết. Các dự án khác, được điều hành bởi những người chỉ quan tâm đến chức năng, đã cực kỳ thành công. Ngoài ra, cấu trúc đối tượng cứng, được triển khai quá sớm trong dự án, làm cho mã không thể thích ứng với những thay đổi mạnh mẽ trong các thông số kỹ thuật (còn gọi là nhanh nhẹn).

Vì vậy, tôi coi việc trì hoãn là hoạt động xác định các "lớp" hoặc cấu trúc dữ liệu dư thừa trong giai đoạn đầu của dự án hoặc khi không được yêu cầu cụ thể.  

11 mel3kings Jun 14 2013 at 16:31

Về mặt kỹ thuật, tất cả JSP đều được chuyển đổi thành Servlet trong thời gian chạy .

JSP ban đầu được tạo ra với mục đích tách logic nghiệp vụ và logic thiết kế, tuân theo mô hình MVC. Vì vậy, về mặt kỹ thuật JSP là tất cả mã Java trong thời gian chạy.

Nhưng để trả lời câu hỏi, các thư viện thẻ thường được sử dụng để áp dụng logic (loại bỏ mã Java) cho các trang JSP.

8 Yster Dec 24 2015 at 18:47

Làm cách nào để tránh mã Java trong tệp JSP?

Bạn có thể sử dụng các thẻ thư viện tab như JSTL ngoài Ngôn ngữ biểu thức ( EL ). Nhưng EL không hoạt động tốt với JSP. Vì vậy, có lẽ tốt hơn là nên bỏ JSP hoàn toàn và sử dụng Khuôn mặt .

Facelets là JSP ngôn ngữ đầu tiên không khai trang thiết kế cho JSF (Java Server Faces) mà cung cấp một mô hình lập trình đơn giản hơn và mạnh mẽ hơn để phát triển JSF như so sánh với JSP. Nó giải quyết các vấn đề khác nhau xảy ra trong JSP để phát triển ứng dụng web.

Nguồn

8 AjayTakur Apr 02 2012 at 20:52

Nếu chúng tôi sử dụng những thứ sau trong ứng dụng web Java, mã Java có thể bị loại bỏ khỏi nền trước của tệp JSP.

  1. Sử dụng kiến ​​trúc MVC cho ứng dụng web

  2. Sử dụng thẻ JSP

a. Thẻ tiêu chuẩn

b. Thẻ tùy chỉnh

  1. Ngôn ngữ diễn đạt
4 adn.911 Nov 30 2017 at 22:59

Sử dụng Scriptlets là một cách rất cũ và không được khuyến khích. Nếu bạn muốn xuất trực tiếp nội dung nào đó trong các trang JSP của mình, chỉ cần sử dụng Ngôn ngữ biểu thức (EL) cùng với JSTL .

Ngoài ra còn có các tùy chọn khác, chẳng hạn như sử dụng công cụ tạo khuôn mẫu như Velocity, Freemarker, Thymeleaf, v.v. Nhưng sử dụng JSP đơn giản với EL và JSTL phục vụ mục đích của tôi hầu hết thời gian và nó cũng có vẻ đơn giản nhất cho người mới bắt đầu.

Ngoài ra, hãy lưu ý rằng không phải là phương pháp hay nhất để thực hiện logic nghiệp vụ trong lớp xem. Bạn nên thực hiện logic nghiệp vụ của mình trong lớp dịch vụ và chuyển kết quả đầu ra cho các chế độ xem của bạn thông qua một bộ điều khiển .

3 SumeshTG Jun 20 2018 at 20:49

Sử dụng khung JavaScript giống Backbone.js hoặc AngularJS để thiết kế giao diện người dùng và tìm nạp dữ liệu bằng API REST. Điều này sẽ loại bỏ hoàn toàn sự phụ thuộc Java khỏi giao diện người dùng.

3 Eduardo Dec 13 2017 at 02:45

Không có gì trong số đó được sử dụng nữa, bạn của tôi. Lời khuyên của tôi là tách chế độ xem (CSS, HTML, JavaScript, v.v.) khỏi máy chủ.

Trong trường hợp của tôi, tôi xử lý hệ thống của mình bằng Angular và bất kỳ dữ liệu nào cần thiết được đưa từ máy chủ bằng các dịch vụ REST.

Tin tôi đi, điều này sẽ thay đổi cách bạn thiết kế.

3 AlirezaFattahi Apr 12 2016 at 21:55

JSP 2.0 có một tính năng được gọi là "Tệp thẻ" và bạn có thể viết thẻ mà không cần mã Java bên ngoài và tld. Bạn cần tạo một .tagtệp và đưa nó vào WEB-INF\tags. Bạn thậm chí có thể tạo cấu trúc thư mục để đóng gói các thẻ của mình.

Ví dụ:

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

Sử dụng nó như

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

Ngoài ra, bạn có thể đọc nội dung thẻ một cách dễ dàng:

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

Sử dụng nó:

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

Các mẫu này rất đơn giản, nhưng bạn có thể làm rất nhiều tác vụ phức tạp ở đây. Vui lòng xem xét bạn có thể sử dụng các thẻ khác (ví dụ: JSTLtrong đó có thẻ kiểm soát như if/forEcah/chosenthao tác văn bản như format/contains/uppercasehoặc thậm chí thẻ SQL select/update), vượt qua tất cả các thông số hiện vật, ví dụ Hashmap, truy cập session, request... trong tập tin thẻ của bạn quá.

Tệp thẻ được phát triển dễ dàng vì bạn không cần phải khởi động lại máy chủ khi thay đổi chúng, như tệp JSP. Điều này làm cho chúng dễ dàng phát triển.

Ngay cả khi bạn sử dụng một khuôn khổ như Struts 2, có rất nhiều thẻ tốt, bạn có thể thấy rằng việc có các thẻ của riêng bạn có thể làm giảm mã của bạn rất nhiều. Bạn có thể chuyển các tham số thẻ của mình vào thanh chống và bằng cách này, bạn có thể tùy chỉnh thẻ khung của mình.

Bạn có thể sử dụng các thẻ không chỉ để tránh Java mà còn giảm thiểu các mã HTML của mình. Bản thân tôi cố gắng xem lại mã HTML và xây dựng thẻ rất nhiều ngay khi tôi thấy các mã trùng lặp bắt đầu trong các trang của mình.

(Ngay cả khi bạn kết thúc sử dụng Java trong mã JSP của mình, điều mà tôi hy vọng là không, bạn có thể gói mã đó trong một thẻ.)

1 Mehdi Dec 01 2018 at 23:04
  1. Tạo các giá trị và tham số của bạn bên trong các lớp servlet của bạn
  2. Tìm nạp các giá trị và thông số đó trong JSP của bạn bằng JSTL / Taglib

Điều tốt về cách tiếp cận này là mã của bạn cũng là mã HTML giống như mã!

1 Code_Mode Jul 08 2017 at 03:24

Như nhiều câu trả lời cho biết, hãy sử dụng JSTL hoặc tạo các thẻ tùy chỉnh của riêng bạn. Đây là một giải thích tốt về việc tạo các thẻ tùy chỉnh.

bhanwarrathore Jul 15 2016 at 12:48

Bằng cách sử dụng các thẻ JSTL cùng với các biểu thức EL, bạn có thể tránh được điều này. Đặt những thứ sau vào trang JSP của bạn:

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