2025年3月18日 星期二 甲辰(龙)年 月十七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Java

在HTML中插入JSP代码

时间:10-11来源:作者:点击数:44

JSP 文件可以只包含 HTML,也可以插入 JSP 代码,客户端发起请求后,HTML和插入的 JSP 脚本都会被翻译成 Servlet 程序,然后再编译并运行。

小脚本格式(scriptlet)

小脚本格式是指可以在 <% 和 %> 之间插入 JSP 代码:

  • <%
  • // JSP Code
  • %>

JSP代码可以包含任意的Java语句、变量、方法或表达式,只要它们是有效的。

你也可以使用类似 XML 的格式插入:

  • <jsp:scriptlet>
  • // JSP Code
  • </jsp:scriptlet>

文本、HTML标签等都必须写在 JSP 的外边,例如:

  • <!DOCTYPE html>
  • <html lang="zh">
  • <head>
  • <meta charset="UTF-8">
  • <title>演示页面</title>
  • </head>
  • <body>
  • <p>
  • 1+2+3+...+99+100 =
  • <%
  • int result = 0;
  • for(int i=1; i<=100; i++){
  • result += i;
  • }
  • out.print(result);
  • %>
  • </p>
  • </body>
  • </html>

将上面的代码保存到 demo.jsp 并放到站点根目录,假设你为当前虚拟主机分配了 www.jspdemo.com 域名,访问 www.jspdemo.com:8080/demo.jsp,就可以看到输出内容。


图1  演示页面

打开 $CATALINA_HOME\\work\Catalina\www.jspdemo.com\_\org\apache\jsp 目录,你会看到由 JSP 翻译生成的 Servlet 程序 demo_jsp.java,部分代码如下所示:

  • package org.apache.jsp;
  • import javax.servlet.*;
  • import javax.servlet.http.*;
  • import javax.servlet.jsp.*;
  • // demo.jsp 页面的内容被转换为 demo_jsp 类
  • public final class demo_jsp extends org.apache.jasper.runtime.HttpJspBase
  • implements org.apache.jasper.runtime.JspSourceDependent {
  • public void _jspInit() {
  • // 初始化
  • }
  • public void _jspDestroy() {
  • // 销毁
  • }
  • // 处理 http 请求,生成 html 代码
  • public void _jspService(final javax.servlet.http.HttpServletRequest request,
  • final javax.servlet.http.HttpServletResponse response)
  • throws java.io.IOException, javax.servlet.ServletException {
  • out.write("<!DOCTYPE html>\r\n");
  • out.write("<html lang=\"zh\">\r\n");
  • out.write("<head>\r\n");
  • out.write(" <meta charset=\"UTF-8\">\r\n");
  • out.write(" <title>演示页面</title>\r\n");
  • out.write("</head>\r\n");
  • out.write("<body>\r\n");
  • out.write("<p>\r\n");
  • out.write(" 1+2+3+...+99+100 = \r\n");
  • out.write(" ");
  • int result = 0;
  • for(int i=1; i<=100; i++){
  • result += i;
  • }
  • out.print(result);
  • out.write("\r\n");
  • out.write("</p>\r\n");
  • out.write("</body>\r\n");
  • out.write("</html>");
  • }
  • }

可以很清楚的看到 JSP 页面翻译生成的 Java 代码,在<%与%>之间的代码都被放到了 _jspService() 方法内部,包括声明的变量,也是局部变量。

声明格式(declaration)

声明格式是指可以在 <%! 和 %> 之间声明变量、方法和类。与小脚本格式不同的是:

  • <% ... %> 声明的是局部变量,会被放到 _jspService() 方法内部。
  • <% .. %> 不能声明方法,因为Java规定方法不能嵌套声明。
  • <%! ... %> 之间声明的是成员变量,由多线程共享。

注意:<%! ... %> 只能用来声明变量、方法和类,不能包含表达式。

也可以使用类似 XML 的格式插入:

  • <jsp:declaration>
  • // JSP Code
  • </jsp:declaration>

