我们要了解jsp运行原理。JSP的本质就是一个Servlet,JSP的运行之前会先被Tomcat服务器翻译为.java文件,然后在将.java文本编译 为.class文件,而我们在访问jsp时,处理请求的就是那个翻译后的类。 \<% %\>叫做脚本片段,其中写的内容会翻译在Servlet的Service方法中,显然我们可以在Service方法中定义局部变量或者调用其他方法,但是不能 在Service中再定义其他的方法,也就是我们可以在\<%%\>中定义局部变量或者调用方法,但不能定义方法。在jsp页面可以有多个脚本片段,但是多 个脚本片段之间要保证结构完整。 \<%!%\>称作声明,其中写的内容将来会直接翻译在Servlet类中,因为我们可以在类中定义方法和属性以及全局变量,所以我们可以在\<%!%\>中声 明方法、属性、全局变量。 \<%=%\>称作jsp表达式,用于将已经声明的变量或者表达式输出到网页上面。 4.直接写在jsp页面中的代码称作模板元素,将来会Servlet的Service方法中的out.write("___")中,作为输出内容。 # JSP 生命周期 理解JSP底层功能的关键就是去理解它们所遵守的生命周期。 JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。 以下是JSP生命周期中所走过的几个阶段: - 编译阶段: servlet容器编译servlet源文件,生成servlet类 - 初始化阶段: 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法 - 执行阶段: 调用与JSP对应的servlet实例的服务方法 - 销毁阶段: 调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例 很明显,JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示: !\[img\](https://www.runoob.com/wp-content/uploads/2014/01/jsp_life_cycle.jpg) ------ ## JSP编译 当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。 编译的过程包括三个步骤: - 解析JSP文件。 - 将JSP文件转为servlet。 - 编译servlet。 ------ ## JSP初始化 容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样: \`\`\`jsp public void jspInit(){ // 初始化代码 } \`\`\` 一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()方法中初始化数据库连接、打开文件和创建查询表。 ------ ## JSP执行 这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。 当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。 _jspService()方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样: \`\`\`jsp void _jspService(HttpServletRequest request, HttpServletResponse response) { // 服务端处理代码 } \`\`\` _jspService()方法在每个request中被调用一次并且负责产生与之相对应的response,并且它还负责产生所有7个HTTP方法的回应,比如GET、POST、DELETE等等。 ------ ## JSP清理 JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。 jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。 jspDestroy()方法的格式如下: \`\`\`jsp public void jspDestroy() { // 清理代码 } \`\`\` ### 实例 JSP生命周期代码实例如下所示: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> life.jsp \<%! private int initVar=0; private int serviceVar=0; private int destroyVar=0; %\> \<%! public void jspInit(){ initVar++; System.out.println("jspInit(): JSP被初始化了"+initVar+"次"); } public void jspDestroy(){ destroyVar++; System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次"); } %\> \<% serviceVar++; System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求"); String content1="初始化次数 : "+initVar; String content2="响应客户请求次数 : "+serviceVar; String content3="销毁次数 : "+destroyVar; %\>
菜鸟教程 JSP 测试实例
=============
\<%=content1 %\>
\<%=content2 %\>
\<%=content3 %\>
\`\`\` 浏览器打开该页面,输出结果为: !\[img\](https://www.runoob.com/wp-content/uploads/2014/01/E80496E2-35DF-439F-8A43-6376D92DFA45.jpg) ## JSP声明 一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。 JSP声明的语法格式: \`\`\`jsp \<%! declaration; \[ declaration; \]+ ... %\> \`\`\` 或者,您也可以编写与其等价的XML语句,就像下面这样: \`\`\`jsp 代码片段 \`\`\` 程序示例: \`\`\`jsp \<%! int i = 0; %\> \<%! int a, b, c; %\> \<%! Circle a = new Circle(2.0); %\> \`\`\` ------ ## JSP表达式 一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方。 由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签。 表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。 JSP表达式的语法格式: \`\`\`jsp \<%= 表达式 %\> \`\`\` 同样,您也可以编写与之等价的XML语句: \`\`\`jsp 表达式 \`\`\` 程序示例: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn)
今天的日期是: \<%= (new java.util.Date()).toLocaleString()%\>
\`\`\` 运行后得到以下结果: \`\`\`jsp 今天的日期是: 2016-6-25 13:40:07 \`\`\` ------ ## JSP注释 JSP注释主要有两个作用:为代码作注释以及将某段代码注释掉。 JSP注释的语法格式: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn) \<%-- 该部分注释在网页中不会被显示--%\>
今天的日期是: \<%= (new java.util.Date()).toLocaleString()%\>
\`\`\` 运行后得到以下结果: \`\`\`jsp 今天的日期是: 2016-6-25 13:41:26 \`\`\` 不同情况下使用注释的语法规则: \| \*\*语法\*\* \| 描述 \| \| -------------- \| ---------------------------------------------------- \| \| \<%-- 注释 --%\> \| JSP注释,注释内容不会被发送至浏览器甚至不会被编译 \| \| \| HTML注释,通过浏览器查看网页源代码时可以看见注释内容 \| \| \<\\% \| 代表静态 \<%常量 \| \| %\\\> \| 代表静态 %\> 常量 \| \| \\' \| 在属性中使用的单引号 \| \| \\" \| 在属性中使用的双引号 \| ------ ## JSP指令 JSP指令用来设置与整个JSP页面相关的属性。 JSP指令语法格式: \`\`\`jsp \<%@ directive attribute="value" %\> \`\`\` 这里有三种指令标签: \| \*\*指令\*\* \| \*\*描述\*\* \| \| ------------------ \| --------------------------------------------------------- \| \| \<%@ page ... %\> \| 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等 \| \| \<%@ include ... %\> \| 包含其他文件 \| \| \<%@ taglib ... %\> \| 引入标签库的定义,可以是自定义标签 \| ------ ## Page指令 Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。 Page指令的语法格式: \`\`\`jsp \<%@ page attribute="value" %\> \`\`\` 等价的XML格式: \`\`\`jsp \`\`\` ------ ## 属性 下表列出与Page指令相关的属性: \| \*\*属性\*\* \| \*\*描述\*\* \| \| ------------------ \| --------------------------------------------------- \| \| buffer \| 指定out对象使用缓冲区的大小 \| \| autoFlush \| 控制out对象的 缓存区 \| \| contentType \| 指定当前JSP页面的MIME类型和字符编码 \| \| errorPage \| 指定当JSP页面发生异常时需要转向的错误处理页面 \| \| isErrorPage \| 指定当前页面是否可以作为另一个JSP页面的错误处理页面 \| \| extends \| 指定servlet从哪一个类继承 \| \| import \| 导入要使用的Java类 \| \| info \| 定义JSP页面的描述信息 \| \| isThreadSafe \| 指定对JSP页面的访问是否为线程安全 \| \| language \| 定义JSP页面所用的脚本语言,默认是Java \| \| session \| 指定JSP页面是否使用session \| \| isELIgnored \| 指定是否执行EL表达式 \| \| isScriptingEnabled \| 确定脚本元素能否被使用 \| ------ ## Include指令 JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。 Include指令的语法格式如下: \`\`\`jsp \<%@ include file="文件相对 url 地址" %\> \`\`\` \*\*include\*\* 指令中的文件名实际上是一个相对的 URL 地址。 如果您没有给文件关联一个路径,JSP编译器默认在当前路径下寻找。 等价的XML语法: \`\`\`jsp \`\`\` ------ ## Taglib指令 JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。 Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。 Taglib指令的语法: \`\`\`jsp \<%@ taglib uri="uri" prefix="prefixOfTag" %\> \`\`\` uri属性确定标签库的位置,prefix属性指定标签库的前缀。 等价的XML语法: \`\`\`jsp \`\`\` ## JSP行为 JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。 行为标签只有一种语法格式,它严格遵守XML标准: \`\`\`jsp \`\`\` 行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签:: \| \*\*语法\*\* \| \*\*描述\*\* \| \| --------------- \| ---------------------------------------------------------- \| \| jsp:include \| 用于在当前页面中包含静态或动态资源 \| \| jsp:useBean \| 寻找和初始化一个JavaBean组件 \| \| jsp:setProperty \| 设置 JavaBean组件的值 \| \| jsp:getProperty \| 将 JavaBean组件的值插入到 output中 \| \| jsp:forward \| 从一个JSP文件向另一个文件传递一个包含用户请求的request对象 \| \| jsp:plugin \| 用于在生成的HTML页面中包含Applet和JavaBean对象 \| \| jsp:element \| 动态创建一个XML元素 \| \| jsp:attribute \| 定义动态创建的XML元素的属性 \| \| jsp:body \| 定义动态创建的XML元素的主体 \| \| jsp:text \| 用于封装模板数据 \| ------ ## JSP 动作元素 与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。 利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。 动作元素只有一种语法,它符合XML标准: \`\`\`jsp \`\`\` ------ ## 常见的属性 所有的动作要素都有两个属性:id属性和scope属性。 - \*\*id属性:\*\* id属性是动作元素的唯一标识,可以在JSP页面中引用。动作元素创建的id值可以通过PageContext来调用。 - \*\*scope属性:\*\* 该属性用于识别动作元素的生命周期。 id属性和scope属性有直接关系,scope属性定义了相关联id对象的寿命。 scope属性有四个可能的值: (a) page, (b)request, (c)session, 和 (d) application。 ------ ## 动作元素 动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下: \`\`\`jsp \`\`\` 前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。 以下是include动作相关的属性列表。 \| 属性 \| 描述 \| \| ----- \| ------------------------------------------ \| \| page \| 包含在页面中的相对URL地址。 \| \| flush \| 布尔属性,定义在包含资源前是否刷新缓存区。 \| ### 实例 以下我们定义了两个文件 \*\*date.jsp\*\* 和 \*\*main.jsp\*\*,代码如下所示: date.jsp文件代码: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\>
今天的日期是: \<%= (new java.util.Date()).toLocaleString()%\>
\`\`\` main.jsp文件代码: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn)
include 动作实例
------------
\`\`\` 现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下: \`\`\`jsp include 动作实例 今天的日期是: 2016-6-25 14:08:17 \`\`\` ------ ## 动作元素 \*\*jsp:useBean\*\* 动作用来加载一个将在JSP页面中使用的JavaBean。 这个功能非常有用,因为它使得我们可以发挥 Java 组件复用的优势。 jsp:useBean动作最简单的语法为: \`\`\`jsp \`\`\` 在类载入后,我们既可以通过 jsp:setProperty 和 jsp:getProperty 动作来修改和检索bean的属性。 以下是useBean动作相关的属性列表。 \| 属性 \| 描述 \| \| -------- \| ----------------------------------------------------------- \| \| class \| 指定Bean的完整包名。 \| \| type \| 指定将引用该对象变量的类型。 \| \| beanName \| 通过 java.beans.Beans 的 instantiate() 方法指定Bean的名字。 \| 在给出具体实例前,让我们先来看下 jsp:setProperty 和 jsp:getProperty 动作元素: ------ ## 动作元素 jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty,如下所示: \`\`\`jsp ... \`\`\` 此时,不管jsp:useBean是找到了一个现有的Bean,还是新创建了一个Bean实例,jsp:setProperty都会执行。第二种用法是把jsp:setProperty放入jsp:useBean元素的内部,如下所示: \`\`\`jsp ... \`\`\` 此时,jsp:setProperty只有在新建Bean实例时才会执行,如果是使用现有实例则不执行jsp:setProperty。 jsp:setProperty动作有下面四个属性,如下表: \| 属性 \| 描述 \| \| -------- \| ------------------------------------------------------------ \| \| name \| name属性是必需的。它表示要设置属性的是哪个Bean。 \| \| property \| property属性是必需的。它表示要设置哪个属性。有一个特殊用法:如果property的值是"\*",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法。 \| \| value \| value 属性是可选的。该属性用来指定Bean属性的值。字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、 byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如"true")通过 Boolean.valueOf转换,int和Integer类型的属性值(比如"42")通过Integer.valueOf转换。 value和param不能同时使用,但可以使用其中任意一个。 \| \| param \| param 是可选的。它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值。 \| ------ ## 动作元素 jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出。语法格式如下: \`\`\`jsp ... \`\`\` 下表是与getProperty相关联的属性: \| 属性 \| 描述 \| \| -------- \| -------------------------------------- \| \| name \| 要检索的Bean属性名称。Bean必须已定义。 \| \| property \| 表示要提取Bean属性的值 \| ### 实例 以下实例我们使用了Bean: \`\`\`jsp package com.php.main; public class TestBean { private String message = "php中文网"; public String getMessage() { return(message); } public void setMessage(String message) { this.message = message; } } \`\`\` 编译以上实例文件 TestBean.java : \`\`\`jsp $ javac TestBean.java \`\`\` 编译完成后会在当前目录下生成一个 \*\*TestBean.class\*\* 文件, 将该文件拷贝至当前 JSP 项目的 \*\*WebContent/WEB-INF/classes/com/php/main\*\*下( com/php/main 包路径,没有需要手动创建)。 下面是一个 Eclipse 中目录结构图: !\[6AC33FBA-0B76-4BFD-A690-E856E9E01900.jpg\](https://img.php.cn/upload/image/193/770/549/1486201456891693.jpg) 下面是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。 现在让我们在main.jsp文件中调用该Bean: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn)
Jsp 使用 JavaBean 实例 {#myName}
----------------------------
输出信息....
\`\`\` 浏览器访问,执行以上文件,输出如下所示: !\[D7AD87A8-3392-4D4E-8731-18806B0644CD.jpg\](https://img.php.cn/upload/image/286/667/307/1486201805771925.jpg) ------ ## 动作元素 jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。语法格式如下所示: \`\`\`jsp \`\`\` 以下是forward相关联的属性: \| 属性 \| 描述 \| \| ---- \| ------------------------------------------------------------ \| \| page \| page属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算,可以是一个JSP页面或者一个 Java Servlet. \| ### 实例 以下实例我们使用了两个文件,分别是: date.jsp 和 main.jsp。 date.jsp 文件代码如下: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\>
今天的日期是: \<%= (new java.util.Date()).toLocaleString()%\>
\`\`\` main.jsp文件代码: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn)
forward 动作实例
------------
\`\`\` 现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下: \`\`\`jsp 今天的日期是: 2016-6-25 14:37:25 \`\`\` ------ ## 动作元素 jsp:plugin动作用来根据浏览器的类型,插入通过Java插件 运行Java Applet所必需的OBJECT或EMBED元素。 如果需要的插件不存在,它会下载插件,然后执行Java组件。 Java组件可以是一个applet或一个JavaBean。 plugin动作有多个对应HTML元素的属性用于格式化Java 组件。param元素可用于向Applet 或 Bean 传递参数。 以下是使用plugin 动作元素的典型实例: \`\`\`jsp Unable to initialize Java Plugin \`\`\` 如果你有兴趣可以尝试使用applet来测试jsp:plugin动作元素,元素是一个新元素,在组件出现故障的错误是发送给用户错误信息。 ------ ## 、 、 动作元素 、 、 动作元素动态定义XML元素。动态是非常重要的,这就意味着XML元素在编译时是动态生成的而非静态。 以下实例动态定义了XML元素: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> php中文网(php.cn) 属性值 XML 元素的主体 \`\`\` 浏览器访问以下页面,输出结果如下所示: !\[7D8C47F0-0DDE-4F1D-8BE1-B2C9C955683E.jpg\](https://img.php.cn/upload/image/653/928/525/1486201689958422.jpg) ------ ## 动作元素 动作元素允许在JSP页面和文档中使用写入文本的模板,语法格式如下: \`\`\`jsp 模板数据 \`\`\` 以上文本模板不能包含其他元素,只能只能包含文本和EL表达式(注:EL表达式将在后续章节中介绍)。请注意,在XML文件中,您不能使用表达式如 ${whatever \> 0},因为\>符号是非法的。 你可以使用 ${whatever gt 0}表达式或者嵌入在一个CDATA部分的值。 \`\`\`jsp \`\`\` 如果你需要在 XHTML 中声明 DOCTYPE,必须使用到动作元素,实例如下: \`\`\`jsp jsp:text action Welcome to JSP Programming \`\`\` 你可以对以上实例尝试使用及不使用该动作元素执行结果的区别。 ## JSP隐含对象 JSP支持九个自动定义的变量,江湖人称隐含对象。这九个隐含对象的简介见下表: \| \*\*对象\*\* \| \*\*描述\*\* \| \| ----------- \| ------------------------------------------------------------ \| \| request \| \*\*HttpServletRequest\*\*类的实例 \| \| response \| \*\*HttpServletResponse\*\*类的实例 \| \| out \| \*\*PrintWriter\*\*类的实例,用于把结果输出至网页上 \| \| session \| \*\*HttpSession\*\*类的实例 \| \| application \| \*\*ServletContext\*\*类的实例,与应用上下文有关 \| \| config \| \*\*ServletConfig\*\*类的实例 \| \| pageContext \| \*\*PageContext\*\*类的实例,提供对JSP页面所有对象以及命名空间的访问 \| \| page \| 类似于Java类中的this关键字 \| \| Exception \| \*\*Exception\*\*类的对象,代表发生错误的JSP页面中对应的异常对象 \| ------ ## request对象 request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。 request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。 ------ ## response对象 response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。 response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。 ------ ## out对象 out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。 最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用buffered='false'属性来轻松关闭缓存。 JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter新增了一些专为处理缓存而设计的方法。还有就是,JspWriter类会抛出IOExceptions异常,而PrintWriter不会。 下表列出了我们将会用来输出boolean,char,int,double,String,object等类型数据的重要方法: \| \*\*方法\*\* \| \*\*描述\*\* \| \| ---------------------------- \| ------------------------ \| \| \*\*out.print(dataType dt)\*\* \| 输出Type类型的值 \| \| \*\*out.println(dataType dt)\*\* \| 输出Type类型的值然后换行 \| \| \*\*out.flush()\*\* \| 刷新输出流 \| ------ ## session对象 session对象是 javax.servlet.http.HttpSession 类的实例。和Java Servlets中的session对象有一样的行为。 session对象用来跟踪在各个客户端请求间的会话。 ------ ## application对象 application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。 这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。 通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。 ------ ## config对象 config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。 这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。 以下是config对象的使用方法,不是很重要,所以不常用: \`\`\`jsp config.getServletName(); \`\`\` 它返回包含在元素中的servlet名字,注意,元素在 WEB-INF\\web.xml 文件中定义。 ------ ## pageContext 对象 pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。 这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。 这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。 pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。 PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。 其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute("attrName")移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性: \`\`\`jsp pageContext.removeAttribute("attrName", PAGE_SCOPE); \`\`\` ------ ## page 对象 这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。 page 对象就是this对象的同义词。 ------ ## exception 对象 exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。 ## HttpServletRequest类 request对象是javax.servlet.http.HttpServletRequest类的实例。每当客户端请求一个页面时,JSP引擎就会产生一个新的对象来代表这个请求。 request对象提供了一系列方法来获取HTTP信息头,包括表单数据,cookies,HTTP方法等等。 接下来将会介绍一些在JSP编程中常用的获取HTTP信息头的方法。详细内容请见下表: \| \*\*序号\*\* \| \*\*方法\*\*\*\*\&\*\* \*\*描述\*\* \| \| -------- \| ------------------------------------------------------------ \| \| 1 \| \*\*Cookie\[\] getCookies()\*\* 返回客户端所有的Cookie的数组 \| \| 2 \| \*\*Enumeration getAttributeNames()\*\* 返回request对象的所有属性名称的集合 \| \| 3 \| \*\*Enumeration getHeaderNames()\*\* 返回所有HTTP头的名称集合 \| \| 4 \| \*\*Enumeration getParameterNames()\*\* 返回请求中所有参数的集合 \| \| 5 \| \*\*HttpSession getSession()\*\* 返回request对应的session对象,如果没有,则创建一个 \| \| 6 \| \*\*HttpSession getSession(boolean create)\*\* 返回request对应的session对象,如果没有并且参数create为true,则返回一个新的session对象 \| \| 7 \| \*\*Locale getLocale()\*\* 返回当前页的Locale对象,可以在response中设置 \| \| 8 \| \*\*Object getAttribute(String name)\*\* 返回名称为name的属性值,如果不存在则返回null。 \| \| 9 \| \*\*ServletInputStream getInputStream()\*\* 返回请求的输入流 \| \| 10 \| \*\*String getAuthType()\*\* 返回认证方案的名称,用来保护servlet,比如 "BASIC" 或者 "SSL" 或 null 如果 JSP没设置保护措施 \| \| 11 \| \*\*String getCharacterEncoding()\*\* 返回request的字符编码集名称 \| \| 12 \| \*\*String getContentType()\*\* 返回request主体的MIME类型,若未知则返回null \| \| 13 \| \*\*String getContextPath()\*\* 返回request URI中指明的上下文路径 \| \| 14 \| \*\*String getHeader(String name)\*\* 返回name指定的信息头 \| \| 15 \| \*\*String getMethod()\*\* 返回此request中的HTTP方法,比如 GET,,POST,或PUT \| \| 16 \| \*\*String getParameter(String name)\*\* 返回此request中name指定的参数,若不存在则返回null \| \| 17 \| \*\*String getPathInfo()\*\* 返回任何额外的与此request URL相关的路径 \| \| 18 \| \*\*String getProtocol()\*\* 返回此request所使用的协议名和版本 \| \| 19 \| \*\*String getQueryString()\*\* 返回此 request URL包含的查询字符串 \| \| 20 \| \*\*String getRemoteAddr()\*\* 返回客户端的IP地址 \| \| 21 \| \*\*String getRemoteHost()\*\* 返回客户端的完整名称 \| \| 22 \| \*\*String getRemoteUser()\*\* 返回客户端通过登录认证的用户,若用户未认证则返回null \| \| 23 \| \*\*String getRequestURI()\*\* 返回request的URI \| \| 24 \| \*\*String getRequestedSessionId()\*\* 返回request指定的session ID \| \| 25 \| \*\*String getServletPath()\*\* 返回所请求的servlet路径 \| \| 26 \| \*\*String\[\] getParameterValues(String name)\*\* 返回指定名称的参数的所有值,若不存在则返回null \| \| 27 \| \*\*boolean isSecure()\*\* 返回request是否使用了加密通道,比如HTTPS \| \| 28 \| \*\*int getContentLength()\*\* 返回request主体所包含的字节数,若未知的返回-1 \| \| 29 \| \*\*int getIntHeader(String name)\*\* 返回指定名称的request信息头的值 \| \| 30 \| \*\*int getServerPort()\*\* 返回服务器端口号 \| ## HttpServletResponse类 response 对象是 javax.servlet.http.HttpServletResponse 类的一个实例。就像服务器会创建request对象一样,它也会创建一个客户端响应。 response对象定义了处理创建HTTP信息头的接口。通过使用这个对象,开发者们可以添加新的cookie或时间戳,还有HTTP状态码等等。 下表列出了用来设置HTTP响应头的方法,这些方法由HttpServletResponse 类提供: \| \*\*S.N.\*\* \| \*\*方法\*\* \*\*\&\*\* \*\*描述\*\* \| \| -------- \| ------------------------------------------------------------ \| \| 1 \| \*\*String encodeRedirectURL(String url)\*\* 对sendRedirect()方法使用的URL进行编码 \| \| 2 \| \*\*String encodeURL(String url)\*\* 将URL编码,回传包含Session ID的URL \| \| 3 \| \*\*boolean containsHeader(String name)\*\* 返回指定的响应头是否存在 \| \| 4 \| \*\*boolean isCommitted()\*\* 返回响应是否已经提交到客户端 \| \| 5 \| \*\*void addCookie(Cookie cookie)\*\* 添加指定的cookie至响应中 \| \| 6 \| \*\*void addDateHeader(String name, long date)\*\* 添加指定名称的响应头和日期值 \| \| 7 \| \*\*void addHeader(String name, String value)\*\* 添加指定名称的响应头和值 \| \| 8 \| \*\*void addIntHeader(String name, int value)\*\* 添加指定名称的响应头和int值 \| \| 9 \| \*\*void flushBuffer()\*\* 将任何缓存中的内容写入客户端 \| \| 10 \| \*\*void reset()\*\* 清除任何缓存中的任何数据,包括状态码和各种响应头 \| \| 11 \| \*\*void resetBuffer()\*\* 清除基本的缓存数据,不包括响应头和状态码 \| \| 12 \| \*\*void sendError(int sc)\*\* 使用指定的状态码向客户端发送一个出错响应,然后清除缓存 \| \| 13 \| \*\*void sendError(int sc, String msg)\*\* 使用指定的状态码和消息向客户端发送一个出错响应 \| \| 14 \| \*\*void sendRedirect(String location)\*\* 使用指定的URL向客户端发送一个临时的间接响应 \| \| 15 \| \*\*void setBufferSize(int size)\*\* 设置响应体的缓存区大小 \| \| 16 \| \*\*void setCharacterEncoding(String charset)\*\* 指定响应的编码集(MIME字符集),例如UTF-8 \| \| 17 \| \*\*void setContentLength(int len)\*\* 指定HTTP servlets中响应的内容的长度,此方法用来设置 HTTP Content-Length 信息头 \| \| 18 \| \*\*void setContentType(String type)\*\* 设置响应的内容的类型,如果响应还未被提交的话 \| \| 19 \| \*\*void setDateHeader(String name, long date)\*\* 使用指定名称和值设置响应头的名称和内容 \| \| 20 \| \*\*void setHeader(String name, String value)\*\* 使用指定名称和值设置响应头的名称和内容 \| \| 21 \| \*\*void setIntHeader(String name, int value)\*\* 使用指定名称和值设置响应头的名称和内容 \| \| 22 \| \*\*void setLocale(Locale loc)\*\* 设置响应的语言环境,如果响应尚未被提交的话 \| \| 23 \| \*\*void setStatus(int sc)\*\* 设置响应的状态码 \| ## 控制流语句 JSP提供对Java语言的全面支持。您可以在JSP程序中使用Java API甚至建立Java代码块,包括判断语句和循环语句等等。 ## 判断语句 If...else块,请看下面这个例子: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%! int day = 3; %\> php中文网(php.cn)
### IF...ELSE 实例
\<% if (day == 1 \| day == 7) { %\>
今天是周末
\<% } else { %\>
今天不是周末
\<% } %\> \`\`\` 运行后得到以下结果: \`\`\`jsp IF...ELSE 实例 今天不是周末 \`\`\` 现在来看看switch...case块,与if...else块有很大的不同,它使用out.println(),并且整个都装在脚本程序的标签中,就像下面这样: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%! int day = 3; %\> php中文网(php.cn)
### SWITCH...CASE 实例
\<% switch(day) { case 0: out.println("星期天"); break; case 1: out.println("星期一"); break; case 2: out.println("星期二"); break; case 3: out.println("星期三"); break; case 4: out.println("星期四"); break; case 5: out.println("星期五"); break; default: out.println("星期六"); } %\> \`\`\` 浏览器访问,运行后得出以下结果: \`\`\`jsp SWITCH...CASE 实例 星期三 \`\`\` ------ ## 循环语句 在JSP程序中可以使用Java的三个基本循环类型:for,while,和 do...while。 让我们来看看for循环的例子,以下输出的不同字体大小的"php中文网": \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%! int fontSize; %\> php中文网(php.cn)
### For 循环实例
\<%for ( fontSize = 1; fontSize \<= 3; fontSize++){ %\> php中文网
\<%}%\> \`\`\` 运行后得到以下结果: !\[7B4B85CF-FE4B-43CB-AAFF-F8594AD4342C.jpg\](https://img.php.cn/upload/image/304/538/927/1486201220973921.jpg) 将上例改用while循环来写: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%! int fontSize; %\> php中文网(php.cn)
### While 循环实例
\<%while ( fontSize \<= 3){ %\> php中文网
\<%fontSize++;%\> \<%}%\> \`\`\` 浏览器访问,输出结果为(fontSize 初始化为0,所以多输出了一行): !\[7B4B85CF-FE4B-43CB-AAFF-F8594AD4342C.jpg\](https://img.php.cn/upload/image/539/546/815/1486201342375778.jpg) JSP运算符 JSP支持所有Java逻辑和算术运算符。 下表罗列出了JSP常见运算符,优先级从高到底: \| \*\*类别\*\* \| \*\*操作符\*\* \| \*\*结合性\*\* \| \| --------- \| ---------------------------------- \| ---------- \| \| 后缀 \| () \[\] . (点运算符) \| 左到右 \| \| 一元 \| ++ - - ! \~ \| 右到左 \| \| 可乘性 \| \* / % \| 左到右 \| \| 可加性 \| + - \| 左到右 \| \| 移位 \| \>\> \>\>\> \<\< \| 左到右 \| \| 关系 \| \> \>= \< \<= \| 左到右 \| \| 相等/不等 \| == != \| 左到右 \| \| 位与 \| \& \| 左到右 \| \| 位异或 \| \^ \| 左到右 \| \| 位或 \| \\\| \| 左到右 \| \| 逻辑与 \| \&\& \| 左到右 \| \| 逻辑或 \| \\\|\\\| \| 左到右 \| \| 条件判断 \| ?: \| 右到左 \| \| 赋值 \| = += -= \*= /= %= \>\>= \<\<= \&= \^= \\\|= \| 右到左 \| \| 逗号 \| , \| 左到右 \| ------ ## JSP 字面量 JSP语言定义了以下几个字面量: - 布尔值(boolean):true 和 false; - 整型(int):与 Java 中的一样; - 浮点型(float):与 Java 中的一样; - 字符串(string):以单引号或双引号开始和结束; - Null:null。 ## Servlet过滤器方法 一个过滤器就是一个Java类,它实现了javax.servlet.Filter 接口。javax.servlet.Filter接口定义了三个方法: \| \*\*序号\*\* \| \*\*方法\*\* \*\*\&\*\*\*\*描述\*\* \| \| -------- \| ------------------------------------------------------------ \| \| 1 \| \*\*public void doFilter (ServletRequest, ServletResponse, FilterChain)\*\* 每当 request/response要通过过滤链时容器会调用这个方法,因为客户端请求链尾的资源 \| \| 2 \| \*\*public void init(FilterConfig filterConfig)\*\* 容器调用这个方法来表明一个过滤器被安置在服务中 \| \| 3 \| \*\*public void destroy()\*\* 容器调用这个方法来表明一个过滤器正在从服务中移除 \| ------ ## JSP过滤器示例 这个例子将会打印IP地址和每次访问JSP文件的日期时间。当然,这只是个简单的例子,让您了解一些简单的过滤器用法,但是可以使用这些概念来自行构造更复杂的程序。 \`\`\`jsp // 引入Java包 import java.io.\*; import javax.servlet.\*; import javax.servlet.http.\*; import java.util.\*; // 实现 Filter 类 public class LogFilter implements Filter { public void init(FilterConfig config) throws ServletException{ // 获取初始化参数 String testParam = config.getInitParameter("test-param"); //打印初始化参数 System.out.println("Test Param: " + testParam); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { // 获取客户端ip地址 String ipAddress = request.getRemoteAddr(); // 输出ip地址及当前时间 System.out.println("IP "+ ipAddress + ", Time " + new Date().toString()); // 传递请求道过滤器链 chain.doFilter(request,response); } public void destroy( ){ /\* 在Filter实例在服务器上被移除前调用。\*/ } } \`\`\` 编译LogFilter.java文件,然后将编译后的class文件放在/webapps/ROOT/WEB-INF/classes目录下。 ------ ## web.xml文件中的JSP过滤器映射 过滤器被定义,然后映射成一个URL或JSP文件名,与servlet被定义然后映射的方式差不多。在部署描述文件web.xml中,使用标签来进行过滤器映射: \`\`\`jsp LogFilter LogFilter test-param Initialization Paramter LogFilter /\* \`\`\` 上述过滤器将会应用在所有servlet和JSP程序中,因为我们在配置中指定了" /\*"。您也可以指定一个servlet或JSP路径,如果您只想要将过滤器应用在少数几个servlet或JSP程序中的话。 现在,像平常一样访问servlet或JSP页面,您就会发现服务器日志中产生了关于此次访问的记录。您也可以使用Log4J记录器来把日志记录在其它文件中。 ------ ## 使用多重过滤器 您的网络应用程序可以定义很多不同的过滤器。现在,您定义了两个过滤器,AuthenFilter和LogFilter,其它的步骤与前面讲的一样,除非要创建一个不同的映射,就像下面这样: \`\`\`jsp LogFilter LogFilter test-param Initialization Paramter AuthenFilter AuthenFilter test-param Initialization Paramter LogFilter /\* AuthenFilter /\* \`\`\` ------ ## 过滤器的应用顺序 在web.xml中元素的映射顺序决定了容器应用这些过滤器的顺序。要反转应用的顺序,您只需要反转web.xml中元素的定义顺序就行了。 比如,上面的例子会首先应用 LogFilter然后再应用AuthenFilter,但是下面这个例子将会反转应用的顺序: \`\`\`jsp AuthenFilter /\* LogFilter /\* \`\`\` # cookie JSP Cookie 处理需要对中文进行编码与解码,方法如下: \`\`\`jsp String str = java.net.URLEncoder.encode("中文"); //编码 String str = java.net.URLDecoder.decode("编码后的字符串"); // 解码 \`\`\` ## Servlet Cookie 方法 下表列出了Cookie对象中常用的方法: \| \*\*序号\*\* \| \*\*方法\*\* \*\*\&\*\* \*\*描述\*\* \| \| -------- \| ------------------------------------------------------------ \| \| 1 \| \*\*public void setDomain(String pattern)\*\* 设置cookie的域名,比如w3cschool.cc \| \| 2 \| \*\*public String getDomain()\*\* 获取cookie的域名,比如w3cschool.cc \| \| 3 \| \*\*public void setMaxAge(int expiry)\*\* 设置cookie有效期,以秒为单位,默认有效期为当前session的存活时间 \| \| 4 \| \*\*public int getMaxAge()\*\* 获取cookie有效期,以秒为单位,默认为-1 ,表明cookie会活到浏览器关闭为止 \| \| 5 \| \*\*public String getName()\*\* 返回 cookie的名称,名称创建后将不能被修改 \| \| 6 \| \*\*public void setValue(String newValue)\*\* 设置 cookie的值 \| \| 7 \| \*\*public String getValue()\*\* 获取cookie的值 \| \| 8 \| \*\*public void setPath(String uri)\*\* 设置cookie 的路径,默认为当前页面目录下的所有URL,还有此目录下的所有子目录 \| \| 9 \| \*\*public String getPath()\*\* 获取cookie 的路径 \| \| 10 \| \*\*public void setSecure(boolean flag)\*\* 指明cookie是否要加密传输 \| \| 11 \| \*\*public void setComment(String purpose)\*\* 设置注释描述 cookie的目的。当浏览器将cookie展现给用户时,注释将会变得非常有用 \| \| 12 \| \*\*public String getComment()\*\* 返回描述cookie目的的注释,若没有则返回null \| ------ ## 使用JSP设置Cookie 使用JSP设置cookie包含三个步骤: \*\*(1)创建一个Cookie对象:\*\* 调用Cookie的构造函数,使用一个cookie名称和值做参数,它们都是字符串。 \`\`\`jsp Cookie cookie = new Cookie("key","value"); \`\`\` 请务必牢记,名称和值中都不能包含空格或者如下的字符: \`\`\`jsp \[ \] ( ) = , " / ? @ : ; \`\`\` \*\*(2) 设置有效期:\*\*调用setMaxAge()函数表明cookie在多长时间(以秒为单位)内有效。下面的操作将有效期设为了24小时。 \`\`\`jsp cookie.setMaxAge(60\*60\*24); \`\`\` \*\*(3) 将cookie发送至HTTP响应头中:\*\*调用response.addCookie()函数来向HTTP响应头中添加cookie。 \`\`\`jsp response.addCookie(cookie); \`\`\` ------ ### 实例演示 main.jsp 文件代码如下所示: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%@ page import="java.net.\*" %\> \<% // 编码,解决中文乱码 String str = URLEncoder.encode(request.getParameter("name"),"utf-8"); // 设置 name 和 url cookie Cookie name = new Cookie("name", str); Cookie url = new Cookie("url", request.getParameter("url")); // 设置cookie过期时间为24小时。 name.setMaxAge(60\*60\*24); url.setMaxAge(60\*60\*24); // 在响应头部添加cookie response.addCookie( name ); response.addCookie( url ); %\> 设置 Cookie
设置 Cookie
=========
* **网站名:**
\<%= request.getParameter("name")%\>
* **网址:**
\<%= request.getParameter("url")%\>
\`\`\` 以下是一个简单的 HTML 表单通过GET方法将客户端数据提交到 main.jsp 文件中,并设置 cookie: \`\`\`jsp php中文网(php.cn) 站点名:
网址: \`\`\` 将以上HTML代码保存到test.htm文件中。 将该文件放置于当前jsp项目的 WebContent 目录下(与 main.jsp 同一个目录)。 通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示: !\[img\](http://php.cn/style/images/jsp6.gif) 试着输入 "站点名" 和 "网址",然后点击提交按钮,它将会在您的屏幕中显示 "站点名" 和 "网址",并且设置 "站点名" 和 "网址" 的两个 cookie。 ------ ## 使用 JSP 读取 Cookie 想要读取cookie,您就需要调用request.getCookies()方法来获得一个javax.servlet.http.Cookie对象的数组,然后遍历这个数组,使用getName()方法和getValue()方法来获取每一个cookie的名称和值。 让我们来读取上个例子中的cookie, 以下为 cookie.jsp 文件代码: \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%@ page import="java.net.\*" %\> 获取 Cookie \<% Cookie cookie = null; Cookie\[\] cookies = null; // 获取cookies的数据,是一个数组 cookies = request.getCookies(); if( cookies != null ){ out.println("
查找 Cookie 名与值
-------------
"); for (int i = 0; i \< cookies.length; i++){ cookie = cookies\[i\]; out.print("参数名 : " + cookie.getName()); out.print("
"); out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +"
"); out.print("------------------------------------
"); } }else{ out.println("
没有发现 Cookie
-----------
"); } %\> \`\`\` # Session ## session对象 除了以上几种方法外,JSP利用servlet提供的HttpSession接口来识别一个用户,存储这个用户的所有访问信息。 默认情况下,JSP允许会话跟踪,一个新的HttpSession对象将会自动地为新的客户端实例化。禁止会话跟踪需要显式地关掉它,通过将page指令中session属性值设为false来实现,就像下面这样: \`\`\`jsp \<%@ page session="false" %\> \`\`\` JSP引擎将隐含的session对象暴露给开发者。由于提供了session对象,开发者就可以方便地存储或检索数据。 下表列出了session对象的一些重要方法: \| \*\*S.N.\*\* \| \*\*方法\*\* \*\*\&\*\* \*\*描述\*\* \| \| -------- \| ------------------------------------------------------------ \| \| 1 \| \*\*public Object getAttribute(String name)\*\* 返回session对象中与指定名称绑定的对象,如果不存在则返回null \| \| 2 \| \*\*public Enumeration getAttributeNames()\*\* 返回session对象中所有的对象名称 \| \| 3 \| \*\*public long getCreationTime()\*\* 返回session对象被创建的时间, 以毫秒为单位,从1970年1月1号凌晨开始算起 \| \| 4 \| \*\*public String getId()\*\* 返回session对象的ID \| \| 5 \| \*\*public long getLastAccessedTime()\*\* 返回客户端最后访问的时间,以毫秒为单位,从1970年1月1号凌晨开始算起 \| \| 6 \| \*\*public int getMaxInactiveInterval()\*\* 返回最大时间间隔,以秒为单位,servlet 容器将会在这段时间内保持会话打开 \| \| 7 \| \*\*public void invalidate()\*\* 将session无效化,解绑任何与该session绑定的对象 \| \| 8 \| \*\*public boolean isNew(\*\* 返回是否为一个新的客户端,或者客户端是否拒绝加入session \| \| 9 \| \*\*public void removeAttribute(String name)\*\* 移除session中指定名称的对象 \| \| 10 \| \*\*public void setAttribute(String name, Object value)\*\* 使用指定的名称和值来产生一个对象并绑定到session中 \| \| 11 \| \*\*public void setMaxInactiveInterval(int interval)\*\* 用来指定时间,以秒为单位,servlet容器将会在这段时间内保持会话有效 \| ------ ## JSP Session应用 这个例子描述了如何使用HttpSession对象来获取创建时间和最后一次访问时间。我们将会为request对象关联一个新的session对象,如果这个对象尚未存在的话。 \`\`\`jsp \<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%\> \<%@ page import="java.io.\*,java.util.\*" %\> \<% // 获取session创建时间 Date createTime = new Date(session.getCreationTime()); // 获取最后访问页面的时间 Date lastAccessTime = new Date(session.getLastAccessedTime()); String title = "再次访问php中文网实例"; Integer visitCount = new Integer(0); String visitCountKey = new String("visitCount"); String userIDKey = new String("userID"); String userID = new String("ABCD"); // 检测网页是否由新的访问用户 if (session.isNew()){ title = "访问php中文网实例"; session.setAttribute(userIDKey, userID); session.setAttribute(visitCountKey, visitCount); } else { visitCount = (Integer)session.getAttribute(visitCountKey); visitCount += 1; userID = (String)session.getAttribute(userIDKey); session.setAttribute(visitCountKey, visitCount); } %\> Session 跟踪
Session 跟踪
==========
| Session 信息 | 值 |
|------------|--------------------------------------|
| id | \<% out.print( session.getId()); %\> |
| 创建时间 | \<% out.print(createTime); %\> |
| 最后访问时间 | \<% out.print(lastAccessTime); %\> |
| 用户 ID | \<% out.print(userID); %\> |
| 访问次数 | \<% out.print(visitCount); %\> |
\`\`\` # JSP 文件上传 JSP可以通过HTML的form表单上传文件到服务器。 文件类型可以是文本文件、二进制文件、图像文件等其他任何文档。 ------ ## 创建文件上传表单 接下来我们使用HTML标签来创建文件上传表单,以下为要注意的点: - form表单 \*\*method\*\* 属性必须设置为 \*\*POST\*\* 方法 ,不能使用 GET 方法。 - form表单 \*\*enctype\*\* 属性需要设置为 \*\*multipart/form-data\*\*。 - form表单 \*\*action\*\* 属性需要设置为提交到后台处理文件上传的jsp文件地址。例如 \*\*uploadFile.jsp\*\* 程序文件用来处理上传的文件。 - 上传文件元素需要使用 标签,属性设置为 type="file"。如果需要上传多个文件,可以在 标签中设置不同的名称。 以下是一个上传文件的表单,实例如下: \`\`\`jsp File Uploading Form
### File Upload:
Select a file to upload:
\`\`\` 在你本地浏览器访问该文件,显示界面如下所示,在你点击"Upload File"会弹出一个窗口让你选择要上传的文件: !\[sup1.jpg\](http://img.php.cn/upload/image/722/713/414/1476694089242277.jpg) ------ ## 后台JSP处理脚本 首先我们先定义文件上传后存储在服务上的位置,你可以将路径写在你的程序当中,或者我们可以在web.xml配置文件中通过设置 context-param 元素来设置文件存储的目录,如下所示: \`\`\`jsp .... 文件上传地址 file-upload c:\\apache-tomcat-5.5.29\\webapps\\data\\ .... \`\`\` 以下脚本文件UploadFile.jsp可以处理多个上传的文件,在使用该脚本前,我们需要注意以下几点: - 以下实例依赖 FileUpload, 所以你需要在你的classpath中引入最新的 \*\*commons-fileupload.x.x.jar\*\* 包文件。 下载地址为:http://commons.apache.org/fileupload/。 - FileUpload 依赖 Commons IO, 所以你需要在你的classpath中引入最新的 \*\*commons-io-x.x.jar\*\* 。 下载地址为: http://commons.apache.org/io/。 - 在测试以下实例时,你需要上传确认上传的文件大小小于 \*maxFileSize\* 变量设置的大小 ,否则文件无法上传成功。 - 确保你已经创建了目录 c:\\temp 和 c:\\apache-tomcat-5.5.29\\webapps\\data 。 \`\`\`jsp \<%@ page import="java.io.\*,java.util.\*, javax.servlet.\*" %\> \<%@ page import="javax.servlet.http.\*" %\> \<%@ page import="org.apache.commons.fileupload.\*" %\> \<%@ page import="org.apache.commons.fileupload.disk.\*" %\> \<%@ page import="org.apache.commons.fileupload.servlet.\*" %\> \<%@ page import="org.apache.commons.io.output.\*" %\> \<% File file ; int maxFileSize = 5000 \* 1024; int maxMemSize = 5000 \* 1024; ServletContext context = pageContext.getServletContext(); String filePath = context.getInitParameter("file-upload"); // 验证上传内容了类型 String contentType = request.getContentType(); if ((contentType.indexOf("multipart/form-data") \>= 0)) { DiskFileItemFactory factory = new DiskFileItemFactory(); // 设置内存中存储文件的最大值 factory.setSizeThreshold(maxMemSize); // 本地存储的数据大于 maxMemSize. factory.setRepository(new File("c:\\\\temp")); // 创建一个新的文件上传处理程序 ServletFileUpload upload = new ServletFileUpload(factory); // 设置最大上传的文件大小 upload.setSizeMax( maxFileSize ); try{ // 解析获取的文件 List fileItems = upload.parseRequest(request); // 处理上传的文件 Iterator i = fileItems.iterator(); out.println(""); out.println(""); out.println("JSP File upload"); out.println(""); out.println(""); while ( i.hasNext () ) { FileItem fi = (FileItem)i.next(); if ( !fi.isFormField () ) { // 获取上传文件的参数 String fieldName = fi.getFieldName(); String fileName = fi.getName(); boolean isInMemory = fi.isInMemory(); long sizeInBytes = fi.getSize(); // 写入文件 if( fileName.lastIndexOf("\\\\") \>= 0 ){ file = new File( filePath , fileName.substring( fileName.lastIndexOf("\\\\"))) ; }else{ file = new File( filePath , fileName.substring(fileName.lastIndexOf("\\\\")+1)) ; } fi.write( file ) ; out.println("Uploaded Filename: " + filePath + fileName + "
"); } } out.println(""); out.println(""); }catch(Exception ex) { System.out.println(ex); } }else{ out.println(""); out.println(""); out.println("Servlet upload"); out.println(""); out.println(""); out.println("
No file uploaded
"); out.println(""); out.println(""); } %\> \`\`\`
原创
jsp
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法