我刚接触javaee,我知道下面三行
<%= x+1 %><%= request.getParameter("name") %><%! counter++; %>
<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>
是一种老式的编码方式,在jsp版本2中存在一种避免jsp文件中出现java代码的方法。可供选择的jsp2行是什么,这种技术叫什么?
toiithl61#
scriptlet的使用(那些 <% %> 自从taglibs(如jstl)和el(expression language,即 ${} 事情)早在2001年。scriptlet的主要缺点是:可重用性:不能重用scriptlet。可替换性:不能将scriptlet抽象化。oo能力:你不能使用继承/组合。可调试性:如果scriptlet中途抛出异常,那么得到的只是一个空白页。可测试性:scriptlet不是单元可测试的。可维护性:每个saldo都需要更多的时间来维护混合/混乱/重复的代码逻辑。sunoracle本身也在jsp编码约定中建议,只要(tag)类可以实现相同的功能,就不要使用scriptlet。以下是几个相关的例子:根据jsp1.2规范,强烈建议在web应用程序中使用jsp标准标记库(jstl),以帮助减少页面中对jsp脚本的需求。通常,使用jstl的页面更易于阅读和维护。...在可能的情况下,只要标记库提供等效的功能,就避免使用jsp scriptlet。这使页面更易于阅读和维护,有助于将业务逻辑与表示逻辑分离,并使页面更容易演变为jsp2.0样式的页面(jsp2.0规范支持但不强调scriptlet的使用)。...本着采用模型-视图-控制器(model-view-controller,mvc)设计模式从业务逻辑上减少表示层之间耦合的精神,jsp脚本不应该用于编写业务逻辑。相反,如果需要,可以使用jsp scriptlet将处理客户机请求返回的数据(也称为“值对象”)转换为适合客户机的格式。即使这样,最好使用前端控制器servlet或自定义标记来完成。如何替换scriptlet完全取决于代码/逻辑的唯一用途。这段代码经常被放在一个完整的java类中:如果您希望在每个请求上调用相同的java代码,不管请求的页面是多少,例如检查用户是否登录,那么实现一个过滤器并相应地在中编写代码 doFilter() 方法。例如。:
<% %>
${}
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. }}
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.
}
当Map到适当的 <url-pattern> 覆盖感兴趣的jsp页面,就不需要在整个jsp页面上复制粘贴同一段代码。如果您想调用一些java代码来预处理请求,例如从数据库中预加载一些列表以显示在某个表中,如果需要的话,可以基于一些查询参数,然后实现一个servlet并在中相应地编写代码 doGet() 方法。例如。:
<url-pattern>
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); }}
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之前访问的。您仍然可以在db访问抛出异常时更改响应。在上面的示例中,将显示默认错误500页,您可以通过 <error-page> 在 web.xml .如果您想调用一些java代码来对请求进行后处理,例如处理表单提交,那么就实现一个servlet并在中相应地编写代码 doPost() 方法。例如。:
<error-page>
web.xml
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. }}
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.
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的front controller模式实现一个servlet。例如。:
${message}
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); }}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
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);
response.sendRedirect(view);
} catch (Exception e) {
throw new ServletException("Executing action failed.", e);
或者采用一个mvc框架,比如jsf、springmvc、wicket等,这样您就只需要一个jsp/facelets页面和一个javabean类,而不需要定制servlet。如果您想调用一些java代码来控制jsp页面中的流,那么您需要获取一个(现有的)流控制taglib,比如jstlcore。e、 g.显示 List<Product> 在表格中:
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>
<%@ 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,因此代码的可读性(因而可维护性)比一堆带有各种大括号的scriptlet要好(“这个大括号到底属于哪里?”)。一个简单的辅助方法是,通过将以下内容添加到 web.xml :
<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group></jsp-config>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
facelets是jsp的继承者,jsp是javaee提供的mvc框架jsf的一部分,在facelets中,已经不可能使用scriptlets了。这样你就自然而然地被迫以“正确的方式”做事。如果您想调用一些java代码来访问和显示jsp页面中的“后端”数据,那么您需要使用el(expression language),这些 ${} 东西。e、 g.重新显示提交的输入值:
<input type="text" name="foo" value="${param.foo}" />
这个 ${param.foo} 显示的结果 request.getParameter("foo") .如果您想直接在jsp页面中调用一些实用程序java代码(通常是 public static 方法),然后需要将它们定义为el函数。jstl中有一个标准函数taglib,但是您也可以自己轻松地创建函数。下面是一个jstl fn:escapeXml 有助于防止XSATTACK。
${param.foo}
request.getParameter("foo")
public static
fn:escapeXml
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>...<input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
<%@ 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/whatever没有任何特定的关系,在您开发的每个web应用程序中都需要考虑这个问题。scriptlets的问题是它没有提供内置的预防方法,至少没有使用标准的javaapi。jsp的后继facelets已经隐含了html转义,所以您不必担心facelets中的xss漏洞。
jsp、servlet和jsf之间有什么区别?servlet、servletcontext、httpsession和httpservletrequest/response是如何工作的?带有jsp、servlet和jdbc的基本mvc示例javaweb应用程序中的设计模式jsp/servlet的隐藏特性
gijlo24d2#
您可以将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>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ 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>
wtlkbnrh3#
还有一些基于组件的框架,比如wicket,可以为您生成大量的html。最终出现在html中的标记是非常基本的,实际上没有任何逻辑混合在一起。结果几乎是空的,就像带有典型html元素的html页面一样。缺点是wicketapi中有很多组件需要学习,在这些约束条件下有些事情很难实现。
5vf7fwbs4#
jstl为条件、循环、集合、获取等提供标记,例如:
<c:if test="${someAttribute == 'something'}"> ...</c:if>
<c:if test="${someAttribute == 'something'}">
</c:if>
jstl处理请求属性—它们通常由一个servlet在请求中设置,servlet转发给jsp。
gcxthw6b5#
经验表明,jsp有一些缺点,其中之一就是很难避免将标记与实际代码混合在一起。如果可以的话,可以考虑使用专门的技术来完成你需要做的事情。在JavaEE6中有JSF2.0,它提供了很多很好的特性,包括通过 #{bean.method(argument)} 接近。
#{bean.method(argument)}
c86crjj06#
无论您如何避免,当您与其他开发人员一起工作时,他们中的一些人仍然会喜欢scriptlet,然后插入邪恶的c
3gtaxfhh7#
学习使用jstl自定义和编写自己的标记注意el是邪恶的(运行时异常和重构)。wicket也可能是邪恶的(对于小型应用程序或简单的视图层来说,性能和麻烦)。
必须将其添加到web应用程序的web.xml中
<taglib> <taglib-uri>/java2s</taglib-uri> <taglib-location>/WEB-INF/java2s.tld</taglib-location></taglib>
<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>
<!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>
将以下代码编译成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; }}
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>
<%@ taglib uri="/java2s" prefix="java2s" %>
<title>A custom tag: body content</title>
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>
a11xaf1n8#
如果您只是想避免jsp中java编码的缺点,那么即使使用scriplets也可以这样做。只需遵循一些规则,在jsp中使用最少的java,而在jsp页面中几乎没有计算和逻辑。
<%@ page contentType="text/html;charset=UTF-8" language="java" %><% // Instantiate a JSP controllerMyController clr = new MyController(request, response);// Process action, if anyclr.process(request);// Process page forwarding, if necessary// Do all variable assignment hereString 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>
<% // 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();%>
<form name="frm1">
<p><%= showMe %>
<p><% for(String str : clr.listOfStrings()) { %>
<p><%= str %><% } %>
// And so on
</form>
vtwuwzda9#
在mvc架构模式中,jsp表示视图层。在jsp中嵌入java代码被认为是一种不好的做法。您可以将jstl、freemarker和velocity与jsp一起用作“模板引擎”。这些标记的数据提供者取决于您正在处理的框架。struts2和webwork作为mvc模式的一个实现,使用ognl“非常有趣的技术将bean属性公开给jsp”。
mcvgt66p10#
作为保护措施:永远禁用scriptlet正如另一个正在讨论的问题,您可以而且应该始终禁用 web.xml web应用程序描述符。我总是这样做是为了防止任何开发人员添加scriptlet,特别是在大公司中,在那里您迟早会失去概述。这个 web.xml 设置如下所示:
oo7oh9g911#
你提出了一个很好的问题,虽然你得到了很好的答案,但我建议你摆脱jsp。这是过时的技术,最终会消亡。使用现代方法,如模板引擎。您将有非常清晰的业务层和表示层分离,而且模板中肯定没有java代码,因此您可以直接从web表示编辑软件生成模板,在大多数情况下利用所见即所得。当然要远离过滤器和前后处理,否则您可能会遇到支持/调试困难,因为您总是不知道变量从何处获取值。
zbsbpyhn12#
wicket也是一种将java与html完全分离的替代方法,因此设计者和程序员可以在彼此不太了解的情况下,在不同的代码集上协同工作。看看小门。
12条答案
按热度按时间toiithl61#
scriptlet的使用(那些
<% %>
自从taglibs(如jstl)和el(expression language,即${}
事情)早在2001年。scriptlet的主要缺点是:
可重用性:不能重用scriptlet。
可替换性:不能将scriptlet抽象化。
oo能力:你不能使用继承/组合。
可调试性:如果scriptlet中途抛出异常,那么得到的只是一个空白页。
可测试性:scriptlet不是单元可测试的。
可维护性:每个saldo都需要更多的时间来维护混合/混乱/重复的代码逻辑。
sunoracle本身也在jsp编码约定中建议,只要(tag)类可以实现相同的功能,就不要使用scriptlet。以下是几个相关的例子:
根据jsp1.2规范,强烈建议在web应用程序中使用jsp标准标记库(jstl),以帮助减少页面中对jsp脚本的需求。通常,使用jstl的页面更易于阅读和维护。
...
在可能的情况下,只要标记库提供等效的功能,就避免使用jsp scriptlet。这使页面更易于阅读和维护,有助于将业务逻辑与表示逻辑分离,并使页面更容易演变为jsp2.0样式的页面(jsp2.0规范支持但不强调scriptlet的使用)。
...
本着采用模型-视图-控制器(model-view-controller,mvc)设计模式从业务逻辑上减少表示层之间耦合的精神,jsp脚本不应该用于编写业务逻辑。相反,如果需要,可以使用jsp scriptlet将处理客户机请求返回的数据(也称为“值对象”)转换为适合客户机的格式。即使这样,最好使用前端控制器servlet或自定义标记来完成。
如何替换scriptlet完全取决于代码/逻辑的唯一用途。这段代码经常被放在一个完整的java类中:
如果您希望在每个请求上调用相同的java代码,不管请求的页面是多少,例如检查用户是否登录,那么实现一个过滤器并相应地在中编写代码
doFilter()
方法。例如。:当Map到适当的
<url-pattern>
覆盖感兴趣的jsp页面,就不需要在整个jsp页面上复制粘贴同一段代码。如果您想调用一些java代码来预处理请求,例如从数据库中预加载一些列表以显示在某个表中,如果需要的话,可以基于一些查询参数,然后实现一个servlet并在中相应地编写代码
doGet()
方法。例如。:这种处理异常的方法更容易。数据库不是在jsp呈现过程中访问的,而是在显示jsp之前访问的。您仍然可以在db访问抛出异常时更改响应。在上面的示例中,将显示默认错误500页,您可以通过
<error-page>
在web.xml
.如果您想调用一些java代码来对请求进行后处理,例如处理表单提交,那么就实现一个servlet并在中相应地编写代码
doPost()
方法。例如。:这种处理不同结果页目的地的方法更容易:在出现错误的情况下重新显示带有验证错误的表单(在这个特定示例中,您可以使用
${message}
在el中),或者在成功的情况下直接转到所需的目标页。如果您想调用一些java代码来控制执行计划和/或请求和响应的目标,那么根据mvc的front controller模式实现一个servlet。例如。:
或者采用一个mvc框架,比如jsf、springmvc、wicket等,这样您就只需要一个jsp/facelets页面和一个javabean类,而不需要定制servlet。
如果您想调用一些java代码来控制jsp页面中的流,那么您需要获取一个(现有的)流控制taglib,比如jstlcore。e、 g.显示
List<Product>
在表格中:由于xml样式的标记非常适合所有html,因此代码的可读性(因而可维护性)比一堆带有各种大括号的scriptlet要好(“这个大括号到底属于哪里?”)。一个简单的辅助方法是,通过将以下内容添加到
web.xml
:facelets是jsp的继承者,jsp是javaee提供的mvc框架jsf的一部分,在facelets中,已经不可能使用scriptlets了。这样你就自然而然地被迫以“正确的方式”做事。
如果您想调用一些java代码来访问和显示jsp页面中的“后端”数据,那么您需要使用el(expression language),这些
${}
东西。e、 g.重新显示提交的输入值:这个
${param.foo}
显示的结果request.getParameter("foo")
.如果您想直接在jsp页面中调用一些实用程序java代码(通常是
public static
方法),然后需要将它们定义为el函数。jstl中有一个标准函数taglib,但是您也可以自己轻松地创建函数。下面是一个jstlfn:escapeXml
有助于防止XSATTACK。请注意,xss敏感性与java/jsp/jstl/el/whatever没有任何特定的关系,在您开发的每个web应用程序中都需要考虑这个问题。scriptlets的问题是它没有提供内置的预防方法,至少没有使用标准的javaapi。jsp的后继facelets已经隐含了html转义,所以您不必担心facelets中的xss漏洞。
另请参见:
jsp、servlet和jsf之间有什么区别?
servlet、servletcontext、httpsession和httpservletrequest/response是如何工作的?
带有jsp、servlet和jdbc的基本mvc示例
javaweb应用程序中的设计模式
jsp/servlet的隐藏特性
gijlo24d2#
您可以将jstl标记与el表达式一起使用,以避免java和html代码混合使用:
wtlkbnrh3#
还有一些基于组件的框架,比如wicket,可以为您生成大量的html。
最终出现在html中的标记是非常基本的,实际上没有任何逻辑混合在一起。结果几乎是空的,就像带有典型html元素的html页面一样。缺点是wicketapi中有很多组件需要学习,在这些约束条件下有些事情很难实现。
5vf7fwbs4#
jstl为条件、循环、集合、获取等提供标记,例如:
jstl处理请求属性—它们通常由一个servlet在请求中设置,servlet转发给jsp。
gcxthw6b5#
经验表明,jsp有一些缺点,其中之一就是很难避免将标记与实际代码混合在一起。
如果可以的话,可以考虑使用专门的技术来完成你需要做的事情。在JavaEE6中有JSF2.0,它提供了很多很好的特性,包括通过
#{bean.method(argument)}
接近。c86crjj06#
无论您如何避免,当您与其他开发人员一起工作时,他们中的一些人仍然会喜欢scriptlet,然后插入邪恶的c
3gtaxfhh7#
学习使用jstl自定义和编写自己的标记
注意el是邪恶的(运行时异常和重构)。
wicket也可能是邪恶的(对于小型应用程序或简单的视图层来说,性能和麻烦)。
java2s示例
必须将其添加到web应用程序的web.xml中
在/web inf中创建文件java2s.tld/
将以下代码编译成web inf\classes\com\java2s
启动服务器并在浏览器中加载bodycontent.jsp文件:
a11xaf1n8#
如果您只是想避免jsp中java编码的缺点,那么即使使用scriplets也可以这样做。只需遵循一些规则,在jsp中使用最少的java,而在jsp页面中几乎没有计算和逻辑。
vtwuwzda9#
在mvc架构模式中,jsp表示视图层。在jsp中嵌入java代码被认为是一种不好的做法。
您可以将jstl、freemarker和velocity与jsp一起用作“模板引擎”。
这些标记的数据提供者取决于您正在处理的框架。struts2和webwork作为mvc模式的一个实现,使用ognl“非常有趣的技术将bean属性公开给jsp”。
mcvgt66p10#
作为保护措施:永远禁用scriptlet
正如另一个正在讨论的问题,您可以而且应该始终禁用
web.xml
web应用程序描述符。我总是这样做是为了防止任何开发人员添加scriptlet,特别是在大公司中,在那里您迟早会失去概述。这个
web.xml
设置如下所示:oo7oh9g911#
你提出了一个很好的问题,虽然你得到了很好的答案,但我建议你摆脱jsp。这是过时的技术,最终会消亡。使用现代方法,如模板引擎。您将有非常清晰的业务层和表示层分离,而且模板中肯定没有java代码,因此您可以直接从web表示编辑软件生成模板,在大多数情况下利用所见即所得。
当然要远离过滤器和前后处理,否则您可能会遇到支持/调试困难,因为您总是不知道变量从何处获取值。
zbsbpyhn12#
wicket也是一种将java与html完全分离的替代方法,因此设计者和程序员可以在彼此不太了解的情况下,在不同的代码集上协同工作。
看看小门。