Как избежать Java-кода в файлах JSP?

1673

Я новичок в Java EE и знаю, что-то вроде следующих трех строк

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

это старый способ кодирования, и в JSP версии 2 существует метод, позволяющий избежать Java-кода в файлах JSP. Может кто-нибудь сказать, пожалуйста, альтернативные линии JSP 2, и как называется эта техника?

chmoelders
источник
22
@ Корай Тугай, если переменная counter объявлена ​​где-то до ее использования, то она наверняка действительна ...
Шелдон Р.
@SheldonR. Это верно: <% = counter ++%> или это: <%! int counter = 0; int x = counter ++; %> но не: <%! int counter = 0; Счетчик ++; %>
Корай Тугай
@KorayTugay, я имел в виду, что если переменная counter была объявлена ​​в более раннем блоке скрипта, она должна быть действительной в более позднем блоке. Но в конечном счете, программисты J2EE в наши дни должны использовать переменные EL вместо скриптлетов, в любом случае ...
Шелдон Р.

Ответы:

1972

Использование скриптлетов (те <% %>вещи) в JSP действительно крайне не рекомендуется с момента рождения taglibs (например, JSTL ) и EL ( Expression Language , те ${}вещи) еще в 2001 году.

Основными недостатками скриплетов являются:

  1. Возможность повторного использования : вы не можете повторно использовать скриптлеты.
  2. Заменимость: вы не можете сделать скриптлеты абстрактными.
  3. ОО-способность: вы не можете использовать наследование / композицию.
  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>in 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, то вам нужно получить (существующий) taglib управления потоком, такой как ядро 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 (Expression Language), эти ${}вещи. Например, повторное отображение введенных значений ввода:

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

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


  • Если вы хотите вызывать некоторый служебный Java-код непосредственно на странице JSP (обычно это public staticметоды), то вам нужно определить их как функции EL. В JSTL есть стандартные функции taglib , но вы также можете легко создавать функции самостоятельно . Вот пример того, как 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. Преемник JSP Facelets уже неявно экранирует HTML, поэтому вам не нужно беспокоиться о дырах XSS в Facelets.

Смотрите также:

BalusC
источник
117
+1 Отличный ответ. Но не будьте догматичны, иногда использование скриптлетов - это нормально, но это должно быть исключением, которое подтверждает правило.
свачон
26
@svachon: Scriptlets полезны для быстрого создания прототипов / тестирования. Насколько я знаю, существует только одно «законное» производственное использование скриптлета, а именно <% response.getWriter().flush(); %>между </head>и <body>для повышения производительности анализа веб-страницы в браузере. Но это использование, в свою очередь, совершенно незначительно, когда размер выходного буфера на стороне сервера мал (1 ~ 2 КБ). Смотрите также эту статью .
BalusC
5
@BalusC Несколько раз я застревал с классами Java, которые не следовали шаблону получения / установки. ИМХО, это тот случай, когда скриптлет выполняет свою работу.
свачон
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.

Bozho
источник
2
Почему вы говорите, что JSTL работает с атрибутами запроса? Они могут работать с атрибутами в любой области, не так ли?
Корай Тугай
60

Я не уверен, правильно ли я понял.

Вы должны прочитать кое-что о MVC. Spring MVC & Struts 2 являются двумя наиболее распространенными решениями.

tzim
источник
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-элементами. Недостатком является то, что в Wicket API есть много компонентов для изучения, и некоторые вещи могут быть труднодостижимы при этих ограничениях.

tsand
источник
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) ссылку, и вы поймете, почему.
Алекс
@ Алекс, но все же лучше. Не стесняйтесь рекомендовать что-то еще лучше.
Торбьерн Равн Андерсен
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>
Dipu
источник
26

Научитесь настраивать и писать свои собственные теги, используя JSTL

Обратите внимание, что EL - это EviL (исключения во время выполнения, рефакторинг).
Wicket также может быть плохим ( производительность, сложная для небольших приложений или простого уровня просмотра).

Пример из 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 \ classes \ com \ java2s

package com.java2s;

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

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

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

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

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

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

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

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

Запустите сервер и загрузите bodyContent.jsp в браузер

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>
tomasb
источник
хотя повторное использование компонентов в порядке, оно предназначается для некоторой области
tomasb
25

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

Посмотри на калитку.

msj121
источник
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>

