小吴 发布的文章 - 小吴博客
首页
资源下载
关于
搜 索
1
通过 Tampermonkey 实现学习通全自动刷课
1,287 阅读
2
易语言下载与安装
46 阅读
3
易语言的配置
42 阅读
4
Filter 介绍
19 阅读
5
JSP 脚本中的 9 个内置对象
17 阅读
Java
Java面向对象基础
Java企业应用开发
数据结构
Spring Boot
数据库
Mysql数据库原理
网页前端
HTML/CSS/JS
Vue框架
C++
C++程序设计
计算机网络
概述
物理层
数据链路层
网络层
运输层
应用层
网络安全
互联网上的音频/视频服务
无线网络和移动网络
Linux系统管理
实战教程
其他
易语言
登录
/
注册
搜 索
标签搜索
JSP/Servlet 及相关技术详解
下载与配置
小吴
累计撰写
12
篇文章
首页
分类
Java
Java面向对象基础
Java企业应用开发
数据结构
Spring Boot
数据库
Mysql数据库原理
网页前端
HTML/CSS/JS
Vue框架
C++
C++程序设计
计算机网络
概述
物理层
数据链路层
网络层
运输层
应用层
网络安全
互联网上的音频/视频服务
无线网络和移动网络
Linux系统管理
实战教程
其他
易语言
页面
资源下载
关于
用户登录
登录
注册
找到
12
篇与
小吴
相关的结果
2022-12-29
易语言下载与安装
视频教程资源下载图文教程 本文跟大家讲讲易语言的下载和安装。上面的链接是我给大家打包的易语言应用程序,不需要加密狗,大家自行下载。 易语言下载网站:http://www.dywt.com.cn/ 易语言资源分享:https://www.eyuyan.la/post/11049.html 这两个网站为易语言官方网站,如果有需要可以去官网下载和购买加密狗。加密狗的价格大概在400-600元之间,淘宝也是可以购买的。 下载之后,解压出来是有 3 个文件的——e593_chs.exe、VC6linker 和破解补丁。e593_chs.exe 为易语言安装包,VC6linker 为易语言的链接器。 具体安装步骤如下: ① 双击打开 e593_chs.exe,一直点击下一步直到更改安装路径,这里我们更改一下安装路径,演示安装的路径为 D:\e。最好是不要安装到 C 盘。 ② 选择组件,我们把不需要的组件全部勾掉。最终勾选的组件如下图所示。只留下 Windows 支持库和易语言的静态支持库。后面的安装过程一直下一步即可。 安装易语言过程前,最好是把杀毒软件都关闭,否则可能出现故障的情况。 ③ 易语言安装完成之后先不打开应用,我们找到到易语言的安装目录,把破解补丁文件夹里的 e.exe 复制到易语言的安装目录中,替换掉原来的 e.exe。 ④ 此时,易语言应用程序可以正常打开。 我们试着来创建一个易语言项目。点击“程序”——“新建”——双击“Windows窗口程序”,此时会打开易语言的 UI 编辑界面。 接着点击“编译”——“静态编译”,给文件命名之后保存。 此时我们可以看到下方输出台会提示编译失败。原因是什么呢——静态链接失败,无法定位链接器。问题就是没有链接器或者他没有找到,这个时候就需要我们的第三个文件了——VC6linker。我们把 VC6linker 整个文件夹拖到易语言的安装目录中,然后打开 VC6linker 中的 link 文件,使用易语言应用程序打开。点击上方运行按钮,此时弹出“易语言静态版link.ini修改器”,什么都不要动,我们直接点击修改,修改配置成功后我们直接关闭窗口即可。回到我们刚才的易语言界面中,再次点击“编译”——“静态编译”,给文件命名之后保存,此时我们可以发现已经编译成功,到我们刚才保存的路径下,我们可以看到易语言编译出来的应用程序。到此,易语言的下载与安装便完成了。
2022年12月29日
46 阅读
0 评论
2 点赞
2022-12-25
JSP 的 3 个编译指令
JSP 的编译指令是通知 JSP 引擎的消息,它不直接生成输出。编译指令都有默认值,因此开发人员无须为每个指令设置值。 常见的编译指令有如下三个。 ➢ page:该指令是针对当前页面的指令。 ➢ include:用于指定包含另一个页面。 ➢ taglib:用于定义和访问自定义标签。 使用编译指令的语法格式如下:<%@ 编译指令名 属性名="属性值"···%> 下面主要介绍 page 和 include 指令,关于 taglib 指令,将在自定义标签库处详细讲解。page 指令 page 指令通常位于 JSP 页面的顶端,一个 JSP 页面可以使用多条 page 指令。page 指令的语法格式如下:<%@page [language="Java"] [extends="package.class"] [import="package.class | package.*,..."] [session="true | false"] [buffer="none | 8KB | size Kb"] [autoFlush="true | false"] [isThreadSafe="true | false"] [info="text"] [errorPage="relativeURL"] [contentType="mimeType[;charset=characterSet]" | "text/html;charSet=ISO-8859-1"] [pageEncoding="ISO-8859-1"] [isErrorPage="true | false"] %> 下面依次介绍 page 指令各属性的意义。 ➢ language:声明当前 JSP 页面使用的脚本语言的种类,因为页面是 JSP 页面,该属性的值通常都是 java,该属性的默认值也是 java,所以通常无须设置。 ➢ extends:指定 JSP 页面编译所产生的 Java 类所承的父类,或所实现的接口。 ➢ import: 用来导入包。下面几个包是默认自动导入的,不需要显式导入。默认导入的包有:java.lang.、javax.servlet.、javax.servlet.jsp.、javax.servlet.http.。 ➢ session:设定这个 JSP 页面是否需要 HTTP Session。 ➢ buffer:指定输出缓冲区的大小。输出缓冲区的 JSP 内部对象:out用于缓存 JSP 页面对客户浏览器的输出,默认值为 8KB,可以设置为 none,也可以设置为其他的值,单位为 KB。 ➢ autoFlush:当输出缓冲区即将溢出时,是否需要强制输出缓冲区的内容。设置为 true 时为正常输出;如果设置为 false,则会在 buffer 溢出时产生一个异常。 ➢ info:设置该 JSP 程序的信息,也可以看做其说明,可以通过 Servlet.getServletInfo()方法获取该值。如果在 JSP 页面中,可直接调用 getServletInfo()方法获取该值,因为 JSP 页面的实质就是 Servlet。 ➢ errorPage:指定错误处理页面。如果本页面产生了异常或者错误,而该 JSP 页面没有对应的处理代码,则会自动调用该属性所指定的JSP页面。 因为 JSP 内建了异常机制支持,所以 JSP 可以不处理异常,即使是 checked 异常。 ➢ isErrorPage:设置本 JSP 页面是否为错误处理程序。如果该页面本身已是错误处理页面,则通常无须指定 errorPage 属性。 ➢ contentType:用于设定生成网页的文件格式和编码字符集,即 MIME 类型和页面字符集类型,默认的 MIME 类型是 text/html;默认的字符集类型为 ISO-8859-1。 ➢ pageEncoding:指定生成网页的编码字符集。 从JSP 的 4 种基本语法中执行数据库操作的 JSP 页面中可以看出,在basicSyntax\connDb.jsp 页面的头部,使用了两条 page 指令:<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@ page import="java.sql.*" %> 其中第二条指令用于导入本页面中使用的类,如果没有通过 page 指令的 import 属性导入这些类,则需在脚本中使用全限定类名——即必须带包名。可见,此处的 import 属性类似于 Java 程序中的 import 关键字的作用。 如果删除第二条 page 指令,则执行效果如下图所示。 看下面的 JSP 页面,该页面使用 page 指令的 info 属性指定了 JSP 页面的描述信息,又使用 getServletInfo()方法输出该描述信息。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <!--指定info信息--> <%@ page info="this is a jsp"%> <!DOCTYPE html> <html> <head> <title> 测试page指令的info属性 </title> </head> <body> <!-- 输出info信息 --> <%=getServletInfo() %> </body> <html> 以上页面的第 3 行代码设置了 info 属性,用于指定该 JSP 页面的描述信息;第 11 行代码使用了getServletInfo()方法来访问该描述信息。 在浏览器中执行该页面,将看到如下图所示的效果。 errorPage 属性的实质是 JSP 的异常处理机制,JSP 脚本不要求强制处理异常,即使该异常是checked异常。如果 JSP 页面在运行中抛出未处理的异常,系统将自动跳转到 errorPage 属性指定的页面;如果 errorPage 没有指定错误页面,系统则直接把异常信息呈现给客户端浏览器——这是所有的开发者都不愿意见到的场景。 看下面的 JSP 页面,该页面设置了 page 指令的 errorPage 属性,该属性指定了当本页面发生异常时的异常处理页面。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="error.jsp" %> <!DOCTYPE html> <html> <head> <title> new document </title> </head> <body> <% // 下面代码将出现运行时异常 int a = 6; int b = 0; int c = a / b; %> </body> <html> 以上页面的 errorPage 属性指定 errorTest.jsp 页面(上面的页面)的错误处理页面是 error.jsp。下面是 error.jsp 页面,该页面本身是错误处理页面,因此将 isErrorPage 设置成true。<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%> <!DOCTYPE html> <html> <head> <title> 错误提示页面 </title> </head> <body> <!-- 提醒客户端系统出现异常 --> 系统出现异常<br/> </body> </html> 上面页面的 isErrorPage 属性指定error.jsp 页面是一个错误处理页面。在浏览器中浏览 errorTest.jsp 页面的效果如下图所示。 如果将前一个页面中 page 指令的 errorPage 属性删除,再次通过浏览器浏览该页面,执行效果如下图所示。 可见,使用 errorPage 属性控制异常处理的效果在表现形式上要好得多。 关于 JSP 异常,在介绍 exception 内置对象时还会有更进一步的解释。include 指令 使用 include 指令,可以将一个外部文件嵌入到当前 JSP 文件中,同时解析这个页面中的 JSP 语句(如果有的话)。这是个静态的 inude 语句,它会把目标页面的其他编译指令也包含进来,但动态 include 则不会。 include 既可以包含静态的文本,也可以包含动态的 JSP 页面。静态的 include 编译指令会将被包含的页面加入本页面,融合成一个页面,因此被包含页面甚至不需要是一个完整的页面。 include 编译指令的语法如下:<%@include file="relativeURISpec"%> 如果被嵌入的文件经常需要改变,建议使用<jsp:include>操作指令,因为它是动态的 include 语句。 下面的页面是使用静态导入的示例代码。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <!DOCTYPE html> <html> <head> <title> 静态include测试 </title> </head> <body> <!-- 使用include编译指定导入页面 --> <%@include file="scriptlet.jsp"%> </body> </html> 以上页面中第 9 行代码使用静态导入的语法将 scriptlet.jsp 页面导入本页,该页面的执行效果与 scriptlet.jsp 的执行效果相同。 scriptlet.jsp 为JSP 的 4 种基本语法中的小脚本测试页 查看 Tomcat 的 work\Catalina\localhost\directive\org\apache\jsp 路径下的 staticInclude_jsp.java文件,从 staticInclude.jsp 编译后的源代码可看到,staticInclude.jsp 页面已经完全将 scriptlet.jsp 的代码融入到本页面中。下面是 staticInclude_jsp.java 文件的片段:out.write("<table bgcolor=\"#9999dd\" border=\"1\" width=\"300px\">\r\n"); out.write("<!-- Java脚本,这些脚本会对HTML的标签产生作用 -->\r\n"); for(int i = 0; i < 10; i++){ out.write("\r\n"); out.write(" <!-- 上面的循环将控制<tr>标签循环 -->\r\n"); out.write(" <tr>\r\n"); out.write(" <td>循环值:</td>\r\n"); out.write(" <td>"); out.print(i); out.write("</td>\r\n"); out.write(" </tr>\r\n"); } 上面这些页面代码并不是由 staticInclude.jsp 页面所生成的,而是由 scriptlet.jsp 页面生成的。也就是说,scriptlet.jsp 页面的内容被完全融入 staticInclude.jsp 页面所生成的 Servlet 中,这就是静态包含意义:包含页面在编译时将完全包含了被包含页面的代码。 需要指出的是,静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突,那么页面就会出错。
2022年12月25日
7 阅读
0 评论
3 点赞
2022-12-25
JSP 的 4 种基本语法
前面已经讲过,编写 JSP 页面非常简单:在静态 HTML 页面中“镶”动态 Java 脚本即可。现在开始学习的内容是:JSP 页面的 4 种基本语法——也就是 JSP 允许在静态 HTML 页面中“镶嵌”的成分。掌握这4种语法之后,读者即可按如下步骤开发JSP页面。 ① 编写一个静态 HTML 页面。 ② 用合适的语法向静态 HTML 页面中“镶嵌”4 种基本语法的一种或多种,这样即可为静态 HTML 页面增加动态内容。JSP 注释 JSP 注释用于标注在程序开发过程中的开发提示,它不会输出到客户端 JSP注释的格式如下:<%-- 注释内容 --%> 与 JSP 注释形成对比的是 HTML 注释,HTML 注释的格式是:<!-- 注释内容 --> 看下面的 JSP 页面。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <html> <head> <title> 注释示例 </title> </head> <body> 注释示例 <!-- 增加 JSP 注释 --> <%-- JSP 注释部分 --%> <!-- 增加 HTML 注释 --> <!-- HTML 注释部分 --> </body> </html> 上面的页面中第 9 行代码是 JSP 注释,其他注释都是 HTML 注释。在浏览器中浏览该页面,看页面源代码,页面的源代码如下:<html> <head> <title> 注释示例 </title> </head> <body> 注释示例 <!-- 增加 JSP 注释 --> <!-- 增加 HTML 注释 --> <!-- HTML 注释部分 --> </body> </html> 在上面的源代码中可看到,HTML 的注释可以通过源代码查看到,但 JSP 的注释是无法通过源代码查看到的。这表明 JSP 注释不会被发送到客户端。JSP 声明 JSP 声明用于声明变量和方法。在 JSP 声明中声明方法看起来很特别,似乎不需要定义类就可以直接定义方法,方法似乎可以脱离类独立存在。实际上,JSP 声明将会转换成对应 Servlet 的成员变量或成员方法,因此 JSP 声明依然符合 Java 语法。 JSP 声明的语法格式如下:<%! 声明部分 %> 看下面使用JSP声明的示例页面。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <!DOCTYPE html> <html> <head> <title>Document</title> </head> <!-- 下面是 JSP 声明部分 --> <%! // 声明一个整型变量 public int count; // 声明一个方法 public String info(){ return "hello"; } %> <body> <% out.println(count++); %> <br/> <% // 输出 info() 方法的返回值 out.println(info()); %> </body> </html> 在浏览器中测试该页面时,可以看到正常输出了 count 值,每刷新一次,count 值将加 1,同时也可以看到正常输出了 info()方法的返回值。 上面的代码中声明了一个整型变量和一个普通方法,表面上看起来这个变量和方法不属于任何类,似乎可以独立存在,但这只是一个假象。打开 Tomcat 的 work\Catalina\localhost\basicSyntax\org\apache\jsp 目录下的 declare_jsp.java 文件,看到如下代码片段:public final class declare_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { // 声明一个整型变量 public int count; // 声明一个方法 public String info(){ return "hello"; } ··· } 上面的代码与 JSP 页面的声明部分完全对应,这表明 JSP 页面的声明部分将转换成对应Servlet的成员变量或成员方法。 由于 JSP 声明语法定义的变量和方法对应于 Servlet 类的成员变量和方法,所以 JSP 声明部分定义的变量和方法可以使用 private、public 等访问控制符修饰,也可使用 static 修饰,将其变成类属性和类方法。但不能使用 abstract 修饰声明部分的方法,因为抽象方法将导致 JSP 对应 Servlet 变成抽象类,从而导致无法实例化。 打开多个浏览器,甚至可以在不同的机器上打开浏览器来刷新该页面,将发现所有客户端访问的 count 值是连续的,即所有客户端共享了同一个 count 变量。这是因为:JSP 页面会编译成一个 Servlet 类,每个 Servlet 在容器中只有一个实例;在 JSP 中声明的变量是成员变量,成员变量只在创建实例时初始化,该变量的值将一直保存,直到实例销毁。 值得注意的是,info()的值也可正常输出。因为 JSP 声明的方法其实是在 JSP 编译中生成的 Servlet 的实例方法——Java 里的方法是不能独立存在的,即使在 JSP 页面中也不行。 JSP 声明中独立存在的方法,只是一种假象。输出 JSP 表达式 JSP 提供了一种输出表达式值的简单方法,输出表达式值的语法格式如下:<%=表达式%> 看下面的 JSP 页面,该页面使用输出表达式的方式输出变量和方法返回值。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <!DOCTYPE html> <html> <head> <title> 输出表达式 </title> </head> <%! public int count; public String info(){ return "hello"; } %> <body> <!-- 使用表达式输出变量值 --> <%=count++%> <br/> <!-- 使用表达式输出方法返回值 --> <%=info()%> </body> </html> 上面的页面中 body 标签内的代码使用输出表达式的语法代替了原来的 out.println 输出语句,该页面的执行效果与前一个页面的执行效果没有区别。由此可见,输出表达式将转换成 Servlet 里的输出语句。 输出表达式语法后不能有分号。JSP 脚本 以前 JSP 脚本的应用非常广泛,因此 JSP 脚本里可以包含任何可执行的的 Java 代码。通常来说,所有可执行性 Java 代码都可通过 JSP 脚本嵌入 HTML 页面。看下面使用 JSP 脚本的示例程序。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <!DOCTYPE html> <html> <head> <title> 小脚本测试 </title> </head> <body> <table bgcolor="#9999dd" border="1" width="300px"> <!-- Java脚本,这些脚本会对HTML的标签产生作用 --> <% for(int i = 0; i < 10; i++){ %> <!-- 上面的循环将控制<tr>标签循环 --> <tr> <td>循环值:</td> <td><%=i%></td> </tr> <% } %> </table> </body> </html> 上面的页面中 for 循环语句就是使用 JSP 脚本的代码,这些代码可以控制页面中静态内容。上面例子程序将<tr.../>标签循环 10 次,即生成一个 10 行的表格,并在表格中输出表达式值。 在浏览器中浏览该页面,将看到如下图所示的效果。 接下来打开 Tomcat 的 work\Catalina\localhost\basicSyntax\org\apache\jsp 路径下的 scriptlet_jsp.java 文件,将看到如下代码片段:public final class scriptlet_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { ··· public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { ··· out.write("\r\n"); out.write("<!DOCTYPE html>\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write(" <title> 小脚本测试 </title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("<table bgcolor=\"#9999dd\" border=\"1\" width=\"300px\">\r\n"); out.write("<!-- Java脚本,这些脚本会对HTML的标签产生作用 -->\r\n"); for(int i = 0; i < 10; i++){ out.write("\r\n"); out.write(" <!-- 上面的循环将控制<tr>标签循环 -->\r\n"); out.write(" <tr>\r\n"); out.write(" <td>循环值:</td>\r\n"); out.write(" <td>"); out.print(i); out.write("</td>\r\n"); out.write(" </tr>\r\n"); } out.write("\r\n"); out.write("</table>\r\n"); out.write("</body>\r\n"); out.write("</html>"); ··· } } 上面的代码片段中 for 循环完全对应于 scriptlet.jsp 页面中的小脚本部分。由上面代码片段可以看,JSP脚本将转换成 Servlet 里_jspService 方法的可执行性代码。这意味着在 JSP 小脚本部分也可以声变量,但在 JSP 脚本部分声明的变量是局部变量,但不能使用 private、public 等访问控制符修饰,也不可使用 static 修饰。 实际上不仅 JSP 小脚本部分会转换成_jspService 方法里的可执行性代码,JSP 页面里的所有静态内容都将由_jspService 方法里输出语句来输出,这就是 JSP 脚本可以控制 JSP 页面中静态内容的原因。由于 JSP 脚本将转换成_jspService 方法里的可执行性代码,而 Java 语法不允许在方法里定义方法,所以 JSP 脚本里不能定义方法。 因为 JSP 脚本中可以放置任何可执行性语句,所以可以充分利用 Java 语言的功能,例如连接数据库和执行数据库操作。看下面的 JSP 页面执行数据库查询。<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <%@ page import="java.sql.*" %> <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> 小脚本测试 </title> </head> <body> <% // 注册数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 获取数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3308/javaee","root","root"); // 创建Statement Statement stmt = conn.createStatement(); // 执行查询 ResultSet rs = stmt.executeQuery("select * from news_inf"); %> <table bgcolor="#9999dd" border="1" width="300"> <% // 遍历结果集 while(rs.next()) {%> <tr> <!-- 输出结果集 --> <td><%=rs.getString(1)%></td> <td><%=rs.getString(2)%></td> </tr> <%}%> <table> </body> </html> 上面程序中的脚本执行了连接数据库,执行 SQL 查询,并使用输出表达式语法来输出查询结果。在浏览器中浏览该页面,将看到如下图所示的效果。 上面的页面执行 SQL 查询需要使用 MySQL 驱动程序,所以读者应该将 MySQL 驱动的 JAR 文件放在 Tomcat 的 lib 路径下(所有 Web 应用都可使用 MySQL 驱动),或者将 MySQL 驱动复制到该 Web 应用的 WEB-INF/lib 路径下(只有该 Web 应用可使用 MySOL 驱动)。除此之外,由于本 JSP 需要查询 javaee 数据库下的 news_inf 数据表,所以不要忘记了将 data.sql 导入数据库。
2022年12月25日
10 阅读
0 评论
2 点赞
2022-12-25
JSP 的基本原理
JSP 的本质是 Servlet,当用户向指定 Servlet 发送请求时,Servlet 利用输出流动态生成 HTML 页面,包括每一个静态的 HTML 标签和所有在 HTML 页面中出现的内容。 由于包括大量的 HTML 标签、大量的静态文本及格式等,导致 Servlet 的开发效率极为低下。所有的表现逻辑,包括布局、色彩及图像等,都必须耦合在 Java 代码中,这的确让人不胜其烦。JSP 的出现弥补了这种不足,JSP 通过在标准的 HTML 页面中嵌入 Java 代码,其静态的部分无须 Java 程序控制,只有那些需要从数据库读取或需要动态生成的页面内容,才使用 Java 脚本控制。 从上面的介绍可以看出,JSP 页面的内容由如下两部分组成。 ➢ 静态部分:标准的 HTML 标签、静态的页面内容,这些内容与静态 HTML 页面相同。 ➢ 动态部分:受 Java 程序控制的内容,这些内容由 Java 脚本动态生成。 下面是一个最简单的JSP页面代码。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <html> <head> <title>欢迎</title> </head> <body> 欢迎学习 Java Web 知识,现在时间是: <%out.println(new java.util.Date());%> </body> </html> 上面的页面中第 8 行代码放在<%和%>之间,表明这些是 Java 脚本,而不是静态内容,通过这种方式就可以把 Java 代码嵌入 HTML 页面中,这就变成了动态的 JSP 页面。在浏览器中浏览该页面,将看到如下图所示的页面。 上面 JSP 页面必须放在 Web 应用中才有效,所以编写该 JSP 页面之前应该先构建一个Web应用。在后面介绍的内容都必须运行在 Web 应用中,所以也必须先构建 Web 应用。 从表面上看,,,JSP 页面已经不再需要 Java 类,似乎完全脱离了 Java 面向对象的特征。事实上JSP的本质依然是 Servlet(一个特殊的Java类)每个 JSP 页面就是一个 Servlet 实例——JSP 页面由系统编译成 Servlet,Servlet 再负责响应用户请求。也就是说,JSP 其实也是 Servlet 的一种简化,使用 JSP 时,其实还是使用 Servlet,因为 Web 应用中的每个 JSP 页面都会由 Servlet 容器生成对应的 Servlet。对于 Tomcat 而言,JSP 页面生成的 Servlet 放在 work 路径对应的 Web 应用下。 再看如下一个简单的 JSP 页面。<!-- 表明这是一个 JSP 页面 --> <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <html> <head> <title> 第二个JSP页面 </title> </head> <body> <!-- 下面是 Java 脚本 --> <%for(int i = 0;i < 7;i++){ out.println("<font size='" + i + "'>"); %> 小吴博客</font> <br/> <%}%> </body> </html> 当启动 Tomcat 之后,可以在 Tomcat 的 work\Catalina\localhost\jspPrinciple\org\apache\jsp 目录到如下文件(本 Web 应用名为jspPrinciple,上面 JSP 页的名为 test.jsp): test_jsp.java 和 test_jsp.class。这两个文件都是由 Tomcat 生成的,Tomcat 根据 JSP 页面生成对应 Servlet 的 Java 文件和 class文件。 下面是 test_jsp.java 文件的源代码,这是一个特殊的 Java 类,是一个 Servlet 类。// JSP 页面经过 Tomcat 编译后默认的包 package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; // 继承 HttpJspBase 类,该类其实是 Httpservlet 的子类 public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java.util.HashSet<>(); _jspx_imports_packages.add("javax.servlet"); _jspx_imports_packages.add("javax.servlet.http"); _jspx_imports_packages.add("javax.servlet.jsp"); _jspx_imports_classes = null; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory() { if (_el_expressionfactory == null) { synchronized (this) { if (_el_expressionfactory == null) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { if (_jsp_instancemanager == null) { synchronized (this) { if (_jsp_instancemanager == null) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } 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 { final java.lang.String _jspx_method = request.getMethod(); if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); return; } final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html; charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, "", true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("<!-- 表明这是一个 JSP 页面 -->\r\n"); out.write("\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write(" <title> 第二个JSP页面 </title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("<!-- 下面是 Java 脚本 -->\r\n"); for(int i = 0;i < 7;i++){ out.println("<font size='" + i + "'>"); out.write("\r\n"); out.write("小吴博客</font>\r\n"); out.write("<br/>\r\n"); } out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>"); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { if (response.isCommitted()) { out.flush(); } else { out.clearBuffer(); } } catch (java.io.IOException e) if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else throw new ServletException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } } 初学者看到上面的 Java 类可能有点难以阅读,其实这就是一个 Servlet 类的源代码,该 Java 类主要包含如下三个方法(去除方法名中的_jsp 前缀,再将首字母小写)。 ➢ init():初始化 JSP/Servlet 的方法。 ➢ destroy():销毁 JSP/Servlet 之前的方法。 ➢ service():对用户请求生成响应的方法。 即使读者暂时不了解上面提供的 Java 代码,也依然不会影响 JSP 页面的编写,因为这都是由 Web 容器负责生成的,后面介绍了编写 Servlet 的知识之后再来看这个 Java 类将十分清晰。浏览该页面可看到如下图所示的页面。 从上图中可以看出,JSP 页面里的 Java 代码不仅仅可以输出动态内容,还可以动态控制页面里的静态内容,例如,从上图中看到将“小吴博客”重复输出了7次。 根据上图所示的执行效果,再次对比 test.jsp 和 test_jsp.java 文件,可得到一个结论:JSP 页面中的所有内容都由 test_jsp.java 文件的页面输出流来生成。下图显示了 JSP 页面的工作原理。 根据上面的 JSP 页面工作原理图,可以得到如下 4 个结论。 ➢ JSP 文件必须在 JSP 服务器内运行。 ➢ JSP 文件必须生成 Servlet 才能执行。 ➢ 每个 JSP 页面的第一个访问者速度很慢,因为必须等待 JSP 编译成 Servlet。 ➢ JSP 页面的访问者无须安装任何客户端,甚至不需要可以运行 Java 的运行环境,因为 JSP 页面输送到客户端的是标准 HTML 页面。 JSP 技术的出现,大大提高了 Java 动态网站的开发效率,所以得到了 Java 动态网站开发者的广泛支持。
2022年12月25日
11 阅读
0 评论
5 点赞
2022-12-25
Web 应用和 web.xml 文件
JSP、Servlet、Listener 和 Filter 等都必须运行在 Web 应用中,所以先来学习如何构建一个 Web 应用。构建 Web 应用 在前文中已经介绍了如何通过 Eclipse 来构建一个 Web 应用,但如果你仅学会在 Eclipse 等IDE工具中单击“下一步”、“确定”等按钮,那你将很难成为一个真正的程序员。 笔者一直坚信:要想成为一个优秀的程序员,应该从基本功练起,所有的代码都应该用简单的文本编辑器(包括 EditPlus、UltraEdit 等工具)完成。 坚持使用最原始的工具来学习技术,会让你对整个技术的每个细节有更准确的把握。比如说你掌握了通过 Eclipse 来构建一个 Web 应用的内容,但你是否知道 Eclipse 创建 Web 应用时为你做了些什么?如果你还不清楚 Eclipse 所干的每件事情,那你还不能使用它。 真正优秀的程序员当然可以使用 IDE 工具,但真正的程序员,即使使用 vi(UNIX 下无格式编辑器)、记事本也一样可以完成非常优秀的项目。正确对待 IDE 工具的态度是:可以使用 IDE 工具,但绝不可依赖于 IDE 工具。学习阶段,前期不要使用 IDE 工具;开发阶段,使用 IDE 工具。真正技术掌握了,无论用什么 IDE 工具都得心应手。不要盲目相信有些人的“掌握这些细节没用的······”说法,有些程序员的心态是:凡是他不会的,就是没用的。 对于 IDE 工具,业内有一个说法:IDE 工具会加快高手的开发效率,但会使初学者更白痴。 下面将“徒手”建立一个 Web 应用,请按如下步骤进行: ① 在任意目录下新建一个文件夹,此处将以 webDemo 文件夹建立一个 Web 应用。 ② 在第 1 步所建的文件夹内建一个 WEB-INF 文件夹(注意大小写,这里区分大小写)。 ③ 进入 Tomcat 或任何其他 Web 容器内,找到任何一个 Web 应用,将 Web 应用的 WEB-INF 下的 web.xml 文件复制到第 2 步所建的 WEB-INF 文件夹下。 对于 Tomcat 而言,其 webapps 路径下有大量的示例 Web 应用。 ④ 修改复制后的 web.xml 文件,将该文件修改成只有一个根元素的 XML文件。修改后的 web.xml 文件代码如下。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> </web-app> 在第 2 步所建的 WEB-INF 路径下,新建两个文件夹:classes 和 lib,这两个文件夹的作用完全相同:都是用于保存 Web 应用所需要的 Java 类文件,区别是 classes 保存单个*.class 文件;而 lib 保存打包后的 JAR 文件。 经过以上步骤,已经建立了一个空 Web 应用。将该 Web 应用复制到 Tomcat 的 webapps 路径下,该 Web 应用将可以自动部署在 Tomcat 中。 通常只需将 JSP 放在 Web 应用的根路径下(对本例而言,就是放在 webDemo 目录下),然后就可以通过浏览器来访问这些页面了。 根据上面介绍,不难发现 Web 应用应该有如下文件结构:<webDemo>——这是 Web 应用的名称,可以改变 |——WEB-INF | |——classes | |——lib | |——web.xm1l |——<a.jsp>——此处可存放任意多个 JSP 页面 上面的 webDemo 是 Web 应用所对应文件夹的名字,可以更改;a.jsp 是该 Web 应用下 JSP 页的名字,也可以修改(还可以增加更多的 JSP 页面)。其他文件夹、配置文件都不可以修改。 a.jsp页面的内容如下。<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %> <html> <head> <title>欢迎</title> </head> <body> 欢迎学习 Java Web 知识 </body> </html> 上面的页面实际上是一个静态 HTML 页面,在浏览器中浏览该页面将看到如右图所示的界面。 将上面的 webDemo 应用复制到 Tomcat 的 webapp 目录下(部署完成),然后启动 Tomcat 服务器,再使用浏览器访问 http://127.0.0.1:8888/webDemo/ajsp,即可看到如右图所示的页面,即表示 Web 应用构建成功,并已经将其成功地部署到 Tomcat 中了。配置描述符web.xml 上面介绍的位于每个 Web 应用的 WEB-INF 路下的 web.xml 文件被称为配置描述符,这个 web.xml 文件对于 Java Web 应用十分重要,在 Servlet 2.5 规范之前,每个 Java Web 应用都必须包含一个 web.xml 文件,且必须放在 WEB-INF 路径下。 从 Servlet 3.0 开始,WEB-INF 路径下的 web.xml 文件不再是必需的,但通常还是建议保留该配置文件。 对于 Java Web 应用而言,WEB-INF 是一个特殊的文件夹,Web 容器会包含该文件夹下的内容,客户端浏览器无法访问 WEB-INF 路径下的任何内容。 在 Servlet 2.5 规范之前,Java Web 应用的绝大部分组件都通过 web.xml 文件来配置管理,从 Servlet 3.0 开始,也可通过注解来配置管理 Web 组件,因此 web.xml 文件可以变得更加简洁,这也是 Servlet 3.0 的重要简化。接下来讲解的内容会同时介绍两种配置管理方式。 ➢ 配置 JSP。 ➢ 配置和管理 Servlet。 ➢ 配置和管理 Listener。 ➢ 配置和管理 Filter。 ➢ 配置标签库。 ➢ 配置 JSP 属性。 除此之外,web.xml 还负责配置、管理如下常用内容。 ➢ 配置和管理 JAAS 授权认证。 ➢ 配置和管理资源引用。 ➢ Web 应用首页。 web.xml文件的根元素是<web-app.../>元素,在 Servlet 3.0 规范中,该元素新增了如下属性。 ➢ metadata-complete: 该属性接受 true 或 false 两个属性值。当该属性值为 true 时,该 Web 应用将不会加载注解配置的 Web 组件(如Servlet、Filter、Listener 等)。 在 web.xml 文件中配置首页使用 welcome-file-list 元素,该元素能包含多个 welcome-file 子元素,其中每个 welcome-file 子元素配置一个首页。例如,如下配置片段:<!-- 配置 Web 应用的首页列表 --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> 上面的配置信息指定该 Web 应用的首页依次是 index.html、index.htm 和 index.jsp,意思是说:当 Web 应用中包含 index.html 页面时,如果浏览者直接访问该 Web 应用,系统将会把该页面呈现给浏览者;当 index.html 页面不存在时,则由 index.htm 页面充当首页,依此类推。 每个 Web 容器都会提供一个系统的 web.xml 文件,用于描述所有 Web 应用共同的配置属性。例如,Tomcat 的系统 web.xml 放在 Tomcat 的 conf 路径下,而 Jetty 的系统 web.xml 文件放在 Jetty 的 etc 路径下,文件名为 webdefault.xml。
2022年12月25日
9 阅读
0 评论
3 点赞
1
2