Як уникнути коду Java у файлах JSP?


1673

Я новачок у Java EE і знаю, що щось на зразок наступних трьох рядків

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

є старовинним шкільним способом кодування, а у JSP версії 2 існує спосіб уникнути коду Java у файлах JSP. Може хтось, будь ласка, скажіть мені альтернативні лінії JSP 2, і як називається ця методика?


22
@Koray Tugay, якщо змінна лічильника декларується десь до її використання, то це, безумовно, справедливо ...
Sheldon R.

@SheldonR. Це дійсно: <% = лічильник ++%> або це: <%! int counter = 0; int x = лічильник ++; %> але не: <%! int counter = 0; лічильник ++; %>
Корай Тугай

@KorayTugay, що я мав на увазі, якщо лічильник змінних був оголошений у попередньому блоці скриптів, він повинен бути дійсним у більш пізньому блоці. Але в кінцевому підсумку програмісти J2EE в ці дні повинні використовувати змінні EL замість сценаріїв, так чи інакше ...
Шелдон Р.

Відповіді:


1971

Використання сценаріїв (тих <% %>речей) в JSP дійсно сильно не рекомендується з моменту народження талібів (наприклад, JSTL ) та EL ( мова експресії , ці ${}речі) ще в 2001 році.

Основними недоліками скриптів є:

  1. Повторність використання: сценарії не можна використовувати повторно.
  2. Замінність: не можна робити сценарії абстрактними.
  3. OO-здатність: ви не можете використовувати спадщину / склад.
  4. Налагодження: якщо скриплет кидає виняток наполовину, все, що ви отримуєте, - це порожня сторінка.
  5. Заповідність: сценарії не перевіряються одиницями.
  6. Ремонтопридатність: за сальдо потрібно більше часу для підтримки логіки змішаного / захаращеного / дублюваного коду.

Сам Sun Oracle також рекомендує в умовах кодування JSP уникати використання скриптів, коли однакова функціональність можлива для класів (тегів). Ось декілька релевантних цитат:

З специфікації JSP 1.2, настійно рекомендується використовувати бібліотеку стандартних тегів JSP (JSTL) у вашій веб-програмі, щоб зменшити потребу в JSP-скриптах на ваших сторінках. Сторінки, які використовують JSTL, в цілому легше читати та підтримувати.

...

Де можливо, уникайте сценаріїв JSP, коли бібліотеки тегів забезпечують еквівалентну функціональність. Це робить сторінки простішими для читання та обслуговування, допомагає відділити ділову логіку від логіки презентації, а ваші сторінки легше перетворюються на сторінки в стилі JSP 2.0 (специфікація JSP 2.0 підтримує, але не підкреслює використання сценаріїв).

...

В дусі прийняття моделі дизайну-контролера (MVC) для зменшення зв'язку між рівнем презентації та бізнес-логікою сценарії JSP не повинні використовуватися для написання бізнес-логіки. Скоріше, сценарії JSP використовуються при необхідності для перетворення даних (також званих "об'єктами цінності"), повернених після обробки запитів клієнта, у належний готовий для клієнтів формат. Вже тоді це краще зробити з сервлетом переднього контролера або спеціальним тегом.


