我是 Java EE 的新手,我知道类似于以下三行
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
是一种老式的编码方式,在 JSP 版本 2 中存在一种避免在 JSP 文件中使用 Java 代码的方法。什么是替代的 JSP 2 行,这种技术叫什么?
自 2001 年标记库(如JSTL)和EL(表达式语言,那些东西)诞生以来,确实非常不鼓励在JSP中使用scriptlet(那些东西)。<% %>
${}
Scriptlet的主要缺点是:
Sun Oracle 本身也在JSP 编码约定中建议避免使用scriptlet ,只要(标记)类可以实现相同的功能。以下是一些相关的引用:
从 JSP 1.2 规范开始,强烈建议在您的 Web 应用程序中使用 JSP 标准标记库 (JSTL),以帮助减少页面中对 JSP scriptlet 的需求。使用 JSTL 的页面通常更易于阅读和维护。
...
只要标签库提供等效功能,就尽可能避免使用 JSP scriptlet 。这使页面更易于阅读和维护,有助于将业务逻辑与表示逻辑分开,并使您的页面更容易演变为 JSP 2.0 样式的页面(JSP 2.0 规范支持但不强调使用 scriptlet)。
...
本着采用模型-视图-控制器 (MVC) 设计模式来减少表示层与业务逻辑之间的耦合的精神,不应使用 JSP 脚本来编写业务逻辑。相反,如果需要,可以使用 JSP 脚本将处理客户端请求返回的数据(也称为“值对象”)转换为适当的客户端就绪格式。即便如此,最好使用前端控制器 servlet 或自定义标记来完成。
如何替换scriptlet完全取决于代码/逻辑的唯一目的。这段代码经常被放在一个完全有价值的 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代码来处理一个GET请求,例如从数据库中预加载一些列表以显示在一些表中,如果有必要基于一些查询参数,那么实现一个servletdoGet()
并在方法中相应地编写代码。例如:
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 呈现过程中不访问 DB,但在显示 JSP 之前很长时间。每当数据库访问引发异常时,您仍然可以更改响应。在上面的示例中,将显示默认错误 500 页面,您可以通过<error-page>
in自定义该页面web.xml
。
如果您想调用一些 Java 代码来处理 POST 请求,例如从提交的 HTML 表单中收集数据并用它做一些业务(转换、验证、保存在 DB 中等),那么实现一个servlet并相应地编写代码在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.
}
}
这种处理不同结果页面目标的方式更容易:在出现错误时重新显示带有验证错误的表单(在这个特定的示例中,您可以使用EL${message}
重新显示它),或者在成功的情况下只进入所需的目标页面。
如果您想调用一些 Java 代码来控制执行计划和/或请求和响应的目的地,那么根据MVC 的 Front Controller Pattern实现一个servlet。例如:
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);
}
}
或者只是采用JSF、Spring MVC、Wicket等 MVC 框架,这样您最终只需要一个 JSP/Facelets 页面和一个 JavaBean 类,而无需自定义 servlet。
如果您想调用一些 Java 代码来控制JSP 页面内的流程,那么您需要获取一个(现有的)流程控制标签库,如JSTL core。例如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>
使用与所有 HTML 完美匹配的 XML 样式标签,代码比一堆带有各种左大括号和右大括号的 scriptlet 更易读(因此更易于维护)(“这个右大括号到底属于哪里?”)。一个简单的帮助是配置您的 Web 应用程序,以便在仍然使用scriptlet时抛出异常,方法是将以下部分添加到web.xml
:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
在JSP 的继承者Facelets中,它是 Java EE 提供的 MVC 框架JSF的一部分,已经不可能使用scriptlets了。这样,您就会自动被迫以“正确的方式”做事。
如果您想调用一些 Java 代码来访问和显示JSP 页面内的“后端”数据,那么您需要使用 EL(表达式语言),这些${}
东西。例如重新显示提交的输入值:
<input type="text" name="foo" value="${param.foo}" />
显示${param.foo}
的结果request.getParameter("foo")
。
如果您想直接在 JSP 页面中调用一些实用public static
Java 代码(通常是方法),那么您需要将它们定义为 EL 函数。JSTL 中有一个标准的函数标签库,但您也可以轻松地自己创建函数。fn:escapeXml
这是一个 JSTL 如何用于防止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/无论如何都没有特别的关系,在您开发的每个Web 应用程序中都需要考虑到这个问题。scriptlet的问题在于它没有提供内置预防措施,至少不使用标准 Java API。JSP 的继任者 Facelets 已经隐式 HTML 转义,因此您无需担心 Facelets 中的 XSS 漏洞。
作为保障:永久禁用 Scriptlet
正如另一个问题所讨论的那样,您可以并且始终应该在您的web.xml
Web 应用程序描述符中禁用 scriptlet。
我总是这样做是为了防止任何开发人员添加脚本,尤其是在您迟早会失去概览的大公司中。web.xml
设置如下所示:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
JSTL为条件、循环、集合、获取等提供标签。例如:
<c:if test="${someAttribute == 'something'}">
...
</c:if>
JSTL 与请求属性一起工作——它们通常由 Servlet 在请求中设置,然后转发给 JSP。
您可以将 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>
还有一些基于组件的框架,例如Wicket,可以为您生成大量 HTML。
最终出现在 HTML 中的标签非常基本,几乎没有混入其中的逻辑。结果几乎是空的 HTML 页面,带有典型的 HTML 元素。缺点是Wicket API中有很多组件需要学习,在这些限制下,有些事情可能很难实现。
If you simply want to avoid the drawbacks of Java coding in JSP you can do so even with scriplets. Just follow some discipline to have minimal Java in JSP and almost no calculation and logic in the JSP page.
<%@ 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>
经验表明,JSP 有一些缺点,其中之一是难以避免将标记与实际代码混合。
如果可以,请考虑使用专门的技术来完成您需要做的事情。#{bean.method(argument)}
在 Java EE 6 中有 JSF 2.0,它提供了许多不错的特性,包括通过该方法将 Java bean 与 JSF 页面粘合在一起。
学习使用 JSTL 自定义和编写自己的标签
请注意,EL 是EviL(运行时异常和重构)。
Wicket 也可能是邪恶的(小型应用程序或简单视图层的性能和繁琐)。
这必须添加到 Web 应用程序的 web.xml
<taglib>
<taglib-uri>/java2s</taglib-uri>
<taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>
在/WEB-INF/中创建文件java2s.tld
<!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>
Wicket也是一种将 Java 与 HTML 完全分开的替代方案,因此设计人员和程序员可以在相互了解很少的情况下一起工作并处理不同的代码集。
看看检票口。
您提出了一个很好的问题,尽管您得到了很好的答案,但我建议您摆脱 JSP。这是过时的技术,最终会消亡。使用现代方法,例如模板引擎。您将非常清楚地分离业务层和表示层,并且模板中当然没有 Java 代码,因此您可以直接从 Web 表示编辑软件生成模板,在大多数情况下利用所见即所得。
并且一定要远离过滤器以及前后处理,否则您可能会遇到支持/调试困难,因为您总是不知道变量从哪里获得值。
为了避免 JSP 文件中出现 Java 代码,Java 现在提供了标记库,例如 JSTL。
此外,Java 还提出了JSF,您可以将所有编程结构以标签的形式写入其中。
不管你如何避免,当你与其他开发人员合作时,他们中的一些人仍然会更喜欢 scriptlet,然后将恶意代码插入到项目中。因此,如果你真的想减少 scriptlet 代码,一开始就设置项目非常重要。有几种技术可以克服这个问题(包括其他提到的几个框架)。但是,如果您更喜欢纯 JSP 方式,那么请使用 JSTL 标记文件。这样做的好处是您还可以为您的项目设置母版页,因此其他页面可以继承母版页
在您的 WEB-INF/tags 下创建一个名为 base.tag 的母版页,其中包含以下内容
<%@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/>
将替换为子页面的内容
在您的 WebContent 文件夹中创建子页面 (child.jsp):
<%@ 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/>
您的母版页上的。您的子页面还可以包含任何标签库,您可以像其他提到的那样正常使用它。但是,如果您在此处使用任何 scriptlet 代码 ( <%= request.getParameter("name") %>
...) 并尝试运行此页面,您将获得一个JasperException because Scripting elements ( <%!, <jsp:declaration, <%=, <jsp:expression, <%, <jsp:scriptlet ) are disallowed here
. 因此,其他人无法将恶意代码包含到jsp文件中
从您的控制器调用此页面:
您可以轻松地从控制器调用 child.jsp 文件。这也适用于 struts 框架
在 JSP 中使用 JSTL 标记库。这将完美地工作。
只需使用 JSTL 标记和 EL 表达式。
如果有人真的反对用一种以上的语言进行编程,我建议使用 GWT。从理论上讲,您可以避免使用所有 JavaScript 和 HTML 元素,因为 Google Toolkit 将所有客户端和共享代码都转换为 JavaScript。您不会对它们有任何问题,因此您无需使用任何其他语言进行编码即可拥有 Web 服务。您甚至可以从某个地方使用一些默认 CSS,因为它是由扩展(smartGWT 或Vaadin)提供的。你不需要学习几十个注释。
当然,如果你愿意,你可以深入到代码的深处,注入 JavaScript 并丰富你的 HTML 页面,但如果你愿意,你真的可以避免它,结果会很好,因为它是在任何其他框架中编写的. 我说值得一试,基本的 GWT 有据可查。
当然,许多程序员同行在此描述或推荐了其他几种解决方案。GWT 适用于那些真的不想处理 Web 部件或将其最小化的人。
Python 世界的一个好主意是模板属性语言;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 命名空间中的一些特殊属性;它可以用浏览器查看,并由设计师安全地进行调整。
还支持宏以及国际化和本地化:
<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 实现不太了解。
在 JSP 中使用 scriptlet 不是一个好习惯。
相反,您可以使用:
请参阅:
当然,替换<%! counter++; %>
为事件生产者-消费者架构,其中通知业务层需要增加计数器,它会做出相应的反应,并通知演示者以便他们更新视图。涉及到许多数据库事务,因为将来我们需要知道计数器的新旧值、谁增加了它以及考虑什么目的。显然涉及到序列化,因为这些层是完全解耦的。您将能够在 RMI、IIOP、SOAP 上增加您的计数器。但是只有 HTML 是必需的,您没有实现它,因为它是如此平凡。您的新目标是在新的闪亮 E7、64GB RAM 服务器上达到每秒 250 个增量。
我有 20 多年的编程经验,大多数项目在六重奏之前就失败了: 可重用性 可替换性 OO 能力 可调试性 可测试性 可维护性甚至是需要的。由只关心功能的人管理的其他项目非常成功。此外,在项目中过早实施的僵硬对象结构使代码无法适应规范的剧烈变化(也称为敏捷)。
因此,我认为在项目早期或没有特别需要时定义“层”或冗余数据结构的活动是拖延。
从技术上讲,JSP 在运行时都被转换为 Servlet。
JSP 最初是为了解耦业务逻辑和设计逻辑而创建的,遵循 MVC 模式。因此,从技术上讲,JSP 是运行时期间的所有 Java 代码。
但要回答这个问题,标记库通常用于将逻辑(删除 Java 代码)应用于 JSP 页面。
如果我们在 Java Web 应用程序中使用以下内容,则可以从 JSP 文件的前台消除 Java 代码。
将 MVC 架构用于 Web 应用程序
使用 JSP 标签
一个。标准标签
湾。自定义标签
如何避免 JSP 文件中的 Java 代码?
除了表达式语言 ( EL )之外,您还可以使用JSTL等选项卡库标签。但是 EL 不适用于 JSP。因此,完全放弃 JSP 并使用Facelets可能会更好。
Facelets是第一个为JSF(Java Server Faces)设计的非 JSP 页面声明语言,与 JSP 相比,它为 JSF 开发人员提供了更简单、更强大的编程模型。它解决了在 JSP 中用于 Web 应用程序开发的不同问题。
使用 Scriptlets 是一种非常古老的方式,不推荐使用。如果您想直接在 JSP 页面中输出某些内容,只需使用表达式语言 (EL) 和JSTL即可。
还有其他选择,例如使用模板引擎,例如 Velocity、Freemarker、Thymeleaf 等。但是使用带有 EL 和 JSTL 的普通 JSP 大部分时间都符合我的目的,而且对于初学者来说似乎也是最简单的。
另外,请注意,在视图层中执行业务逻辑并不是最佳实践。您应该在服务层执行业务逻辑,并通过控制器将输出结果传递给您的视图。
我的朋友,这些都不再使用了。我的建议是将视图(CSS、HTML、JavaScript 等)与服务器分离。
就我而言,我让我的系统使用 Angular 处理视图,并且使用 REST 服务从服务器获取所需的任何数据。
相信我,这会改变你的设计方式。
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
access session
、request
、 ... 。
标记文件非常容易开发,因为您在更改它们时不需要重新启动服务器,例如 JSP 文件。这使它们易于开发。
即使你使用像 Struts 2 这样的框架,它有很多好的标签,你可能会发现拥有自己的标签可以大大减少你的代码。您可以将标签参数传递给 struts,这样可以自定义您的框架标签。
您不仅可以使用标签来避免使用 Java,还可以最大限度地减少 HTML 代码。一旦我在我的页面中看到代码重复,我自己就会尝试大量查看 HTML 代码并构建标签。
(即使您最终在 JSP 代码中使用了 Java,我希望不会,您也可以将该代码封装在标签中。)
使用 Backbone.js 或类似 AngularJS 的 JavaScript 框架进行 UI 设计并使用 REST API 获取数据。这将从 UI 中完全删除 Java 依赖项。
Java 本身是一种非常好的语言,但在企业环境中的大量使用使其标准解决方案极其(荒谬地)困难。示例:JSTL、JSF、Wicket 等。
这是一种在 Java 中创建后端的超轻量级方法:
我将它用于我的一个副项目(托管 Digitalocean 5 美元的水滴、Nginx、Tomcat),它非常快:根据 Googlebot 的平均响应时间约为 160 毫秒。
正如许多答案所说,使用 JSTL 或创建自己的自定义标签。这是关于创建自定义标签的一个很好的解释。
这种方法的好处是您的代码也是类似 HTML 的代码!
这里的很多答案都是“使用框架”路线。这是零错误的。但是我认为它并不能真正回答您的问题,因为框架可能使用也可能不使用 JSP,它们的设计也没有以任何方式将在 JSP 中使用 java 作为主要目标。
您的问题“我如何避免在 JSP 中使用 Java”的唯一好的答案是:您不能。
这就是 JSP 的用途——使用 Java 以动态数据/逻辑呈现 HTML。后续问题可能是,我应该在我的 JSP 中使用多少 java。
在我们回答这个问题之前,您还应该思考,“我需要使用 JSP 来使用 Java 构建 Web 内容吗?” 最后一个的答案是,不。对于使用 Java 开发面向 Web 的应用程序,有许多 JSP 替代方案。例如,Struts 不会强迫您使用 JSP - 不要误会我的意思,您可以使用它们,许多实现都可以,但您并非绝对必须这样做。Struts 甚至不强制您使用任何 HTML。JSP 也不会,但老实说,不产生 HTML 的 JSP 有点奇怪。众所周知,Servlet 允许您通过 HTTP 动态地提供您喜欢的任何类型的内容。它们是几乎所有 java web 背后的主要技术——JSP 只是 servlet 的 HTML 模板,真的。
因此,您应该在 JSP 中放入多少 java 的答案是“尽可能少”。我的 JSP 中当然有 java,但它完全由标记库定义、会话和客户端变量以及封装服务器端对象的 bean 组成。我的 HTML 中的 <%%> 标记几乎完全是属性调用或变量表达式。罕见的例外情况包括与单个页面相关且不太可能被重用的超特定计算;源自页面特定问题的错误修正仅适用于一页;最后一分钟的连接和算术源于不寻常的要求,范围仅限于一页;和其他类似情况。在 150 万行、3000 个 JSP 和 5000 个类的代码集中,可能有 100 个此类独特片段的实例。在类或标记库定义中进行这些更改是完全可能的,但由于每种情况的特殊性,它会非常复杂,编写和调试需要更长的时间,因此需要更多的时间才能到达我的用户。这是一个判断电话。但是不要搞错,你不能用“no java”写出任何意义的JSP,你也不想写。这种能力是有原因的。
通过将 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" %>