我知道类似以下三行

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

是一种老式的编码方式,在JSP版本2中存在一种避免JSP文件中出现Java代码的方法。什么是可选的JSP2行,这种技术叫什么?


当前回答

学习使用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中创建文件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>

其他回答

JSTL为条件、循环、集合、get等提供标记。例如:

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

JSTL与请求属性一起工作——它们通常由Servlet在请求中设置,Servlet转发到JSP。

这里的很多答案都是“使用框架”。这没有错。然而,我认为这并不能真正回答您的问题,因为框架可能使用JSP,也可能不使用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动态地提供任何类型的内容。它们是几乎所有javaweb-JSP背后的主要技术——实际上,JSP只是servlet的HTML模板。因此,您应该在JSP中放入多少java的答案是“尽可能少”。我的JSP中当然有java,但它只包含标记库定义、会话和客户端变量以及封装服务器端对象的bean。HTML中的<%%>标记几乎完全是属性调用或变量表达式。罕见的例外情况包括与单个页面相关的超特定计算,且不太可能重复使用;仅适用于一个页面的页面特定问题导致的错误修复;最后一分钟的连接和运算源于不寻常的要求,其范围仅限于单个页面;以及其他类似情况。在一个150万行、3000个JSP和5000个类的代码集中,可能有100个这样的独特片段的实例。在类或标记库定义中进行这些更改是完全可能的,但由于每种情况的特殊性,它会变得异常复杂,编写和调试需要更长的时间,因此需要更多的时间才能与我的用户联系。这是一个判断。但是不要搞错,你不能用“no java”来编写任何意义的JSP,你也不想这样做。

经验表明,JSP有一些缺点,其中之一是很难避免将标记与实际代码混合。

如果可以,那么可以考虑使用专门的技术来完成您需要做的事情。在JavaEE6中有JSF2.0,它提供了许多不错的功能,包括通过#{bean.method(argument)}方法将Javabean与JSF页面粘合在一起。

JSP2.0有一个名为“标记文件”的特性,您可以在没有外部Java代码和tld的情况下编写标记。您需要创建一个.tag文件并将其放入WEB-INF\tag中。您甚至可以创建一个目录结构来打包标记。

例如:

/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/selected文本操作,如format/inclusions/capital或甚至SQL标记select/update),传递所有类型的参数,例如Hashmap、访问会话、请求等。。。在您的标记文件中。

标记文件非常容易开发,因为在更改它们时不需要重新启动服务器,就像JSP文件一样。这使它们易于开发。

即使您使用Struts2这样的框架,它有很多好的标记,您可能会发现拥有自己的标记可以大大减少代码。您可以将标记参数传递给struts,并通过这种方式自定义框架标记。

您不仅可以使用标记来避免Java,还可以最小化HTML代码。当我看到页面中出现重复的代码时,我自己会尝试检查HTML代码并构建标记。

(即使您最终在JSP代码中使用Java(我希望不会),也可以将该代码封装在标记中。)

作为保障:永远禁用Scriptlets

正如另一个问题所讨论的,您可以并且应该始终禁用web.xml web应用程序描述符中的scriptlets。

我会一直这样做,以防止任何开发人员添加脚本,特别是在大公司中,您迟早会失去概述。web.xml设置如下所示:

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