示例代码:

  • <!DOCTYPE html>
  • <html lang="zh">
  • <head>
  • <meta charset="UTF-8">
  • <title>演示页面</title>
  • </head>
  • <body>
  • <%!
  • int click = 0;
  • %>
  • <p>
  • 1+2+3+...+99+100 =
  • <%
  • int result = 0;
  • for(int i=1; i<=100; i++){
  • result += i;
  • }
  • out.print(result);
  • click++;
  • %>
  • </p>
  • <p>你是第<%= click %>位访客</p>
  • </body>
  • </html>

生成的 demo_jsp.java 部分代码如下:

  • package org.apache.jsp;
  • import javax.servlet.*;
  • import javax.servlet.http.*;
  • import javax.servlet.jsp.*;
  • public final class demo_jsp extends org.apache.jasper.runtime.HttpJspBase
  • implements org.apache.jasper.runtime.JspSourceDependent {
  • int click = 0;
  • public void _jspInit() {
  • // 初始化
  • }
  • public void _jspDestroy() {
  • // 销毁
  • }
  • public void _jspService(final javax.servlet.http.HttpServletRequest request,
  • final javax.servlet.http.HttpServletResponse response)
  • throws java.io.IOException, javax.servlet.ServletException {
  • out.write("<!DOCTYPE html>\r\n");
  • out.write("<html lang=\"zh\">\r\n");
  • out.write("<head>\r\n");
  • out.write(" <meta charset=\"UTF-8\">\r\n");
  • out.write(" <title>演示页面</title>\r\n");
  • out.write("</head>\r\n");
  • out.write("<body>\r\n");
  • out.write("\r\n");
  • out.write("<p>\r\n");
  • out.write(" 1+2+3+...+99+100 = \r\n");
  • out.write(" ");
  • int result = 0;
  • for(int i=1; i<=100; i++){
  • result += i;
  • }
  • out.print(result);
  • click++;
  • out.write("\r\n");
  • out.write("</p>\r\n");
  • out.write("<p>你是第");
  • out.print( click );
  • out.write("位访客</p>\r\n");
  • out.write("</body>\r\n");
  • out.write("</html>");
  • }
  • }

可以看到在 <%! 和 %> 之间声明的 click 变量被翻译成了一个成员变量,与在 <% 和 %> 之间声明的变量作用域不同,访问权限也不同,<%! 和 %> 之间声明的变量在整个 JSP 页面内都有效。

重复访问该页面,会发现每次访客数量都会增加。

这是因为 Servlet 是单实例多线程的,成员变量在堆区分配内存,并一直存在,由多个线程共享,直到服务器关闭或JSP文件更新。而方法内的局部变量在栈区分配内存,线程结束后将被回收。

也就是说,当多个用户请求一个JSP 页面时,JSP 容器会为每个用户启动一个线程,这些线程由JSP容器来管理,这些线程共享 JSP 页面的成员变量,因此任何一个用户对 JSP 页面成员变量操作的结果,都会影响到其他用户。

demo_jsp 类只会在首次访问时被实例化,以后一直存在,新用户访问页面会启动一个线程,并使用该实例的数据,所以每次刷新页面 click 变量都会加1。

Servlet 单实例多线程的特性提高了程序的执行效率,启动一个线程的代价很小,在高并发量方面有很大的优势。但是它也有副作用,带来了线程安全问题,一个线程对数据的操作会影响到下一个线程。所以我建议,除非有必要,否则不要再 <%! 和 %> 之间声明变量。

表达式格式(expression)

前面的JSP代码,输出IP地址时用到了 out.print() 语句:

  • <% out.println(request.getRemoteAddr()); %>

其实还有一种简写,更加方便:

  • <%= request.getRemoteAddr() %>

示例代码:

  • <!DOCTYPE html>
  • <html lang="zh">
  • <head>
  • <meta charset="UTF-8">
  • <title>演示页面</title>
  • </head>
  • <body>
  • <p>
  • 你的IP地址是:
  • <%= request.getRemoteAddr() %>
  • </p>
  • </body>
  • </html>

也可以使用类似 XML 的格式:

  • <jsp:expression>
  • // JSP Code
  • </jsp:expression>

<%= ... %> 可以认为是 out.print() 语句的简写,用来输出一个变量或表达式的值,注意结尾不能有分号(;)。

提示:<%= 是一个完整的界定符,中间不能有空格。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
上一篇:JSP生命周期 下一篇:JSP注释
推荐内容
相关内容
栏目更新
栏目热门