Як повністю замінити скрипти, залежить від єдиної мети коду / логіки. Частіше цей код слід розміщувати в повноцінному класі Java:

  • Якщо ви хочете викликати один і той же код Java на кожен запит, менший або більше, незалежно від запитуваної сторінки, наприклад, перевірити, чи користувач увійшов у систему, тоді застосуйте фільтр і запишіть код відповідно doFilter()методом. Наприклад:

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

    Якщо їх відображено на відповідних <url-pattern>сторінках, що цікавлять сторінки JSP, вам не потрібно копіювати один і той же фрагмент коду загальних сторінок JSP.


  • Якщо ви хочете викликати якийсь код Java для попередньої обробки запиту, наприклад, попередньо завантаживши якийсь список із бази даних для відображення в якійсь таблиці, якщо необхідно на основі деяких параметрів запиту, тоді реалізуйте сервлет і запишіть код відповідно doGet()методом. Наприклад:

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

    Цей спосіб поводження з винятками простіше. Доступ до БД не відбувається в середині візуалізації JSP, але набагато до того, як буде показано JSP. Ви все ще маєте можливість змінювати відповідь, коли доступ до БД кидає виняток. У наведеному вище прикладі відображатиметься сторінка помилки за замовчуванням 500 сторінок, яку ви все одно можете налаштувати <error-page>в web.xml.


  • Якщо ви хочете викликати якийсь код Java для обробки після запиту, наприклад, обробку форми подання, тоді реалізуйте сервлет і запишіть код відповідно doPost()методом. Наприклад:

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

    Таким чином , має справу з різними напрямками сторінки результату простіше: повторне відображенням форми з помилками перевірки в разі помилки (в даному прикладі ви можете повторно відобразити з допомогою ${message}в EL ), або просто приймати до бажаної цільової сторінці в разі успіху.


  • Якщо ви хочете викликати якийсь код Java для управління планом виконання та / або призначенням запиту та відповіді, тоді реалізуйте сервлет відповідно до шаблону переднього контролера MVC . Наприклад:

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

    Або просто прийняти рамку MVC на зразок JSF , Spring MVC , Wicket тощо, щоб ви закінчилися лише сторінкою JSP / Facelets та класом JavaBean без необхідності користувацького сервлета.


  • Якщо ви хочете викликати якийсь код Java для управління потоком всередині сторінки JSP, вам потрібно схопити (існуючий) таліг управління потоком, як ядро JSTL . Наприклад, відображення List<Product>в таблиці:

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

    З тегами XML-стилів, які добре вписуються серед усіх цих HTML, код краще читається (і, таким чином, краще піддається обробці), ніж купа сценаріїв з різними дужками відкриття та закриття ( "Куди, до біса, належить ця закриваюча дужка?" ). Простий посібник - налаштувати веб-додаток, щоб викинути виняток, коли сценарії все ще використовуються, додаючи наступний фрагмент до web.xml:

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

    У Facelets , наступник JSP, який є частиною Java EE при умови MVC Framework JSF , це вже НЕ можливо використовувати скріптлет . Таким чином ви автоматично змушені робити речі "правильним способом".


  • Якщо ви хочете викликати якийсь код Java для доступу та відображення даних "задніх днів" всередині сторінки JSP, тоді вам потрібно використовувати EL (мову вираження) ${}. Наприклад, повторне відображення поданих вхідних значень:

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

    В ${param.foo}відображає підсумковий документ request.getParameter("foo").


  • Якщо ви хочете , щоб викликати деякі утиліти Java код безпосередньо на сторінці JSP (зазвичай public staticметоди) то вам необхідно визначити їх як функції EL. У JSTL є стандартний таліб функцій , але ви також можете легко створювати функції самостійно . Ось приклад того, як JSTL fn:escapeXmlкорисний для запобігання XSS- атак .

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

    Зауважте, що чутливість XSS жодним чином не пов'язана з Java / JSP / JSTL / EL / будь-якою, цю проблему потрібно враховувати у кожному веб-додатку, який ви розробляєте. Проблема сценаріїв полягає в тому, що вони не забезпечують вбудованих запобіжників, принаймні, не використовують стандартний Java API. Наступник Facelet у JSP вже невірно вийшов з HTML, тому вам не потрібно турбуватися про отвори XSS у Facelets.

Дивись також:


117
+1 Відмінна відповідь. Але не переходьте догматично, колись із використанням скриптів це нормально, але це має бути винятком, який підтверджує правило.
svachon