На этой основной странице я создал фрагмент с названием «title», чтобы на дочерней странице я мог вставить больше кодов в это место главной страницы. Также тег <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>используется для указания главной страницы, которую вы хотите использовать (в данный момент это base.tag). Весь контент внутри тега <jsp:body>будет заменен <jsp:doBody/>на вашей главной странице. Ваша дочерняя страница также может содержать любой тег lib, и вы можете использовать его, как и другие упомянутые выше. Тем не менее, если вы используете какой-либо код скриплета здесь ( <%= 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 с вашего контроллера. Это также хорошо работает со структурой стоек

Тайский тран
источник
«Независимо от того, сколько вы пытаетесь избежать, когда вы работаете с другими разработчиками, некоторые из них по-прежнему предпочитают скриптлет и затем вставляют злой код в проект». См. Ответ «В качестве меры предосторожности: отключите скрипты насовсем».
Луис Мартинес
19

Используйте JSTL Tag librariesв JSP, это будет отлично работать.

Чандра Сехар
источник
18

Просто используйте тег JSTL и выражение EL.

tanglei
источник
17

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

Конечно, если вы хотите, вы можете взломать себя до глубины кода и внедрить JS и обогатить свою HTML-страницу, но на самом деле вы можете избежать этого, если хотите, и результат будет хорошим, как это было написано в любой другой среде. Я говорю, стоит попробовать, и основной GWT хорошо документирован.

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

CsBalazsHungary
источник
1
На самом деле не отвечает на вопрос ОП.
Эван Донован
1
@EvanDonovan хорошо, практически он дает ответ. Вам не нужно связываться с Java-кодами, смешивающимися с другими языками. Я признаю, что он использует Java для кодирования, но он будет переведен в JS без вызовов Java. Но вопрос в том, как избежать хаоса классической JSP. И технология GWT решает это. Я добавил этот ответ, так как никто не упомянул его, но актуален, поскольку он является альтернативой JSP. Я не хотел отвечать на весь вопрос, но добавить ценную информацию для людей, которые ищут альтернативы.
CsBalazsHungary
16

Отличная идея из мира Python - это языки атрибутов Template ; TAL был введен Zope (следовательно, «Шаблоны страниц Zope», 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
С декабря 2009 года JSP сменила Facelets, которая поддерживает этот материал. Facelets также основан на XML. См. Также главу Facelets в руководстве по Java EE 6 и ui:xxxтеги в Facelts VDL .
BalusC
Я не очень хорошо знаю Facelets, но IIRC это все о написании классов, которые реализуют пользовательские элементы XML. Способ TAL / ZPT состоит в том, чтобы иметь шаблоны, которые содержат истинный (X) HTML со специальными атрибутами, которые заполняют или заменяют исходные элементы; Таким образом, вы можете просмотреть рабочий шаблон и увидеть прототип с красивым фиктивным контентом. Я не уверен, что Facelets позволяют настраивать оригинальные элементы HTML (без дополнительного пространства имен) с помощью пользовательских атрибутов.
Тобиас
Я только что взглянул на этот материал Facelets. Он содержит все виды средств проверки и т. Д. И, следовательно, следует совершенно другой философии, чем 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 лет, большинство проектов проваливаются до появления секстета: возможность повторного использования, возможность замены, возможность OO, возможность отладки, тестируемость. Другие проекты, выполняемые людьми, которые заботились только о функциональности, были чрезвычайно успешными. Кроме того, жесткая объектная структура, реализованная слишком рано в проекте, делает код неспособным адаптироваться к резким изменениям в спецификациях (иначе говоря, гибким).

Поэтому я считаю промедлением деятельность по определению «слоев» или избыточных структур данных либо в начале проекта, либо когда это не требуется специально.  

Разван
источник
11

Технически все JSP преобразуются в сервлеты во время выполнения . Изначально JSP был создан с целью разделения бизнес-логики и логики проектирования в соответствии с шаблоном MVC. Таким образом, JSP технически - это все java-коды во время выполнения. Но чтобы ответить на этот вопрос, библиотеки тегов обычно используются для применения логики (удаления кодов Java) к страницам JSP.

mel3kings
источник
8

Если мы используем следующие вещи в веб-приложении Java, код Java может быть исключен с переднего плана JSP.

  1. Использовать архитектуру MVC для веб-приложения

  2. Используйте теги JSP

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

    б. Пользовательские теги

  3. Язык выражения

Аджай Такур
источник
8

Как избежать Java-кода в файлах JSP?

Вы можете использовать теги библиотеки вкладок, такие как JSTL, в дополнение к языку выражений ( EL ). Но EL плохо работает с JSP. Так что, вероятно, лучше полностью отказаться от JSP и использовать Facelets .

Facelets - это первый не-JSP язык объявления страниц, разработанный для JSF (Java Server Faces), который предоставил разработчикам JSF более простую и мощную модель программирования по сравнению с JSP. Это решает различные проблемы, возникающие в JSP для разработки веб-приложений.

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

Источник

Yster
источник
Я определенно поддерживаю этот ответ. JSF с или без Facelets. Я думал, что разработка в JSP в основном прекратилась более 10 лет назад. В последний раз я писал JSP в 2000 году!
17
4

Использование Scriptlets является очень старым способом и не рекомендуется. Если вы хотите напрямую что-то выводить на своих страницах JSP, просто используйте язык выражений (EL) вместе с JSTL .

Есть и другие варианты, такие как использование шаблонизатора, такого как Velocity, Freemarker, Thymeleaf и т. Д. Но использование простой JSP с EL и JSTL служит моей цели большую часть времени, и это также кажется самым простым для новичка.

Кроме того, обратите внимание, что не рекомендуется использовать бизнес-логику на уровне представления, вы должны выполнять свою бизнес-логику на уровне службы и передавать результат вывода в представления через контроллер.

adn.911
источник
3

Ничего из этого больше не используется, мой друг, мой совет - отделить представление (css, html, javascript и т. Д.) От сервера.

В моем случае мои системы обрабатывают представление с помощью Angular, и любые необходимые данные доставляются с сервера с использованием служб отдыха.

Поверьте, это изменит ваш дизайн

Эдуардо
источник
3

Используйте основу, угловой, как javascript framework для дизайна пользовательского интерфейса и извлекайте данные с помощью rest 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, которая имеет много хороших тегов, вы можете обнаружить, что наличие собственных тегов может значительно сократить ваш код. Вы можете передать параметры вашего тега в распорки и таким образом настроить тег вашего фреймворка.

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

(Даже если вы в конечном итоге используете Java в своем коде JSP, что, я надеюсь, не так, вы можете инкапсулировать этот код в тег)

Алиреза Фаттахи
источник
1

Как говорится во многих ответах, используйте JSTL или создайте свои собственные теги. Вот хорошее объяснение о создании пользовательских тегов

Code_Mode
источник
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" %>
бханвар ратор
источник