我是Java EE的新手,我知道类似以下三行的内容
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
是一种旧式的编码方式,在JSP版本2中,存在一种避免JSP文件中的Java代码的方法。有人可以告诉我替代的JSP 2行,以及这种技术的名称是什么?
答案 0 :(得分:1927)
答案 1 :(得分:218)
作为安全措施:禁用Scriptlets for Good
正如another question所讨论的那样,您可以并且始终应该在web.xml
Web应用程序描述符中禁用scriptlet。
我总是这样做是为了防止任何开发人员添加scriptlet,尤其是在大型公司中,您迟早会丢失概述。 web.xml
设置如下所示:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
答案 2 :(得分:106)
JSTL为条件,循环,集合,获取等提供标签。例如:
<c:if test="${someAttribute == 'something'}">
...
</c:if>
JSTL使用请求属性 - 它们通常由Servlet在请求中设置,转发到JSP。
答案 3 :(得分:60)
我不确定我是否认为这是正确的。
您应该阅读有关MVC的内容。 Spring MVC&amp; Struts 2是两种最常见的解决方案。
答案 4 :(得分:53)
您可以将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>
答案 5 :(得分:34)
还有基于组件的框架,例如 Wicket ,可以为您生成大量HTML。最终在HTML中的标签非常基本,并且几乎没有混合的逻辑。结果几乎是空的HTML页面,具有典型的HTML元素。缺点是 Wicket API中有很多组件需要学习,有些事情在这些限制条件下很难实现。
答案 6 :(得分:32)
在MVC架构模式中,JSP表示View层。在JSP中嵌入Java代码被认为是一种不好的做法。
您可以将JSTL,freeMarker,velocity与JSP一起用作“模板引擎”。
这些标记的数据提供者取决于您正在处理的框架。 Struts 2
和webwork
作为MVC模式的实现使用OGNL“非常有趣的技术将Beans Properties暴露给JSP”。
答案 7 :(得分:27)
经验表明,JSP有一些缺点,其中一个难以避免将标记与实际代码混合。
如果可以,请考虑使用专门的技术来满足您的需求。在Java EE 6中有JSF 2.0,它提供了许多不错的功能,包括通过#{bean.method(argument)}
方法将Java bean与JSF页面粘合在一起。
答案 8 :(得分:26)
如果您只是想避免JSP中Java编码的缺点,即使使用scriplet也可以这样做。只需遵循一些规则,在JSP中使用最少的Java,而在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>
答案 9 :(得分:26)
了解如何使用JSTL自定义和编写自己的代码
请注意,EL是 EviL (运行时异常,重构)
Wicket也可能是邪恶的(性能,对于小应用程序或简单的视图层来说很麻烦)
示例来自 java2s ,
必须将其添加到Web应用程序的web.xml
<taglib>
<taglib-uri>/java2s</taglib-uri>
<taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>
在/ WEB-INF /
中创建File: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>
答案 10 :(得分:25)
Wicket也是一种完全将java与html分开的替代方案,因此设计人员和程序员可以在不同的代码集上协同工作,而彼此之间几乎没有相互理解。
看看Wicket。
答案 11 :(得分:24)
你提出了一个很好的问题,虽然你得到了很好的答案,但我建议你摆脱JSP。它是过时的技术,最终会死亡。使用现代方法,如模板引擎。您将清楚地分离业务层和表示层,当然模板中没有Java代码,因此您可以直接从Web演示文稿编辑软件生成模板,在大多数情况下可以利用WYSIWYG。
当然要远离过滤器以及前后处理,否则你可能会遇到支持/调试困难,因为你总是不知道变量的值在哪里。
答案 12 :(得分:21)
为了避免JSP文件中的java代码,java现在提供了像JSTL这样的标记库,java也提出了JSF,你可以用标签的形式编写所有的编程结构
答案 13 :(得分:21)
无论你多少尝试避免,当你与其他开发人员合作时,他们中的一些人仍然会喜欢scriptlet,然后将邪恶的代码插入到项目中。因此,如果您真的想减少scriptlet代码,那么在第一个符号设置项目非常重要。有几种技术可以克服这个问题(包括其他提到的几个框架)。但是,如果您更喜欢纯JSP方式,那么请使用JSTL标记文件。关于这一点的好处是您还可以为项目设置母版页,以便其他页面可以继承母版页
在您的WEB-INF /标签下创建一个名为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>
在这个mater页面上,我创建了一个名为“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框架
答案 14 :(得分:19)
在JSP中使用 JSTL Tag libraries
,这将非常有效。
答案 15 :(得分:18)
只需使用JSTL标记和EL表达式。
答案 16 :(得分:17)
如果有人真的反对使用多种语言编程,我建议使用GWT,理论上你可以避免使用所有JS和HTML元素,因为Google Toolkit会将所有客户端和共享代码转换为JS,你不会遇到问题,所以你有一个没有任何其他语言编码的web服务。即使你可以使用某些默认的CSS,因为它是由扩展(smartGWT或Vaadin)提供的。您不需要学习几十个注释。
当然,如果你愿意的话,你可以深入了解代码的深度并注入JS并丰富你的HTML页面,但是你真的可以避免它,如果你想要的话,结果会很好,因为它写在任何其他框架。我说值得一试,基本的GWT已经有了很好的记录。
当然,许多程序员在此描述或推荐了其他几种解决方案。 GWT适用于那些真正不想处理Web部件或将其最小化的人。
答案 17 :(得分:16)
来自Python世界的一个巧妙的想法是模板属性语言; TAL由Zope引入(因此a.k.a。“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 implementation并不是很了解。
答案 18 :(得分:15)
在JSP中使用scriptlet不是一个好习惯。
相反,您可以使用:
请参阅:
答案 19 :(得分:14)
答案 20 :(得分:11)
从技术上讲,JSP在运行时都会转换为Servlet 。 JSP最初是为了按照MVC模式解耦业务逻辑和设计逻辑而创建的。所以JSP在运行时在技术上都是java代码。但回答这个问题,Tag Libraries通常用于将逻辑(删除Java代码)应用于JSP页面。
答案 21 :(得分:9)
如果我们在java Web应用程序中使用以下内容,则可以从JSP的前台删除java代码。
将MVC架构用于Web应用程序
使用JSP标记
一个。标准标签
湾自定义标签
表达语言
答案 22 :(得分:6)
如何避免JSP文件中的Java代码?
除了表达式语言( EL )之外,您还可以使用 JSTL 等标签库标签。但是EL与JSP不兼容。因此,最好完全删除JSP并使用 Facelets 。
Facelets 是第一个为 JSF(Java Server Faces)设计的非JSP页面声明语言,与JSP相比,它为JSF开发人员提供了更简单,更强大的编程模型。它解决了JSP中用于Web应用程序开发的不同问题。
答案 23 :(得分:4)
使用Scriptlet是一种非常古老的方式,不推荐使用。如果您想在JSP页面中直接输出内容,只需使用表达式语言(EL)以及 JSTL 。
还有其他选项,例如使用模板引擎,如Velocity,Freemarker,Thymeleaf等。但是使用带有EL和JSTL的普通JSP大部分时间都是我的目的,对初学者来说似乎也是最简单的。
另外,请注意,在视图层中执行业务逻辑不是最佳做法,您应该在服务层执行业务逻辑, 并通过Controller将输出结果传递给您的视图。
答案 24 :(得分:3)
我的朋友不再使用这个,我的建议是将视图(css,html,javascript等)与服务器分离。
在我的情况下,我使用Angular处理视图,并使用其他服务从服务器获取所需的任何数据。
相信我,这将改变你的设计方式
答案 25 :(得分:3)
使用骨架(如javascript框架)进行UI设计 并使用rest api获取数据。这将从UI中完全删除Java依赖项。
答案 26 :(得分:2)
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这样的框架,它有很多好的标签,你可能会发现拥有自己的标签可以减少你的代码。您可以将标记参数传递给struts,这样就可以自定义框架标记。
您不仅可以使用标记来避免使用Java,还可以最小化HTML代码。一旦看到代码重复在我的页面中开始,我自己就会尝试查看HTML代码并构建标签。
(即使你最终在你的JSP代码中使用java,我希望不会,你可以将该代码封装在标签中)
答案 27 :(得分:1)
正如许多答案所说,使用JSTL或创建自己的自定义标签。 Here是关于创建自定义标记的很好的解释
答案 28 :(得分:1)
这种方法的好处是您的代码也像HTML 代码!
答案 29 :(得分:0)
这里的许多答案都是“使用框架”路线。零错。但是,我认为这并不能真正回答您的问题,因为框架可能会也可能不会使用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,也不想这样做。该功能存在是有原因的。
答案 30 :(得分:-1)
通过将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" %>