26
@svachon: Сценарії корисні для швидкого прототипування / тестування. Наскільки я знаю, існує лише одне "законне" використання сценарію для виробництва, а саме <% response.getWriter().flush(); %>між </head>та <body>покращити ефективність розбору веб-сторінок у веб-браузері. Але це використання, в свою чергу, зовсім незначне, коли розмір вихідного буфера на стороні сервера низький (1 ~ 2 КБ). Дивіться також цю статтю .
BalusC

5
@BalusC Кілька разів я застрявав із класами java, які не дотримувались схеми getter / setter. ІМХО - це випадок, коли сценарій виконує цю роботу.
свачон

41
@svachon: Я б обернув ці класи власними класами javabean і використовував їх замість них.
BalusC

31
Це була досить гарна відповідь, але частини doGet і doPost вводять в оману. Ці методи призначені для обробки конкретних запитів (HEAD, GET та POST), а не для запитів "попередньої обробки" чи "після обробки"!
MetroidFan2002

225

Як гарантія: відключити сценарії назавжди

Оскільки обговорюється ще одне питання , ви можете та завжди повинні вимикати сценарії в web.xmlдескрипторі веб-додатків.

Я б завжди робив це для того, щоб будь-який розробник не додав сценарії, особливо у великих компаніях, де рано чи пізно ви втратите огляд. Ці web.xmlпараметри виглядають наступним чином :

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

4
Це також відключає коментарі скриптів ?: <%-- comment that i don't want in the final HTML --%>. Мені корисно використовувати ці, а не HTML коментарі.
Девід Лаванда

16
@MrSpoon простежив відповідь за вас. Відповідно до цієї відповіді + коментаря , це вимикає сценарії <% %>, вирази <%! %>сценаріїв та декларації сценаріїв <%= %>. Це означає, що директиви <%@ %>та коментарі <%-- --%>залишаються ввімкненими та корисними, тому ви все ще можете робити коментарі та включати.
Мартін Керні

3
Відключення директив скриптів було б жахливо - обробка пробілів є неоціненною для взаємодії зі застарілими системами, які вигадують зайвий пробіл.
corsiKa

108

JSTL пропонує теги для умовних умов, циклів, наборів, отримань тощо. Наприклад:

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

JSTL працює з атрибутами запиту - вони найчастіше встановлюються в запиті сервлетом, який пересилає JSP.


2
Чому, на вашу думку, JSTL працює з атрибутами запиту? Вони можуть працювати з атрибутами в будь-якій області, чи не так?
Корай Тугай

60

Я не впевнений, чи мені це правильно.

Ви повинні прочитати щось про MVC. Spring MVC & Struts 2 - два найпоширеніших рішення.


29
MVC може бути реалізований за допомогою сервлетів / jsp, використовуючи багато з перерахованих вище методів без Spring або Struts.
степанець

18
Як це відповідає на питання?
xyz

54

Ви можете використовувати теги JSTL разом з виразами EL, щоб уникнути змішування Java та HTML-коду:

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

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

    </body>
</html>

34

Існують також компоненти на основі компонентів, такі як Wicket, які генерують багато HTML для вас. Теги, що знаходяться в HTML, є надзвичайно елементарними, і практично немає логіки, яка змішується. Результатом є майже порожні HTML-сторінки із типовими елементами HTML. Мінус полягає в тому, що в API Wicket є багато компонентів, які можна вивчити, а деяких речей у цих обмеженнях складно досягти.


33

У архітектурній схемі MVC JSP представляють шар View. Вставлення коду Java в JSP вважається поганою практикою. Ви можете використовувати JSTL , freeMarker , швидкість із JSP як "шаблон двигуна". Постачальник даних для цих тегів залежить від рамок, з якими ви маєте справу. Struts 2і webworkяк реалізація для MVC Pattern використовується OGNL "дуже цікава методика викриття властивостей Beans JSP".


27

Досвід показує, що у JSP є деякі недоліки, один з яких важко уникнути змішування розмітки з фактичним кодом.

Якщо можете, то подумайте про використання спеціалізованої технології для того, що вам потрібно зробити. У Java EE 6 є JSF 2.0, який надає безліч приємних функцій, включаючи склеювання Java-бобів разом зі сторінками JSF через #{bean.method(argument)}підхід.


3
Старий відповідь, але я не можу протистояти, щоб сказати, що JSF - один з найжахливіших винаходів у просторі Java. Спробуйте зробити єдине (HTTP GET like) посилання, і ви зрозумієте, чому.
Олексій

@ Алекс, але все ж краще. Не соромтеся порекомендувати щось ще краще.
Thorbjørn Ravn Andersen

26

якщо ви просто хочете уникнути недоліків кодування Java в JSP, ви можете зробити це навіть із скриптами. Просто дотримуйтесь певної дисципліни, щоб мати мінімальний розмір Java у JSP та майже не мати розрахунків та логіки на сторінці 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>

26

Навчіться налаштовувати та писати власні теги за допомогою JSTL

Зауважте, що EL - це EviL (винятки з виконання, рефакторинг)
Хвіртка теж може бути злом (продуктивність, важка робота для невеликих додатків або простий рівень перегляду)

Приклад з java2s ,

Це потрібно додати до веб-програми web.xml

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

створити Файл: java2s.tld в / WEB-INF /

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

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

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

складіть наступний код у WEB-INF \ 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;
    }
}

Запустіть сервер і завантажте bodyContent.jsp у браузер

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

хоча повторне використання компонентів добре, воно націлене на деяке поле
tomasb

25

Wicket також є альтернативою, яка повністю відокремлює Java від html, тому дизайнер і програміст можуть працювати разом і над різними наборами коду, мало розуміючи один одного.

Подивіться на Вікет.


23

Ви поставили гарне запитання, і хоча ви отримали хороші відповіді, я б запропонував вам позбутися JSP. Це застаріла технологія, яка з часом загине. Використовуйте сучасний підхід, як шаблонні двигуни. У вас буде чітке розділення шарів бізнесу та презентацій, і, звичайно, немає коду Java в шаблонах, тому ви можете генерувати шаблони безпосередньо з програмного забезпечення для редагування веб-презентацій, у більшості випадків використовуючи WYSIWYG.

І неодмінно тримайтеся подалі від фільтрів і перед та після обробки, інакше ви можете зіткнутися з труднощами в підтримці / налагодженні, оскільки ви завжди не знаєте, де змінна отримує значення.


9
JSP - сам шаблон двигуна
WarFox

1
-1 - Існує багато цілком поважних причин використання фільтрів, попередніх процесорів та постпроцесорів. Так, ви можете закінчити значення, які здаються таємничими, але не, якщо ви розумієте свою архітектуру.
RustyTheBoyRobot

21

щоб уникнути коду Java у файлах JSP, java тепер надає бібліотеки тегів на зразок JSTL, а також java придумав JSF, в який ви можете записувати всі структури програмування у вигляді тегів


21

Скільки б ви не намагалися уникати, працюючи з іншими розробниками, деякі з них все ще віддадуть перевагу скрипту, а потім вставлять злий код у проект. Тому налаштування проекту за першою ознакою дуже важливо, якщо ви дійсно хочете зменшити код сценарію. Існує кілька прийомів подолання цього питання (включаючи декілька рамок, про які згадували інші). Однак якщо ви віддаєте перевагу чистому способу JSP, тоді використовуйте файл тегів JSTL. Приємно в тому, що ви також можете налаштувати головні сторінки для свого проекту, так що інші сторінки можуть успадкувати головні сторінки

Створіть головну сторінку під назвою base.tag під WEB-INF / тегами із наступним вмістом

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

На цій сторінці матері я створив фрагмент під назвою "назва", щоб на дочірній сторінці я міг вставити більше кодів у це місце головної сторінки. Також тег<jsp:doBody/> буде замінено вмістом дочірньої сторінки

