java web学习笔记-jsp篇
Posted coder为
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java web学习笔记-jsp篇相关的知识,希望对你有一定的参考价值。
转载自:http://www.cnblogs.com/happyfans/archive/2015/03/17/4343571.html
1.java web简介
1.1静态页面与动态页面
表现形式 | 所需技术 | |
静态网页 | 网页内容固定,不会更新 | html,css |
动态网页 | 网页内容由程序动态显示,自动更新 | html,css,DB,java/c#/php,javascript,xml,主流的动态网页脚本(jsp,asp.net,php) |
1.2搭建java web开发环境
jdk1.7+tomcat7.0+MyEclipse10。关于MyEclipse的安装和配置请参见http://blog.sina.com.cn/s/blog_907043b301016jtp.html。Tomcat服务器是Apache Jakarta的开源项目,是Jsp/Servlet容器。安装Tomcat只需要解压zip包到指定目录即可。新建一个环境变量CATALINA_HOME,变量的值是Tomcat的根目录D:\\Program Files (x86)\\apache-tomcat-7.0.57。全部的环境变量如下:
变量名 | 变量值 |
JAVA_HOME | D:\\Program Files (x86)\\Java\\jdk1.7.0_40 |
Path | C:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;%JAVA_HOME%\\bin;D:\\Program Files\\Sublime Text 3;D:\\Program Files\\mysql\\MySQL Utilities 1.3.6\\ |
classpath | .;%JAVA_HOME%\\lib\\rt.jar;%JAVA_HOME%\\lib\\tools.jar; |
CATALINA_HOME | D:\\Program Files (x86)\\apache-tomcat-7.0.57 |
之后我们测试一下Tomcat的首页:
进入Tomcat服务器根目录下面的bin目录,以管理员方式运行startup.bat,如果运行结果如下就表示Tomcat服务器启动成功。
注意:不要关闭这个窗口(关闭窗口就意味着关闭了Tomcat服务器,将其最小化)。
在浏览器地址栏输入http://localhost:8080/回车得到如下页面:
1.3Tomcat目录结构
1.4手工编写第一个web应用程序
在项目文件夹中创建一个index.jsp:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>手工编写的第一个java web项目</title> 6 </head> 7 <body> 8 <h1>这是手工编写的第一个java web项目——jsp</h1> 9 <hr /> 10 </body> 11 </html>
在项目目录中创建一个WEB-INF目录拷贝/webapps/examples/WEB-INFO/web.xm到自己项目的/myJspProject/WEB-INFO中,在/myJspProject/WEB-INFO中创建两个文件夹:classes和lib。最后的项目目录应该是这样:
测试:浏览器输入:http://localhost:8080/myJspProject/index.jsp回车,运行结果如下:
解决方法:更改浏览器编码为指定编码:
1.5WEB-INF目录详解
该目录是java web应用的安全目录。所谓安全目录就是客户端无法访问只有服务端可以访问的目录。其中web.xml是项目部署文件,classes目录:存放*.class文件,lib目录存放需要的jar包。例如:我们在WEB-INF中创建一个test.html,下面我们通过浏览器访问:
web.xml配置文件可以配置欢迎页面默认的欢迎页面是项目下面的index.jsp,加入我们需要将项目下的haha.jsp,在/WEB-INF/web.xml的web-app标记中添加以下代码:
1 <welcome-file-list> 2 <welcome-file>/haha.jsp</welcome-file> 3</welcome-file-list>
运行结果:
1.6实用Eclipse编写第一个web应用程序
注意:如果要使用Eclipse编写java web应用应该使用Eclipse的J2EE版本。并在Eclipse中配置Tomcat服务器Window-Preference-Server-Runtime Environment-Add,然后在WebContent目录下新建jsp文件,按下Ctrl+F11(或者在项目中右键-Run On Server)就可以使用内置浏览器访问建立的网站。
1.7用MyEclipse编写第一个web应用程序
在新建项目之前首先在MyEclipse中配置jre和tomcat。步骤Window-Preference-Java-Install JREs-Add;Window-MyEclipse-Servers-Tomcat(注意设置tomcat的jre并将服务器设置为Enabled)。
接下来在MyEclipse中启动Tomcat服务器:
测试首页http://localhost:8080/证明Tomcat正常启动,我们就可以在MyEclipse中启动和发布Web应用程序了。
New一个WebProject会生成以下的目录结构(默认在WebRoot目录下有一个index.jsp)。
发布该WebApp。
1.8理解项目的虚拟路径
该虚拟路径是可以修改的项目上右键属性-MyEclipse-Web。
重新部署,浏览器需要使用使用http://localhost:8080/hello/index.jsp访问了。
1.7修改Tomcat默认端口
修改conf目录下的server.xml的以下标记:
<Connector connectionTimeout="20000" port="8888" protocol="HTTP/1.1" redirectPort="8443"/>
2.jsp语法基础
2.1jsp简介
jsp的全名是Java Server Page,是一个简化的Servlet设计,它实现了在java当中使用html标记。jsp是一种动态网页技术,符合J2EE标准。jsp和Servlet一样也是在服务器端执行的。
2.2常见动态网站开发技术对比
平台 | 特点 |
jsp | 跨平台,安全性高,适合开发大型的、企业级的Web应用、分布式应用(Hadoop)。例如:12306、10086.cn、网上银行 |
asp.net | 简单易学,安全性和跨平台性差 |
php | 简单、高效、成本低、开发周期短,适合中小型企业的Web应用开发(LAMP) |
2.3jsp页面元素简介以及page指令
page指令语法:
<%@ page 属性1="属性值" 属性2="属性值1,属性值2" 属性n="属性值n"%>
属性 | 描述 | 默认值 |
language | jsp页面所使用的脚本语言 | java |
import | 引用脚本语言中所要使用的类文件 | 无 |
contentType | 指定jsp页面的编码 | text/html,ISO-8859-1 |
新建一个java web工程默认的jsp页面开头有一个page指令:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
默认的编码是ISO-8859-1,不支持中文,这里建议使用另一个属性contentType。将第一行改为如下:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
这样就支持中文了。
page指令的全部属性如下:
1 <%@page 2 [language="Java"] 3 [extends="package.class"] // 指定JSP页面编译所产生的Java类所继承的父类,或所实现的接口。 4 [import="package.class│package.*,…"] 5 [session="true│false"] 6 [buffer="none│8kb│size kb"] 7 [autoFlush="true│false"] 8 [isThreadSafe="true│false"] 9 [info="text"] 10 [errorPage="relativeURL"] // 指定错误处理页面。因为JSP内建了异常机制支持,所以JSP可以不处理异常。 11 [contentType="mimeType[;charset=characterSet]"│"text/html;charSet=ISO8859-1"] 12 [isErrorPage="true│false"] // 设置本JSP页面是否为错误处理程序。 13 %>
注意:除page指令中的import属性之外,其他属性均只能设置一次。
2.4jsp注释
分为3种:html注释,jsp注释,jsp脚本注释。语法:
1 <!-- html注释 --> 2 <%-- jsp注释 --%> 3 <% 4 /*这里是jsp脚本注释 有两种*/ 5 6 //单行注释 7 8 /*多行注释*/ 9 %>
例如:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP \'index.jsp\' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>欢迎你</h1> 25 <!-- 这是html注释,客户端可可见 --> 26 <%-- 这是jsp注释,客户端不可见 --%> 27 <% 28 /*这里是jsp脚本注释 29 有两种*/ 30 //单行注释 31 /*多行注释*/ 32 %> 33 </body> 34 </html>
将项目部署到Tomcat,客户端用浏览器查看源代码:
2.5jsp脚本
在jsp页面中执行的java代码。语法:
<% java代码 %>
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP \'index.jsp\' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>欢迎你</h1> 25 <hr> 26 <% 27 out.println("通过jsp内置对象out对象打印输出"); 28 %> 29 </body> 30 </html>
2.6jsp声明
jsp页面中定义变量或者方法。语法:
<%! java代码 %>
例如:
1 <%! 2 String s = "张三"; //声明一个String类型的变量 3 int add(int x,int y){ //声明一个返回值为int类型的方法 4 return x+y; 5 } 6 %>
2.7jsp表达式
jsp页面中执行的表达式。语法(注意=紧挨着百分号,表达式末尾没有分号):
<%=表达式 %>
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP \'index.jsp\' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <h1>欢迎你</h1> 25 <hr> 26 <!-- 这是html注释,客户端可可见 --> 27 <%! 28 String s = "张三"; //声明一个String类型的变量 29 int add(int x,int y){ //声明一个返回值为int类型的方法 30 return x+y; 31 } 32 %> 33 你好:<%=s %><br> 34 令x=10,y=5,则x+y = <%=add(10, 5) %> 35 </body> 36 </html>
运行结果:
2.8jsp页面生命周期
jspService()方法被调用来处理客户端的请求。对每一个请求,JSP引擎创建一个新的线程来处理该请求。如果有多个客户端同时请求你该jsp文件,则jsp引擎会创建多个线程(每一个客户端请求对应一个线程)。以多线程的方式执行可以大大降低对系统的资源需求,提高系统的并发量以及缩短服务器的响应时间——但是同时要注意多线程的同步问题。由于该Servlet常驻内存,所以响应是非常快的。
当页面没有被访问的时候work目录下没有相关的Servlet。如果页面被访问之后就会在work目录的对应目录生成响应的Servlet。如图:
打开index_jsp.java会看到以下的初始化方法:
然后该Servlet常驻内存,创建线程处理每一个客户端的请求。由每一个线程调用_jspService()方法来处理请求。
如果jsp页面内容发生了改变,jsp引擎就需要重新编译jsp页面。我们修改index.jsp,用浏览器重新访问,则:
2.9阶段项目(九九乘法表)
1 <%@page import="java.io.IOException"%> 2 <%@ page language="java" import="java.util.*" 3 contentType="text/html; charset=utf-8"%> 4 <% 5 String path = request.getContextPath(); 6 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 7 %> 8 9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 10 <html> 11 <head> 12 <base href="<%=basePath%>"> 13 14 <title>My JSP \'multiplicationTable.jsp\' starting page</title> 15 16 <meta http-equiv="pragma" content="no-cache"> 17 <meta http-equiv="cache-control" content="no-cache"> 18 <meta http-equiv="expires" content="0"> 19 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 20 <meta http-equiv="description" content="This is my page"> 21 22 23 </head> 24 25 <body> 26 <h1>九九乘法表</h1> 27 <h2>表达式的方式打印乘法表</h2> 28 <%! 29 //声明表达式 30 String printMultiTable(){ 31 StringBuilder s = new StringBuilder(); 32 for(int i=1;i<=9;i++){ 33 for(int j=1;j<=i;j++){ 34 s.append(i+" * "+j+" = "+i*j+"\\t"); 35 } 36 s.append("<br />");//追加换行标记,注意不能使用\\n 37 } 38 return s.toString(); 39 } 40 %> 41 <%=printMultiTable() //调用表达式 42 %> 43 44 <h2>使用脚本的方式打印九九乘法表</h2> 45 <%! 46 //jsp小脚本 47 void printMultiTable2(JspWriter out) throws IOException{ 48 StringBuilder s = new StringBuilder(); 49 for(int i=1;i<=9;i++){ 50 for(int j =1;j<=i;j++){ 51 s.append(i+" * "+j+" = "+i*j+"\\t"); 52 } 53 s.append("<br />"); 54 } 55 out.println(s.toString()); 56 } 57 %> 58 59 <% 60 //调用脚本 61 printMultiTable2(out); 62 %> 63 </body> 64 </html>
运行结果:
3.jsp内置对象
3.1jsp内置对象简介
JSP内置对象是Web容器创建的一组对象,不需要使用new关键字,JSP规范将它们完成了默认初始化(由JSP页面对应Servlet的_jspService()方法来创建这些实例)。例如打印九九乘法表的jsp小脚本中使用的out对象就是jsp内置对象。
1 <%! 2 //jsp小脚本 3 void printMultiTable2(JspWriter out) throws IOException{ 4 StringBuilder s = new StringBuilder(); 5 for(int i=1;i<=9;i++){ 6 for(int j =1;j<=i;j++){ 7 s.append(i+" * "+j+" = "+i*j+"\\t"); 8 } 9 s.append("<br />"); 10 } 11 out.println(s.toString());//这里的out就是jsp内置对象 12 } 13 %>
JSP一共有9个内置对象,其中常用的内置对象有5个,如图所示:
3.3out对象
缓冲区(Buffer)就是内存中用来保存临时数据的一块区域。关于缓冲区有一个很形象的例子:比如我们煮好了饭放在锅里,如果我们一粒一粒地来吃米饭就不知道吃到猴年马月,拿来一个碗来一碗一碗吃,岂不快哉!这里的碗就充当了缓冲区的概念。其实IO的本质就是直接操作字节,但是效率太慢所以引入了缓冲区。
out对象是JspWriter类的一个实例——是向客户端输出内容的常用对象,该对象的常用方法:
1 void println(String message); // 向客户端打印字符串 2 void clear(); // 清除缓冲区内容,如果在flush之后调用会抛出异常 3 void clearBuffer(); // 清除缓冲区内容,如果在flush之后调用不会抛出异常 4 void flush(); // 将缓冲区的内容输出到客户端 5 int getBufferSize(); // 返回缓冲区的大小(字节),默认是0 6 int getRemaining(); // 返回缓冲区可用容量 7 boolean isAutoFlush(); // 返回缓冲区满的时候是自动清空还是抛出异常 8 void close(); // 关闭输出流
下面是一个简单的示例:
1 <h1>JSP的out内置对象</h1> 2 <% 3 //jsp脚本 4 out.println("<h2>静夜思</h2>"); 5 out.println("李白<br /><br />"); 6 out.println("窗前明月光,<br />"); 7 out.println("疑是地上霜。<br />"); 8 out.println("举头望明月,<br />"); 9 out.println("低头思故乡。<hr />"); 10 %> 11 <!-- JSP表达式 --> 12 缓冲区大小:<%=out.getBufferSize() %>字节。<br /> 13 剩余缓冲区(可用缓冲区):<%=out.getRemaining() %>字节。<br /> 14 是否自动清空缓冲区:<%=out.isAutoFlush() %><br />
运行结果:
1 <h1>JSP的out内置对象</h1> 2 <% 3 //jsp脚本 4 out.println("<h2>静夜思</h2>"); 5 out.println("李白<br /><br />"); 6 out.println("窗前明月光,<br />");
7 out.flush();//将缓冲区中的内容输出到客户端
8 out.println("疑是地上霜。<br />"); 9 out.println("举头望明月,<br />"); 10 out.println("低头思故乡。<hr />"); 11 %> 12 <!-- JSP表达式 --> 13 缓冲区大小:<%=out.getBufferSize() %>字节。<br /> 14 剩余缓冲区(可用缓冲区):<%=out.getRemaining() %>字节。<br /> 15 是否自动清空缓冲区:<%=out.isAutoFlush() %><br />
如果在第7行强制刷新缓冲区,则输出的页面不会有任何变化,仅仅是可用缓冲区的数量变多了而已【因为flush清空了缓冲区】
1 <% 2 //jsp脚本 3 out.println("<h2>静夜思</h2>"); 4 out.println("李白<br /><br />"); 5 out.println("窗前明月光,<br />"); 6 7 out.flush();//将缓冲区中的内容输出到客户端 8 out.clear();//在flush之后调用clear,将会抛出异常 9 10 out.println("疑是地上霜。<br />"); 11 out.println("举头望明月,<br />"); 12 out.println("低头思故乡。<hr />"); 13 %>
运行结果:
1 <% 2 //jsp脚本 3 out.println("<h2>静夜思</h2>"); 4 out.println("李白<br /><br />"); 5 out.println("窗前明月光,<br />"); 6 7 out.flush();//将缓冲区中的内容输出到客户端 8 out.clearBuffer();//在flush之后调用clearBuffer不会抛出异常 9 10 out.println("疑是地上霜。<br />"); 11 out.println("举头望明月,<br />"); 12 out.println("低头思故乡。<hr />"); 13 %>
运行结果:
3.4post和get提交方式的区别
<form name="regForm" action="处理脚本" method="提交方式[post|get]"></form>
- get:以明文的方式通过URL提交数据,提交的数据最大不超过2K。适合提交数据量小,安全性不高的数据【例如:搜索和查询】
- post:将用户提交的数据封装在URL HEADER内。适合提交数据量大,安全性高的数据【例如:注册、修改、上传】 下面以用户登录的例子比较两者的区别:
- login.jsp页面
1 请输入用户名和密码: 2 <form name = "loginForm" action = "dologin.jsp" method = "get"> 3 用户名:<input type="text" name="username" value="" maxlength = "15" /><br /> 4 密码:<input type="password" name="password" maxlength="16" value="" /><br /> 5 <input type="submit" value="提交" /> 6 </form>
处理登录的动作脚本dologin.jsp仅仅是显示一句话"登录成功"。
运行结果:
将用户登录表单的get方式改为post。
3.5request对象
客户端的请求被封装在request对象中,通过它才能了解到客户端的需求,然后做出响应。它是HttpServletRequest对象的实例。request对象具有请求域,即:完成客户端的请求之前,该对象一直有效。常用方法如下:
/* 两个比较常用的方法 */
1 String getParameter(String name); // 返回name指定参数的参数值 2 String[] getParameterValues(String name); // 返回包含name的所有值的数组
3 void setAttribute(String,Object); // 存储此请求中的属性 4 String getContentType(); // 返回请求体的MIME类型 5 Stirng getProtocol(); // 返回请求所用的协议和版本号 6 String getServerName(); // 返回接受请求的服务器的主机名 7 int getServerPort(); // 返回服务器接受此请求所用的端口号 8 String getCharacterEncoding(); // 返回字符编码方式【只能解决post方式的乱码问题】 9 void setCharacterEncoding(); // 设置请求的字符编码方式 10 int getContentLength(); // 返回请求体的长度(字节) 11 String getRemoteAddr(); // 返回发送此请求的客户端IP 12 String getRealPath(String path); // 返回虚拟路径的真实路径 13 String request.getContextPath(); // 返回上下文路径
以用户注册页面为例(用户在注册页reg.jsp完善信息后提交给request.jsp来处理):
用户注册页reg.jsp
1 请输入相关信息完成注册<br /> 2 <form action="request.jsp" name="regForm" method="post"> 3 用户名:<input type="text" name = "username" /><br /> 4 密码:<input type="password" name = "password" /><br /> 5 爱好: 6 <input type="checkbox" name = "favorite" value="read"/>读书 7 <input type="checkbox" name = "favorite" value="music"/>音乐 8 <input type="checkbox" name = "favorite" value="movie"/>电影 9 <input type="checkbox" name = "favorite" value="internet"/>上网<br /> 10 <input type="submit" value="提交" /> 11 </form>
处理用户注册页的request.jsp
1 <h1>request内置对象</h1><br /> 2 3 用户名:<%=request.getParameter("username") %><br /> 4 密码:<%=request.getParameter("password") %><hr /> 5 爱好:<br /> 6 <% 7 String[]favorites = request.getParameterValues("favorite"); 8 for(String str:favorites){ 9 out.print(str+" "); 10 } 11 %>
运行结果:
但是以上页面存在一个问题:假如我们在用户名中输入中文:
这时只要再request.jsp中设置字符集和reg.jsp一样即可:
1 <h1>request内置对象</h1><br /> 2 <!-- 设置字符集,防止出现中文乱码 --> 3 <% request.setCharacterEncoding("utf-8"); %>
4 用户名:<%=request.getParameter("username") %><br /> 5 密码:<%=request.getParameter("password") %><hr /> 6 爱好:<br /> 7 <% 8 String[]favorites = request.getParameterValues("favorite"); 9 for(String str:favorites){ 10 out.print(str+" "); 11 } 12 %>
除了可以使用表单的方式传递数据给request对象,也可以使用URL传参的方式传递数据给request对象:
reg.jsp
<a href="request.jsp?username=root&password=toor&favorite=read&favorite=internet">测试URL传参</a>
request.jsp(不变)
1 <h1>request内置对象</h1><br /> 2 <!-- 设置字符集,防止出现中文乱码 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 用户名:<%=request.getParameter("username") %><br /> 5 密码:<%=request.getParameter("password") %><hr /> 6 爱好:<br /> 7 <% 8 String[]favorites; 9 if((favorites=request.getParameterValues("favorite"))!=null){ 10 for(String str:favorites){ 11 out.print(str+" "); 12 } 13 } 14 %>
运行结果:
如果我们在URL传参中传入了中文数据,同样会出现乱码问题:
<a href="request.jsp?username=你好&password=toor&favorite=read&favorite=internet">测试URL传参</a>
此时通过request.setCharacterEncoding()方法就无法解决乱码问题了【一个良好的解决方案是修改tomcat的配置文件server.xml】
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
向request对象中添加键值对:
reg.jsp:
1 请输入相关信息完成注册<br /> 2 <form action="request.jsp" name="regForm" method="post"> 3 用户名:<input type="text" name = "username" /><br /> 4 密码:<input type="password" name = "password" /><br /> 5 爱好: 6 <input type="checkbox" name = "favorite" value="read"/>读书 7 <input type="checkbox" name = "favorite" value="music"/>音乐 8 <input type="checkbox" name = "favorite" value="movie"/>电影 9 <input type="checkbox" name = "favorite" value="internet"/>上网<br /> 10 <input type="submit" value="提交" /> 11 </form>
request.jsp
1 <h1>request内置对象</h1><br /> 2 <!-- 设置字符集,防止出现中文乱码 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 <% 5 //在request对象中保存一个email属性 6 request.setAttribute("email","io@gmail.com"); 7 8 %> 9 用户名:<%=request.getParameter("username") %><br /> 10 密码:<%=request.getParameter("password") %><hr /> 11 爱好:<br /> 12 <% 13 String[]favorites; 14 if((favorites=request.getParameterValues("favorite"))!=null){ 15 for(String str:favorites){ 16 out.print(str+" "); 17 } 18 } 19 %> 20 <br />邮箱:<%=request.getAttribute("email") %>
运行结果:
1 <h1>request内置对象</h1><br /> 2 <!-- 设置字符集,防止出现中文乱码 --> 3 <% request.setCharacterEncoding("utf-8"); %> 4 <% 5 //在request对象中保存一个email属性 6 request.setAttribute("email","io@gmail.com"); 7 8 %> 9 用户名:<%=request.getParameter("username") %><br /> 10 密码:<%=request.getParameter("password") %><hr /> 11 爱好:<br /> 12 <% 13 String[]favorites; 14 if((favorites=request.getParameterValues("favorite"))!=null){ 15 for(String str:favorites){ 16 out.print(str+" "); 17 } 18 } 19 %> 20 <br />邮箱:<%=request.getAttribute("email") %> <hr /> 21 请求体的MIME类型:<%=request.getContentType() %><br /> 22 请求体的协议及版本号:<%=request.getProtocol() %><br /> 23 服务器主机名:<%=request.getServerName() %><br /> 24 服务器端口号:<%=request.getServerPort() %><br /> 25 请求的字符编码:<%=request.getCharacterEncoding() %><br /> 26 请求的文件长度:<%=request.getContentLength() %>字节<br /> 27 请求的客户端的IP:<%=request.getRemoteAddr() %><br /> 28 请求的真实路径:<%=request.getRealPath("request.jsp") %><br /> 29 请求的上下文路径:<%=request.getContextPath() %>
运行结果:
3.6response对象
response对象包含了响应客户请求的相关信息,但是在JSP中很少直接使用到它。它是HttpServletResponse类的实例。response对象具有页面作用域——即:访问一个页面时,该页面的response只对本次访问有效,其他页面的response对象对当前页面无效。常用方法如下:
1 String getCharacterEncoding(); // 返回响应所用的编码 2 void setContentType(); // 设置响应的MIME类型 3 PrintWriter getPrintWriter(); // 返回一个可以向客户端输出字符的对象【注意区别于out内置对象】 4 sendRedirect(String location); // 重定向客户端的请求
response.jsp
1 <%@page import="java.io.PrintWriter"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 <% 4 response.setContentType("text/html;charset=utf-8");//设置响应的MIME类型 5 6 out.println("<h1>response内置对象</h1><hr />"); 7 8 PrintWriter outer = response.getWriter();//获得输出流对象 9 outer.println("我是response对象生成的outter对象,在页面中总是在前面输出"); 10 %>
运行结果:
运行结果很是奇怪:明明out对象的输出在代码中位于前面。但是结果却是PrintWriter的打印结果在前面,根本原因就是:PrintWriter的对象的输出总是在最前面。如果我们需要让标题先输出,可以使用内置对象out的flush()方法强制刷新缓冲,向页面输出——保证标题出现在最前面。
请求重定向——当用户请求response.jsp的时候马上跳转到login.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> <% response.sendRedirect("login.jsp"); // 请求重定向 %>
3.7请求重定向与请求转发的区别
- 请求重定向:客户端行为response.sendResponse(),从本质上讲相当于两次请求,前一次的请求对象不会保存,浏览器的URL栏会改变。
- 请求转发:服务器行为request.getRequestDipatcher().forword(req,resp);是一次请求,转发后请求对象会被保存,浏览器的URL不会改变。 例如还是用原来的例子:我们在reg.jsp中指定处理页面的脚本是response.jsp而在response.jsp中我们重定向到request.jsp。观察request.jsp的输出:
如果我们在response.jsp中使用请求转发:
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 2 <% 3 //请求转发 4 request.getRequestDispatcher("request.jsp").forward(request, response); 5 %>
运行结果:
3.8session对象
Session客户端与服务器的一次会话。Web中的Session表示用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间——也就是用户浏览这个网站所花费的时间。在服务器的内存中保存着不同用户的Session。
session对象的常用方法:
1 long getCreationTime(); // 返回session的创建时间 2 String getId(); // 返回session创建时JSP引擎为它设定的唯一ID号 3 Object setAttribute(String name,Object value); // 使用指定名称将对象绑定到此会话 4 Object getAttribute(String name); // 返回此会话中的指定名称绑定在一起的对象,如果没有对象绑定在该名称下则返回null 5 String[] getValueNames(); // 返回一个包含此Session所有可用属性的数组 6 int getMaxInactiveInterval(); // 返回两次请求间隔多长时间此session被取消【单位:秒】
sesseion_page1.jsp
1 <h1>session内置对象</h1> 2 <h2>session_page1.jsp</h2> 3 <% 4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 5 String date = sdf.format(new Date(session.getCreationTime())); 6 out.print("session的创建时间:" + date); 7 session.setAttribute("username", "admin"); // 向session中设置属性 8 %> 9 <br />Session的ID号:<%=session.getId() %><br /> 10 从session中获取用户名:<%=session.getAttribute("username") %> 11 12 <a href="session_page2.jsp" target="_blank">以新窗口的方式打开session_page2.jsp</a>
session_page2.jsp
1 <h2>session_page2.jsp</h2> 2 <% 3 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 4 String date = sdf.format(new Date(session.getCreationTime())); 5 out.print("session的创建时间:" + date); 6 %> 7 <br />Session的ID号:<%=session.getId() %><br /> 8 从session中获取用户名:<%=session.getAttribute("username") %>
运行结果:
可以获取session中保存的属性集合以及设置session的有效期:
1 <% 2 session.setMaxInactiveInterval(5);//设置session的有效期为5s 3 4 session.setAttribute("username", "admin"); // 向session中设置属性 5 session.setAttribute("password", "123456"); 6 session.setAttribute("age", 16); 7 %> 8 9 <% 10 //获取session中保存的属性 11 String[]names=session.getValueNames(); 12 if(names!=null){ 13 for(String str:names){ 14 out.print(str+"\\t"); 15 } 16 } 17 %>
Session的生命周期:
- 创建:当客户端第一次访问某个jsp页面或者Servlet的时候,服务器会为当前会话创建一个SessionId。每次客户端向服务器发送请求的时候都会携带此SessionId,服务端会对此SessionId进行检验——判断是否属于同一次会话。
- 活动阶段:某次会话中通过超链接打开新的页面;只要当前页面没有全部关闭,打开新的浏览器窗口访问同一项目资源也属于同一会话。注意:原有的会话仍然存在,只不过再也没有客户端会携带此sessionId交给服务器检验。——创建一个新的会话并不意味着原有会话消失,除非超时。
- 销毁。
Tomcat如何进入后台管理系统?
修改/conf/tomcat-user.xml为以下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <tomcat-users> 3 <role rolename="admin-gui"/> 4 <role rolename="manager-gui"/> 5 <user username="admin" password="admin" roles="admin-gui,manager-gui"></user> 6 </tomcat-users>
在浏览器中打开session_page1.jsp然后通过session_page1.jsp的超链接打开session_page2.jsp在后台管理系统中查看:
如果我们在session创建之后调用session.invalidate()方法,例如:我们在session_page1.jsp中这样写:
1 <h1>session内置对象</h1> 2 <h2>session_page1.jsp</h2> 3 <% 4 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 5 String date = sdf.format(new Date(session.getCreationTime())); 6 out.print("session的创建时间:" + date); 7 10 session.setAttribute("username", "admin"); // 向session中设置属性 11 session.setAttribute("password", "123456"); 12 session.setAttribute("age", 16); 13 %> 14 <br />Session的ID号:<%=session.getId() %><hr /> 15 session中保存的属性有:<br /> 16 <% 17 //获取session中保存的属性 18 String[]names=session.getValueNames(); 19 if(names!=null){ 20 for(String str:names){ 21 out.print(str+"\\t"); 22 } 23 } 24 session.invalidate();//销毁session 25 %> 26 <a href = "session_page2.jsp" target = "_blank">点击在新标签页中打开session_page2.jsp</a>
运行结果(不断刷新浏览器):
Session默认session超时是30min设置session对象的超时有两种方式:
- session.setMaxInactiveInterval(5);单位是秒
- 在web.xml中配置(单位是分钟):
-
<session-config> <session-timeout>30</session-timeout> </session-config>
3.9application对象
- application对象实现了用户间数据的共享,可以存放全局变量。
- application对象开始于服务器的启动,结束于服务器的关闭。
- 在用户的前后连接或者不同用户之间,可以对统一个application对象的属性进行操作。
- 在任何地方对application对象属性的操作将会影响到其他用户对此的访问。
- application对象是ServletContext类的实例。 该对象的常用方法如下:
1 void setAttribute(String name,Object value); // 指定名称将对象绑定到此会话 2 Object getAttribute(String name); // 返回此会话中和指定名称绑定在一起的对象,如果没有对象绑定在该名称下则返回null 3 Enumeration getAttributeNames(); // 返回所有可用属性名的枚举 4 String getServerInfo(); // 返回JSP(Servlet)引擎名和版本号
1 <h1>application对象</h1> 2 <% 3 //在application中保存3个键值对 4 application.setAttribute("city", "北京"); 5 application.setAttribute("zipcode", "10000"); 6 application.setAttribute("email", "io@gmail.com"); 7 %> 8 所在城市:<%=application.getAttribute("city") %><hr> 9 application中存放的属性有:<br> 10 <% 11 Enumeration attrs = application.getAttributeNames(); 12 while(attrs.hasMoreElements()){ 13 out.print(attrs.nextElement()+"<br>"); 14 } 15 %> 16 <hr> 17 jsp(Servlet)引擎:<%=application.getServerInfo() %><br>
运行效果:
3.10page对象
page对象就是指向当前jsp页面本身(就好像类中的this),是java.lang.Object类的实例,常用方法和Object类的方法一致。例如它的toString()方法:
1 <h1>page内置对象</h1> 2 当前页面的page对象的字符串描述:<br /> 3 <%=page.toString() %>
运行结果:
我们打开tomcat的work目录(编译生成的Servlet目录)看到它的包结构是org.apache.jsp,在该目录下有一系列的*_jsp.java和*_jsp.class文件。我们打开page_jsp.java发现类名就是page_jsp。
3.11pageContext对象
- 提供了对JSP页面内所有的对象及名字空间的访问。
- 可以访问到本页所在的session,也可以取本页面所在的application的某一属性值
- 相当于页面中所有功能的集大成者。
- pageContext对象的本类名也叫pageContext。 常用方法:
1 JspWriter getOut(); // 返回当前客户端响应被使用的JspWriter流(out) 2 HttpSession getSession(); // 返回当前页中的HttpSession对象(session) 3 Object getPage(); // 返回当前页面的Object对象(page) 4 ServletRequest getRequest(); // 返回当前页面的ServletRequest对象(request) 5 ServletResponse getResponse(); // 返回当前页面的ServletResponse对象(response) 6 void setAttribute(String name,Object value); // 设置属性键值对 7 Object getAttribute(String name,int scope); // 在指定范围内取属性值 8 void forward(String relativeUrlPath); // 将当前页面重定向到另一页面 9 void include(String relativeUrlPath); // 在当前页面包含另一文件
我们在session_page1.jsp中向session中设置了用户名:
<% session.setAttribute("username", "admin"); %>
现在我们在pageContext.jsp中取出session中存储的用户名(注意要先打开session_page1.jsp):
<h1>pageContext内置对象</h1> 用户名:<%=pageContext.getSession().getAttribute("username") %>
运行结果:
用pageContext实现页面跳转:
<% pageContext.forward("reg.jsp"); %>
运行结果:
新建一个include.jsp(页面用于向页面输出当前的日期):
1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%> 3 <% 4 out.print(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())); 5 %>
下面我们在pageContext.jsp页面中包含include.jsp:
1 <h1>pageContext内置对象</h1> 2 用户名:<%=pageContext.getSession().getAttribute("username") %><hr> 3 4 <!-- 包含其他页面 --> 5 <%pageContext.include("include.jsp"); %>
3.12config对象
该对象是一个在servlet初始化时,jsp引擎向它传递信息时使用的,此信息包含Servlet初始化时所用到的参数(键-值对)以及服务器的相关信息(通过传递一个ServletContext对象),常用方法:
1 ServletContext getServletContext(); // 返回服务器相关信息的ServletContext对象 2 String getInitParameter(String name);// 返回初始化参数的值 3 Enumeration getInitParameterNames(); // 返回Servlet初始化时所有需要参数的枚举
3.13exception对象
该对象是一个异常对象,如果一个页面在运行过程中出现了异常就会产生这个对象。如果一个JSP页面需要应用此对象,就必须把isErrorPage设为true——否则无法编译。它实际上是java.lang.Throwable的对象,常用方法:
1 String getMessage(); // 返回异常的描述信息 2 String toString(); // 返回关于异常的简短描述信息 3 void printStackTrace(); // 显示异常及其栈轨迹 4 Throwable FillInStackTrace(); // 重写异常的执行栈轨迹
首先建立一个会出现异常的页面exception_text.jsp(并指定处理异常的页面):
1 <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" errorPage="exception.jsp"%> 2 <!-- 在errorPage中指定处理异常的页面 --> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>这个页面肯定会出现异常</title> 7 </head> 8 9 <body> 10 <h1>测试异常对象</h1><hr /> 11 <% 12 out.println(100/0);//肯定会抛出运行时异常【算术异常】 13 %> 14 </body> 15 </html>
然后建立处理异常的页面exception.jsp: