仅当页面数量少或需要精确控制生成的内容(二进制PDF等)时,才可以从Servlet生成HTML。 对于大多数应用程序,输出将是HTML,我们需要一种更好的方法来完成此操作。 这就是JSP(Java服务器页面)出现的地方。
使用JSP,您可以编写并关注文件中HTML内容。 只有在内容之间需要动态或条件逻辑时,才插入Java代码,称为Scriptlet。 当应用程序服务器处理JSP页面时,它将自动生成一个Servlet类,将这些JSP文件的内容写出(就像您以前用PrintWriter
编程编写它一样)。 在JSP中的任何地方,只要有Scriptlet,它都将内联在生成的Servlet类中。 生成的jsp servlet类全部由应用程序中的应用程序服务器自动管理,编译和部署。 简而言之,JSP只不过是Servlet的反向外壳。
这是一个简单的JSP示例,可以打印Hello World和服务器时间戳。
<!DOCTYPE html>
<html><body><p>Hello World!</p><p>Page served on <%= new java.util.Date()%></p></body>
</html>
只需将其另存为基于src/main/webapp
maven的文件夹中名为hello.jsp
文本文件, hello.jsp
在NetBeans IDE中运行。 对于JSP,您不需要像Serlvet中那样配置URL映射,并且可以从上下文路径直接访问URL映射。 例如,以上内容应通过http:// localhost:8080 / hello.jsp URL在浏览器中显示。
请注意,该示例还显示了如何嵌入Java代码。 您可以在<%= %>
scriptlet内放置一个方法或对象,它将使用结果对象的toString()
方法输出连接到scriptlet标记之外HTML。 您也可以使用<%! %>
定义新方法<%! %>
<%! %>
scriptlet标记,或使用<% %>
scriptlet执行任何不会生成输出的代码。 注意,您也可以在JSP中的<%-- --%>
脚本之间添加注释。
JSP还允许您插入“页面指令”以控制JSP容器如何呈现结果。 例如,您可以通过将其插入页面顶部来更改结果内容类型
<%@ page contentType="text/txt" %>
另一个经常使用的页面指令是import Java package,因此您不需要在每个Java语句行上添加前缀。
<%@ page imporet="java.util.*" %>...<p>Page served on <%= new Date()%></p>
您可以使用更多指令。 请查看JSP规范文档以获取更多详细信息。
除了插入自己的Java代码外,JSP还预定义了一些变量,您可以在不声明它们的情况下直接访问它们。 这是显示大多数这些内置隐式变量的示例。
<!DOCTYPE html>
<html><body><h1>JSP Examples</h1><p>Implicit Variables</p><table><tr><td>Name</td><td>Instance</td><td>Example</td></tr><tr><td>applicationScope</td><td>${applicationScope}</td><td>${applicationScope['myAppName']}</td></tr><tr><td>sessionSope</td><td>${sessionSope}</td><td>${sessionSope['loginSession']}</td></tr><tr><td>pageScope</td><td>${pageScope}</td><td>${pageScope['javax.servlet.jsp.jspConfig']}</td></tr><tr><td>requestScope</td><td>${requestScope}</td><td>${requestScope['foo']}</td></tr><tr><td>param</td><td>${param}</td><td>${param['query']}</td></tr><tr><td>header</td><td>${header}</td><td>${header['user-agent']}</td></tr><tr><td>cookie</td><td>${cookie}</td><td>${cookie['JSESSIONID']}</td></tr><tr><td>pageContext</td><td>${pageContext}</td><td>${pageContext.request.contextPath}</td></tr></table><p>Page served on <%= new java.util.Date()%></p></body>
</html>
在上面的示例中,我使用JSP表达式语言(EL)语法而不是
<%=%>脚本。 EL更紧凑且更易于阅读,但是它只能读取存在于任何请求,会话或应用程序范围中的变量。 EL使用DOT表示法访问对象变量中的字段甚至嵌套字段。 假设这些字段具有相应的getter方法。 EL还可以使用“ myMap [key]”格式访问地图,或使用“ myList [index]”语法访问列表。 这些隐式变量中的大多数都可以作为Map对象进行访问,它们像在您自己的Servlet类中一样,主要从请求上的ServletHttpRequest
对象公开。
JSP可以被视为Web应用程序中的模板语言。 它有助于生成应用程序的“ VIEW”部分。 它使您或团队中的创作者可以专注于HTML以及内容的外观。 它可以帮助更轻松地构建更大的Web应用程序。 不过,在JSP文件中使用过多和复杂的逻辑Java代码时要小心,因为它会使调试和读取变得更加困难。 尤其是当您有抛出异常的Java语句时。 stacktrace中的行号将更难跟踪并与您的Scriptlet代码匹配。 还要想象一下,如果您开始在JSP文件中包含JavaScript代码,那么它可能会变得非常混乱。 最好将它们保存在单独的文件中。 如果必须将Java代码嵌入JSP中,请尝试将其包装在一行Java调用调用中。 更好的方法是,尝试使用Servlet代码处理请求,并通过将它们插入请求作用域空间中,然后将其转发到JSP文件进行渲染,来生成需要在JSP中显示的所有数据。 使用这种模式,您实际上可以限制JSP中scriptlet的使用,并且仅使用EL和JSP标记。
- 您可以在GitHub的jsp-example中找到上述代码。
翻译自: https://www.javacodegeeks.com/2015/01/ee-jsp-the-reversed-jacket-of-servlet.html