Створіть дочірню сторінку (child.jsp) у своїй папці WebContent:

<%@ 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>використовується для вказівки головної сторінки, яку ви хочете використовувати (яка є базовим.таг на даний момент). Весь вміст всередині тегу <jsp:body>тут замінить <jsp:doBody/>на головній сторінці. Ваша дочірня сторінка також може містити будь-яку тегову вікно, і ви можете використовувати її зазвичай, як і інші згадані. Однак якщо ви тут використовуєте будь-який код сценарію ( <%= request.getParameter("name") %>...) і спробуєте запустити цю сторінку, ви отримаєтеJasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here . Тому немає можливості іншим людям включити злий код у файл jsp

Виклик цієї сторінки з вашого контролера:

Ви можете легко зателефонувати у файл child.jsp зі свого контролера. Це також добре працює з рамками стійок


"Скільки б ви не намагалися уникати, працюючи з іншими розробниками, деякі з них все одно віддадуть перевагу скрипту, а потім вставлять злий код у проект." Дивіться відповідь "Як гарантія: вимкнути сценарії назавжди".
Lluis Martinez



17

Якщо хтось дійсно проти програмування на декількох мовах, ніж на одній , я пропоную GWT, теоретично ви можете уникнути всіх елементів JS та HTML, тому що Google Toolkit перетворює весь клієнтський та спільний код у JS, у вас не виникне проблем з ними. у вас є веб-сервіс без кодування іншими мовами. Навіть ви можете використовувати десь CSS за замовчуванням звідкись, як це задано розширеннями (smartGWT або Vaadin). Вам не потрібно вивчати десятки анотацій.

Звичайно, якщо ви хочете, ви можете зламати себе в глибині коду і ввести JS і збагатити свою HTML-сторінку, але насправді ви можете цього уникнути, якщо хочете, і результат буде хорошим, як це було написано в будь-яких інших рамках. Я кажу, що варто спробувати, і базовий ГВТ добре задокументований.

І звичайно багато колег-програмістів описували або рекомендували кілька інших рішень. GWT призначений для людей, які дійсно не хочуть мати справу з веб-частиною або мінімізувати її.


1
Насправді не відповідає на питання ОП.
Еван Донован

1
@EvanDonovan добре, практично це дає відповідь. Вам не потрібно возитися з кодами Java, що змішуються з іншими мовами. Я визнаю, що вона використовує Java для кодування, але вона буде переведена в JS без викликів Java. Але сфера питання полягає в тому, як уникнути хаосу класичного JSP. І технологія GWT це вирішує. Цю відповідь я додав, оскільки ніхто її не згадував, але релевантний, оскільки це альтернатива JSP. Я не хотів відповідати на всю сферу питання, але додати цінну інформацію для людей, які шукають альтернативи.
CsBalazsHungary

16

Акуратною ідеєю світу Python є мови атрибутів Шаблону ; TAL був введений Zope (тому він також "Zope Page Templates", ZPT) і є стандартом, а також реалізаціями в PHP, XSLT та Java (я використовував втілення Python / Zope та PHP). У цьому класі мов шаблонів один із наведених вище прикладів може виглядати так:

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

Код виглядає як звичайний HTML (або XHTML) плюс деякі спеціальні атрибути у просторі імен XML; його можна переглядати за допомогою браузера і безпечно підробляти дизайнером. Існує підтримка макросів та i18n:

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

Якщо доступні переклади вмісту, вони використовуються.

Я не дуже знаю про реалізацію Java .


1
JSP з грудня 2009 року перейшов на зміну Facelets, який підтримує цей матеріал. Facelets також заснована на XML. Дивіться також серед інших розділ Facelets у навчальному посібнику Java EE 6 та ui:xxxтеги в VDL для Facelts .
BalusC

Я не дуже добре знаю Facelets, але IIRC - це все про класи написання, які реалізують власні XML-елементи. Шляхом TAL / ZPT є створення шаблонів, що містять справжній (X) HTML зі спеціальними атрибутами, які заповнюють або замінюють вихідні елементи; Таким чином, ви можете переглянути робочий шаблон і побачити прототип з приємним вмістом манекена. Я не впевнений, що Facelets дозволяють налаштувати оригінальні елементи HTML (без додаткового простору імен) за допомогою спеціальних атрибутів.
Тобіас

Я просто по-іншому подивився на цей матеріал із фейлеток Він містить всілякі засоби перевірки тощо. Таким чином, він відповідає абсолютно іншій філософії, ніж TAL. Спосіб TAL полягає в тому, що "зберігайте логіку поза шаблоном якомога чіткіше; всі складні речі повинні виконувати контролер, який її подає". Ви ніколи не дасте шаблону Facelets дизайнеру, щоб він / її налаштували; це просто неможливо. Щодо генерованого контенту - це так, як постійно використовувати tal:replace="structure (expression)"атрибути.
Тобіас

15

Використання сценаріїв в JSP не є хорошою практикою.

Натомість ви можете використовувати:

  1. Теги JSTL
  2. EL вирази
  3. Спеціальні теги - ви можете визначити власні теги для використання.

Будь ласка зверніться до:

  1. http://docs.oracle.com/javaee/1.4/tutorial/doc/JSTL3.html
  2. EL

14

Впевнений, заміни <%! counter++; %> архітектуру виробника події та споживача, де бізнес-рівень повідомляється про необхідність збільшення лічильника, він відповідно реагує та повідомляє присутніх, щоб вони оновлювали думки. Задіяна низка транзакцій з базами даних, оскільки в майбутньому нам потрібно буде знати нове і старе значення лічильника, хто його зробив і з якою метою пам’ятати. Очевидно, що йдеться про серіалізацію, оскільки шари повністю роз'єднані. Ви зможете збільшити свій лічильник через RMI, IIOP, SOAP. Але потрібен лише HTML, який ви не реалізуєте, оскільки це такий просторучний випадок. Ваша нова мета - досягти 250 кроків на секунду на новому блискучому сервері оперативної пам’яті E7, 64 Гб.

Мені більше 20 років займаються програмуванням, більшість проектів провалюються до секстету: Reusability Replaceability OO-Debuggability Testability Maintability навіть потрібен. Інші проекти, керовані людьми, які піклувалися лише про функціональність, були надзвичайно успішними. Крім того, жорстка структура об'єкта, впроваджена занадто рано в проекті, робить код не в змозі адаптуватися до кардинальних змін специфікацій (так же спритних).

Тому я розглядаю як зволікання активність визначення "шарів" або надлишкових структур даних або на початку проекту, або коли конкретно не потрібно.  


11

Технічно JSP перетворюються на сервлети під час виконання . JSP спочатку був створений з метою роз'єднання бізнес-логіки та логіки проектування за схемою MVC. Таким чином, JSP технічно всі коди Java під час виконання. Але щоб відповісти на запитання, теґі бібліотеки зазвичай використовуються для застосування логіки (видалення кодів Java) на сторінках JSP.


8

Якщо ми використовуємо наступні речі у веб-додатку java, код java може бути видалений з переднього плану JSP.

  1. Використовуйте архітектуру MVC для веб-додатків

  2. Використовуйте теги JSP

    а. Стандартні теги

    б. Спеціальні теги

  3. Мова виразів


8

Як уникнути коду Java у файлах JSP?

Ви можете використовувати теги бібліотеки вкладок, такі як JSTL, крім мови виразів ( EL ). Але EL не дуже добре працює з JSP. Тож, напевно, краще повністю скинути JSP і використовувати Facelets .

Facelet - це перша мова, що не стосується сторінки JSP, розроблена для JSF (Java Server Faces), яка забезпечила більш просту і потужну модель програмування для розробників JSF порівняно з JSP. Він вирішує різні проблеми, що виникають у JSP для розробки веб-додатків.

введіть тут опис зображення

Джерело


Я, безумовно, друге цю відповідь. JSF з фасетками або без них. Я вважав, що розвиток в JSP значною мірою припинився більше 10 років тому. Я востаннє писав JSP у 2000 році!
каса

4

Використання сценаріїв - дуже старий спосіб і не рекомендується. Якщо ви хочете безпосередньо вивести щось на своїх сторінках JSP, просто використовуйте Expression Language (EL) разом з JSTL .

Є й інші варіанти, такі як використання двигуна-шаблону, такого як Velocity, Freemarker, Thymeleaf тощо. Але використання простого JSP з EL та JSTL служить моїм завданням більшу частину часу, і для початківця це також здається найпростішим.

Також візьміть до уваги, що не найкраща практика ділової логіки на рівні перегляду, ви повинні виконувати свою бізнес-логіку на рівні сервісу та передавати результат виводу своїм уявленням через контролер.


3

Нічого з цього не використовую, мій друг, моя порада - відключити представлення (css, html, javascript тощо) з сервера.

У моєму випадку я мою систему, що обробляє подання з використанням Angular, і будь-які необхідні дані надходять із сервера за допомогою послуг відпочинку.

Повірте, це змінить спосіб дизайну


3

Використовуйте магістральну, кутову як javascript рамку для дизайну інтерфейсу та витягуйте дані, використовуючи інші api. Це повністю видалить залежність Java від інтерфейсу користувача.


3

JSP 2.0 має функцію під назвою "Файли тегів" , ви можете писати теги без зовнішнього javaкоду і tld. Вам потрібно створити .tagфайл і помістити його, WEB-INF\tagsви навіть можете створити структуру каталогу для упаковки ваших тегів.

Наприклад:

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

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

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

Використовуйте це як

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

Крім того, ви можете легко прочитати тіло тегу

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

Використай це

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

Зразки дуже прості, але тут можна виконати безліч складних завдань. Будь ласка , зверніть увагу ви можете використовувати інші мітки (наприклад , JSTLяка має контрольні мітки , як з if/forEcah/chosenтекстом , як format/contains/uppercaseабо навіть SQL тегів select/update), передати всі добрі параметри, наприклад Hashmap, доступ session, request... в файлі теги теж.

Файл тегів розроблений настільки просто, що вам не потрібно було перезапускати сервер під час їх зміни, як файли JSP. Це робить їх легкими для розвитку.

Навіть якщо ви використовуєте таку структуру, як Struts 2, яка має багато хороших тегів, ви можете виявити, що наявність власних тегів може значно зменшити ваш код. Ви можете передати параметри свого тегу до стійок і таким чином налаштувати ваш тег Framework.

Ви можете використовувати тег не тільки, щоб уникнути Java, але і мінімізувати свої HTML-коди. Я сам намагаюся дуже багато переглядати HTML-коди та створювати теги, як тільки на моїх сторінках починаються дублікати коду.

(Навіть якщо ви в кінцевому підсумку використовуєте java у своєму JSP-коді, що, я сподіваюся, ні, ви можете інкапсулювати цей код у тег)


1

Як сказано в багатьох відповідях, використовуйте JSTL або створюйте власні власні теги. Ось хороше пояснення щодо створення спеціальних тегів


1
  1. Введіть свої значення та параметри всередині класів сервлетів
  2. Отримайте ці значення та параметри у своєму JSP за допомогою JSTL / Taglib

Хороша річ у такому підході, що ваш код також є кодовим кодом HTML!


0

Використовуючи теги JSTL разом з виразом EL, ви можете цього уникнути. На свою сторінку jsp помістіть такі речі:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.