Servlet
servelt:(基于网络的)
什么是Servelt:
运行在web服务器或应用服务器上的java程序,他是一个中间层负责连接来自web浏览器或其他HTTP客户程序的请求和HTTP服务器上的数据库或应用程序。
为什么使用servlet:
Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。
Servlet的优点:
servlet是用Java编写的,所以它们一开始就是平台无关的。这样,Java编写一次就可以在任何平台运行(write once,run anywhere)的承诺就同样可以在服务器上实现了。servlet还有一些独特优点:
■servlet是持久的。servlet只需Web服务器加载一次,而且可以在不同请求之间保持服务(例如一次数据库连接) ■servlet是与平台无关的。如前所述,servlet是用Java编写的,它自然也继承了Java的平台无关性。
■servlet是可扩展的。由于servlet是用Java编写的,它就具备了Java所能带来的所有优点。Java是健壮的、面向对象的编程语言,它很容易扩展以适应你的需求。servlet自然也具备了这些特征。
■servlet是安全的。从外界调用一个servlet的惟一方法就是通过Web服务器。这提供了高水平的安全性保障,尤其是在你的Web服务器有防火墙保护的时候。
■setvlet可以在多种多样的客户机上使用。由于servlet是用Java编写的,所以你可以很方便地在HTML中使用它们。
总结:
servlet高效、可移植、功能强大且在行业中广泛采用
和实际的部署服务器无关,可以在桌面计算机上运行免费的服务器用于开发
我们项目中用到的servlet的作用:
读取客户发送的所有数据,查询HTTP请求中包含的任何其他请求信息,处理数据并生成结果,设置合适的HTTP的响应参数,将响应信息回送给客户端
web:
什么是web:
含有浏览器的客户端和服务器端,客户端和服务器端通过有线的或无线的网络连接起来的,什么是有线,就例如我们家里用的宽带,无线呢,就例如我们平时用的wiffy,通过这些网络服务器端和客户端产生的一些交互,就是平时我们上网看电影,购物就是访问web.那么我们接下来做的web项目就是能够在浏览器中访问我们做的项目。就是用户发送请求,例如我想搜一下美女图片,我们是不是应该在客户端打开浏览器,这个浏览器是不是有很多种,比如IE浏览器,第一步:在浏览器里输入“美女图片”,那么输入的这个“美女图片”然后回车,这就是客户端向服务器发送了一次请求,告诉服务器端我要干什么,这个过程是不是就是我发送的一次请求。第二步就是在浏览器中我看到了美女图片,图片是不是浏览器显示出来的?就是我告诉服务器我要美女图片,服务器就给我了美女图片,那么这个过程就是服务器端对客户端发送的请求给的回应。那么总结一下,请求就是浏览器到服务器端,响应就是服务器端到浏览器端。
什么是请求和响应?
HTTP请求信息:
请求的组成部分:
(1).请求行:由3个标记方法组成,请求方法,请求URL和HTTP版本,用空格分隔
(2).请求头域:有关键字/值对组成,每行一对,关键字和值用冒号分开。
(3).空行:最后一个请求头标之后是一个空行
(4).请求数据:使用Post传送数据,最长使用的是Content-Type和Content-length头标
HTTP响应信息:
响应信息的组成部分:
(1).状态行:HTTP版本,响应代码和响应描述
(2).响应头标:像请求头标一样,他们指出服务器的功能,标识响应数据细节
(3).空行:最后一个响应头标之后是一个空行
(4).响应数据:HTML文档等
TTP协议:(Hypertext Transfer Protocl)
Hypertext:超文本 Transfer:传输 Protocol: 协议
1.0版本和1.1版本(我们用)
HHTTP协议规定web的基本运作过程,基于客户/服务器通信模式,客户端发出请求,服务器端接收HTTP请求,再返回相应的HTTP响应结果
http是一种协议,那么它是有状态的还是无状态的呢?
HTTP无状态:浏览器和服务器之间不需要建立持久的联系,例如:上网看新闻,我打开了一个网页,发送了一次请求,给了我响应,但是并没有记录我看过新闻,这就是无状态
HTTP有状态:浏览器和服务器之间建立了持久的联系,也可以是一段时间的联系,例如,我到网上买东西,我把一件东西放到购物车中,记录我放入购物车里的东西,当我下次登录的时候还会看到购物车里的东西。这就是有状态。
超文本传输协议:采用客户/服务器通信模式,服务器端为HTTP服务器,也称web服务器,客户端为HTTP客户程序,浏览器是最常见的HTTP客户程序
HTTP请求方式:
(1)GET:客户程序通过这种请求方式,访问服务器上的一个文档,并由服务器把文档发送给客户程序,存储数据量小,不安全,传输快,地址栏长度有限制,最多2kb,编码格式不支持中文,ISO 8859-1
(2)POST:客户程序通过这种方式向服务器发送大量信息,在HTTP请求中除了包含要访问的文档的URL,还包括大量的请求正文,会包含HTTP表单数据,存储量大,安全,传输慢,地址栏长度在IE中最多为2G,编码格式为对应的网页的编码格式
(3)HEAD
(4)PUT
(5)DELETE
(6)OPTIONS
(7)TRACE
在页面中我们最常用的请求方式就是get和post,而为了安全我们在编程的过程中最常用的是Post
状态码:
1**:信息提示,表示临时的响应
2**:响应成功,表示服务器成功的接收到客户端的请求
3**:重定向
4**:客户端错误,表明客户端可能出现问题
5**:服务器错误,表明服务器由于遇到某种错误而不能响应客户端请求
常见的状态码:
200:响应成功
302:临时重定向
401:未经授权
400:错误的请求,客户发送的HTTP请求不正确
404:文件不存在,在服务器上没有客户要访问的文档(不允许请求的方法)
405:服务器不支持客户的请求
500:服务器内部错误
501:服务器不支持能够满足请求的功能
503:服务器不可用
URL和 URI的区别:(绝对路径和相对路径的区别)
URL:统一资源定位符(Uniform Resource Locator),用于完整的描述Inteernet上网页和其他资源的地址的一种标识方法
组成:协议+服务器地址(端口)+具体资源路径,如果端口号是该协议的标准端口号,可以省略端口号
例:hhtp://www.soccer.org.8080/laggue/spring200/html
URI:统一资源标识符(Uniform Resource Identifier),相对于URL是指资源相对于当前页面的地址,它包含从当前页面指向目标页面位置的路径
3种写法:(1).同一目录下只需要输入连接的文件名
(2).上一级目录在目录名和文件名前加“../”
(3).下一级目录输入目录名和文件名之间用“/”隔开
Tomcat:
什么是Tomcat?
Tomcat是一个免费的开放源代码的web应用服务器,它是Apatche软件基金会(Apache Softwar Foundation )的JAKARTA项目中的一个核心项目,由Apache和SUN还有一些其他公司及个人共同完成的。由于有了SUN的参与和支持最新的SERVLE和JSP规范总能在Tomcat中体现出来因为Tomcat性能稳定,而且免费,所以深受JAVA爱好者的喜爱,并得到了部分软件开发商的认可,成为当前比较流行的web应用服务器。
Tomcat目录结构:
(8) Bin:存放启动和关闭tomcat脚本。
(9)Conf:存放不同的配置文件,如server.xml ,Tomcat的主要配置信息,端口号,HTTP协议版本等都在里面,tomcat-users.xml,tomcat的角色。端口号的范围:0-65535
(10) Work:存放JSP编译后产生的class文件。
(11)Webapps:Tomcat的主要Web发布目录。
(12)Logs:存放Tomcat执行时的日志文件。
(13)Temp:Java虚拟机处理文件用的文件夹
(14)Lib:存放tomcat服务器所需的各种jar包
访问本机的tomcat的三种方法:
http://localhost:8080 http://127.0.0.1:8080 http://192.168.4.99:8080
常见的端口号:21:ftp 80:http 8080:tomcat mysql:3306 1521:oracle
环境变量:
Path:指定机器中javac和java的路径,到jdk的bin路径
Classpath:寻找servlet相关所在的路径,到jdk中lib下的servlet-api.jar
Java_home:启动时需要找到jvm,到jdk
为了确保tomcat正常启动,必须配置java_home,其他两个可以没有,三个变量都配置的目的:为了正常开发web项目应用程序,并且能够发布访问web应用程序。
启动Tomcat: E:\姚璐\Java\apache-tomcat-6.0.36\bin\startup.bat
关闭Tomcat: E:\姚璐\Java\apache-tomcat-6.0.36\bin\shutdown.bat
CS与BS
C/S(Client/Server)结构程序,就是指(客户端/服务器)程序,我们主要用cs结构来开发面向桌面的应用程序,他最大的特点就是如果你想用这个程序,你必须安装他的客户端到你的电脑上才能使用,并且如果服务器端更新,客户端必须也更新,不然无法使用。比如:qq和一些大型的网络游戏都是典型的C/S结构程序。
B/S(Browser/Server)结构程序,就是指(浏览器/服务器)程序,我们主要用bs结构来开发面向Internet的应用程序。程序完全部署在服务器上,用户通过浏览器访问应用程序,它是基于Internet的产物。比如:一些购物网站、论坛等都是B/S结构程序。
目前在应用程序开发方面,以B/S结构应用程序开发的比较多,市场比较广,所以我们的课程也主要学习B/S结构程序的开发。
通过下面的图进一步理解B/S结构程序的运行流程
Servlet容器:
Servlet容器有时候也叫做Servlet引擎,是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务。Servlet不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用Servlet的方法,Servlet容器在Servlet的生命周期内包容和管理Servlet。
Servlet类必须部署在一个服务器中才能运行,我们可以管这个服务器叫做Servlet容器。
Servlet的作用:
读取客户发送的所有数据,,查询HTTP请求中包含的任何其他请求信息,处理数据并生成结果,设置合适的HTTP响应参数,将响应信息回送给客户端,servlet本领高的两个原因:(1)由java语言编写的,(2)由servlet容器创建
Servlet的特点:
(1)提供了可被服务器动态加载并执行的程序代码,为来自客户的请求提供相应的服务
(2)Servlet完全java语言编写,因此运行servlet的服务器必须支持java语言
(3)Servlet完全在服务器端运行,因此它的运行不依赖浏览器,不管浏览器是否zhichijava语言,都能请求访问服务器端的servlet
Servlet
Javax.servlet包:
接口:ServletConfig ServeltContext RequestDispatcher Servlet ServletRequest ServletResponse
类:GenericServlet
Javax.servlet.http包:
类:HttpServlet 继承GenericServlet
接口:HttpServletRequest 继承ServletRequest
HttpServletResponse 继承ServletResponse
Servlet常用武器:
(1).请求对象:ServletRequest和HttpServletRequest,获取来自客户端的请求信息
(2).响应对象:ServletResponse和HttpServletResponse,生成响应结果
(3).Servlet配置对象ServletConfig,当容器初始化一个Servlet对象时会向servlet提供一个ServletConfig对象,通过该对象获取初始化参数信息以及ServletContext对象
(4).Servlet上下文对象,ServletContext,访问容器当前web应用提供的各种资源
(5).各接口之间的关系
(6).动态结构,各种对象在运行时的协作过程,以及各种对象的生命周期
定义一个servlet步骤
定义一个Servlet类,在javax.servlet包中定义了所有的Servlet类都必须实现或扩展的的通用接口和类.在javax.servlet.http包中定义了采用HTTP协议的HttpServlet类。我们自己定义的servlet需要继承HttpServlet,而GenericServlet是HttpServlet的父类,我们为什么不继承GenericServlet而是继承了HttpServlet?GenericServlet是抽象类,并且没在http包中,HttpServlet类,是抽象类,继承了GenericServlet,实现了Servlet接口,位于http包中。我们的请求和响应都是基于http协议的,所以我们自定义的servlet类需要继承HttpServlet类。
在多数的网络应用中,都是客户端(浏览器)通过http协议去访问服务器的资源,而我们所编写的servlet也主要是应用于http协议的请求和响应。为了快速开发应用于这个协议的servlet类,sun公司提供了HttpServlet这个类。
HttpServlet简介:(抽象类)
适合用于运行在与客户端采用Http协议通信的servlet容器或者服务器中,在Java Web应用时,自定义的Servlet类一般都扩展HttpServlet,HttpServlet实现了Servlet接口中的service(ServletRequest req ,ServletResponse res)方法,该方法实际上调用的是它的重载方法service(HttpServletRequest req,HttpServletResponse res),service处理请求时首先调用HttpServletRequest类型的参数的getMethod()方法,从而获得客户端的请求方式,再根据请求方式调用方法,如果是Get就调用doGet方法,如果是Post 就调用doPost方法
HttpServletRequest和HttpServletResponse接口
Servlet由Servlet容器来管理,当客户请求到来时,容器创建一个ServletRequest对象,封装请求数据,同时创建一个ServletResponse对象,封装相应数据。而ServletResponse和ServletRquest还有子接口HttpServletRequest和HttpServletResponse接口,父接口是通用的请求和响应,但是我们目前应用的都是基于http协议的,所以用他的子接口。
HttpServletRequest,代表客户端传送过来的请求,包含了ip地址、form表单的参数等信息。
HttpServletResponse,代表服务器给客户端的响应。
HttpServletRequest和HttpServletResponse专门来处理http请求和响应。
Web.xml文件:
当我们编写好servlet之后,如何让tomcat知道,这个java类是和某个请求路径对应的呢,就是通过web.xml配置文件。
servlet-name用于指定servlet名字,在同一个web程序中,每一个servlet的名字必须是唯一的,该元素的内容不能为空。servlet-class用于指定servlet类的完全限定名;servlet-mapping节点用于在servlet于url之间定义一个映射,这里面的servlet-name的值必须与上面的一致,url-pttern用于指定对应的url路径。
配置例子:
<servlet>
<servlet-name>myfirst</servlet-name> 指定servlet的逻辑名
<servlet-class>HelloServlet</servlet-class>
对应的类名(完全限定名)不要忘了包名
</servlet>
<servlet-mapping>
<servlet-name>myfirst</servlet-name> 逻辑名 与上面的一致
<url-pattern>/helloServlet</url-pattern>
指定客户端在地址栏里面输入什么能访问到这个servlet(斜杠表示从项目名开始)
</servlet-mapping>
Servlet生命周期不同阶段调用的不同方法
Servlet运行在Servlet容器中,其生命周期由容器(如:Tomcat)来管理。Servlet的生命周期通过javax.servlet.Servlet接口中的init( )、service( )、destroy( )等方法来完成。
init(ServletConfig config):初始化Servlet对象,容器在创建好Servlet对象后就调用
service(ServletRequest req,ServletResponse res):响应客户请求,当容器接收到客户端要求访问特定的Servlet对象时就会调用
destroy():释放Servlet对象占用的资源,当servlet对象结束生命周期时,容器就会调用(服务器重启或者web项目重新加载时调用)
getServletConfig():返回ServletConfig对象,,在该对象中包含了servlet初始化信息
getServletInf():
Servlet的生命周期包含了四个阶段:
实例化阶段—创建servlet类的对象
初始化阶段—对象调用初始化方法
服务阶段--调用service()方法,根据提交方式调用doget或dopost方法
销毁阶段--调用destroy()方法销毁
在这几个生命周期中会分别调用servlet的不同方法,其中实例化阶段调用servlet的缺省构造函数,创建servlet对象后,会立即调用init()方法,根据请求,调用service方法。
通过下图进一步理解Servlet的生命周期:
当客户端一个请求到来时,tomcat首先根据请求的URL得到相应的servlet,然后调用该servlet的service()方法,并根据是get还是post请求调用doget和dopost方法,这两个方法的输出作为响应内容发送给客户端。当我们要关闭tomcat时,tomcat在退出前,还要负责释放servlet所释放的资源。
通过程序验证四个阶段的执行特点
Servlet中获取数据
通过请求参数request来获取的,可以通过HttpServletRequest中的方法来获取数据。
String getParameter(String name) 根据页面表单组件名称获取页面提交数据
String[] getParameterValues(String name) 获取表单中多值控件提交的信息 ,参数为控件名称。如复选框中的值
Servlet中实现输出html页面
需要通过参数response来作出响应,可以通过HttpServletResponse中的方法来实现。
PrintWriter getWriter( ) 返回PrintWriter对象 PrintWriter可以向客户端输出字符。
通常我们习惯给这个类型的对象起名叫做out。
Servlet中代码实现
PrintWriter out=response.getWriter();
out.println("用户名:"+name+"<br>");
out.println("密码:"+pwd+"<br>");
解决乱码问题
设置提交信息的字符编码,通过HttpServletRequest中的方法来实现:
,参数为”utf-8”时,设置提交字符编码为支持中文。
例:request.setCharacterEncoding("utf-8");
设置响应信息的字符编码,HttpServletResponse中的方法来实现:
例:response.setContentType("text/html; charset=UTF-8");
或
response.setCharacterEncoding("utf-8");
请求转发
请求转发就是指将用户的请求转发给另外一个Servlet或页面,然后由它们进行处理并产生对请求的响应。
HttpServletRequest中具有方法getRequestDispatcher,这个方法是ServletRequest中的方法,方法的返回值是RequestDispatcher类型的对象。
public RequestDispatcher getRequestDispatcher (java.lang.String path)
在Servlet中,利用RequestDispatcher对象,可以将请求转发给另外一个Servlet或JSP页面,甚至是HTML页面,来处理对请求的响应。
RequestDispatcher对象具有的public void forward(ServletRequest request, ServletResponse response)
这个方法能够实现将请求转发给另外的页面。
request.getRequestDispatcher("success.html").forward(request, response);
HttpServletRequest对象的生命周期:从一个请求开始,到这个请求处理结束。而且只要刷新页面,request也将失效。
请求转发的特点:
请求转发后,不会产生新的请求,会继续沿用原来的请求
请求转发后,地址栏显示的是原页面的URL
请求转发时用到的接口RequestDispatcher,在这个接口中定义了两个方法:
1)forward(ServletRequest request,ServletResponse response)
必须在响应提交给用户之前调用。
2)include(ServletRequest request,ServletResponse response)
3)区别:include()将请求转发给其他的Servlet,被调用的Servlet对该请求做出的响应将并入原先的响应对象中,原先的Servlet还可以继续输出响应信息。
forward():将请求转发给其他的Servlet,将由被调用的Servlet负责对请求做出响应,而原先Servlet的执行则终止。
重定向
重定向就是指将用户的请求重定向给另外一个Servlet或页面,然后由它们进行处理并产生对请求的响应。
HttpServletResponse 类的public void sendRedirect(java.lang.String location)
能够实现重定向的页面跳转。但是与请求转发的原理不一样。
Response.sendRedirect(“success”);
重定向的特点:
重定向后,会产生一个新的请求
重定向后,地址栏显示的是目标页面的URL
请求转发和重定向的区别
2种跳转完成同样的功能,但是区别非常大:
在地址栏中,用重定向跳转后地址栏会显示目标页面。请求转发地址栏显示源页面
区别在于请求的次数:请求转发 请求没变;重定向 会产生新的请求
request.getRequestDispatch(“T2.jsp”).forward(request,response);相当于将本次的请求和响应转发给你
请求转发不能跳转到其他项目中,只能在本项目内跳转,重定向可以跳转到其他项目中
HTTP协议的特点
HTTP协议是无状态的协议,发送的请求不记录用户的状态,不记录用户的信息。就相当于它被访问了2次,不知道是哪两人访问的,或者是一个人访问两次。
正是因为HTTP协议的这一特点,用户的活动发生在多个请求和响应之中,作为web服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态。比如说我们平时上的qq.可以设置登录状态,记住密码,之后我们在一段时间内就可以不用输入密码直接输入,那么Http协议是无状态的,我们怎么可以让他记住我们的状态呢,就是通过会话跟踪技术
什么是会话:
就像我和一个人之间的对话
会话跟踪技术有哪几种?
Cookie Session 隐藏表单域(hidden) URL重写
什么是Cookie:
Cookie的中文意思是点心的意思
Cookie是保存到客户端的一个文本文件,与特定客户相关。
Cookie是一种由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,cookie存活在本地,
在客户随后对该服务器的请求中发回它。
Cookie以“键-值”对的形式记录会话跟踪的内容,服务器利用响应报头set-cookie来发送cookie信息。
创建cookie
创建Cookie:new Cookie(name,value)
可以使用Cookie 的setXXX方法来设定一些相应的值
setName(String name)/getName()
setValue(String value)/getValue()
setMaxAge(int age)/getMaxAge()
利用HttpServletResponse的addCookie(Cookie)方法将它设置到客户端
利用HttpServletRequest的getCookies()方法来读取客户端的所有Cookie,返回一个Cookie数组
cookie的分类
Cookie分两种 放在内存中 一旦浏览器关闭 就消失了
Cookie c1=new Cookie("","");
response.addCookie(c1);
一种是属于文本 有生命周期的
可以通过serMaxAge(600);这个方法设置 毫秒为单位 表示这个cookie的有效时间
保存到硬盘上的cookie可以在多个浏览器之间共享,也就是说,两个浏览器在访问同一个url时,使用的是同一个cookie信息。
cookie的缺点
Cookie对用户是透明的,并且保存在磁盘上,持久性高,可以长时间的跟踪用户,了解用户上网的习惯,并且保存用户的名和密码等敏感信息有很大的安全隐患,而用户在网上的一举一动,就有可能成为某些网站的赚钱机会,这就会造成一些隐私权和安全性方法的问题。
而且我们也可以在浏览器中禁用cookie,就可以阻止所有的cookie,那么只要跟cookie相关的操作就失效了
cookie的应用1
设置cookie
Cookie cookie = new Cookie("Session-Cookie-" + i, "Cookie-Value-S" + i);
response.addCookie(cookie);
// 设置cookie的有效时间 单位为毫秒
cookie.setMaxAge(600);
response.addCookie(cookie);
}
读取客户端的Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
Cookie cookie;
for(int i=0; i<cookies.length; i++) {
cookie = cookies[i];
out.println("<TR>\n" +
" <TD>" + cookie.getName() + "</TD>\n" +
" <TD>" + cookie.getValue() + "</TD></TR>\n" );
}
}
out.println("</TABLE></BODY></HTML>");
}
}
session
客户端可以阻止服务器写入cookie 所以说cookie不太可靠 另外也不安全
更安全的是基于session的HttpSession对象
服务器为每个会话创建一个HttpSession对象
– 每个会话对象都有一个唯一的ID
– 把用户的数据保存在相应的HttpSession对象内
原理:
用户第一次发送请求的时候,服务器创建一个HttpSession对象,并把该对象的id返回给用户,同时服务器在内存中开辟一空间,用来保存该对象数据,服务器将此id发送回客户端做出响应;用户第二次发送请求的时候把id一起发送给服务器,服务器根据id号寻找相应的数据。
创建和使用session
会话的创建
使用HttpServletRequest 的 getSession() 方法创建会话,
获取session对象
两个方法:getSession();(=getSession(true);) getSession(boolean b);,
HttpSession session = request.getSession(true);
true: 返回与当前关联的会话,如果没有就创建后将其返回
false: 返回与当前关联的会话,如果没有返回null
使用session
session.setAttribute(String param,Object value);存值
session. getAttribute(String param);取值
session的生命周期
session的创建
浏览器访问服务器时,服务器为每个浏览器创建不同的session对象
session的关闭
调用session. invalidate()方法,使session对象失效(安全退出)
访问时间间隔大于非活动时间间隔, session对象失效
关闭浏览器时,session对象失效(也相当于第二种现象)
可以设置session的有效时间,服务器默认30分钟。
一般点击退出的时候,会调用invalidate()这个方法
生命周期总结:从一个客户端打开浏览器并连接到服务器开始,到客户端关闭浏览器离开这个服务器为止,或调用方法主动卸载session对象,或session对象存在时间超时后被自动卸载,在这期间被称为一个会话 。
每个客户端拥有自己独立的session对象
session与cookie的区别
1.cookie会把信息记录在客户端 就是本地
Session会记录在服务器端,服务器端创建sessionid后,需要把sessionid保存在客户端,就是保存到cookie中,可以采用cookie或url重写的方式保存。
如果cookie被禁用了,cookie不好用,session就会不好用
2.保存sessionid的cookie在关闭浏览器后就删除了,不能在多个浏览器中共享。而普通的cookie在关闭浏览器后再次打开时,仍然存在,可以在多个浏览器进程间共享。
解释: 通常将用于会话跟踪的cookie叫做会话cookie,在servlet规范中,用于会话跟踪的cookie名字必须为JSESSIONID,通常保存在浏览器的内存中。所以在内存中得cookie不能被不同的浏览器共享。对于保存在磁盘中得cookie,因为是在外部的存储设备存储,所以可以再多个浏览器进程中共享。
3.cookie只能写文本 有长度限制 4096字节 session没有限制
误区:很多人认为“浏览器一旦关闭,session就消失了”,是错误的!
主要是因为保存sessionid的cookie是存储在浏览器内存中,一旦浏览器关闭,cookie将被删除,sessioinid也丢失了。再次打开时,没办法找到之前的sessionid,所以肯定会创建一个新的session了。而这个时候先前的session是仍然存在的,直到session失效,才会被服务器消除。
比如:顾客在超市购物存包,购物完毕,忘了取包就走了,但存包处的人不知道顾客走了,所以必须让柜子继续使用存放原来顾客的东西,直到长时间没人来取,工作人员才会消除柜子。
URL重写
这种使用session保存用户信息的方式,我们是通过在客户端浏览器中保存了一个sessionid(其实就是cookie原理)来实现会话跟踪,现在我们在浏览器中禁用cookie,看看还能正常运行么?
设置完后,登录后,还提示没登陆!
访问TestServlet时,发现每次刷新都是1,都是新的sessionid。
这都是因为禁用了cookie,服务器无法从客户端获取sessionid了,那每次请求都会创建一个新的session。
这样,当用户禁用cookie后,session机制也失效了,自然无法实现跟踪了,我们需要使用URL重写机制对用户会话跟踪。
将URL传给response.encodeURL处理。
l 如果服务器使用cookie, 它原封不动地返回URL。
l 如果服务器使用URL重写,它将会话信息附加到URL上。
l 例如:
String url = "order-page.html";
url = response.encodeURL(url);
l 将URL传递给response.encodeRedirectURL(url)
当Cookie禁用 还想用Session时 可以通过URL重写实现会话跟踪
JSP
什么是jsp?
JSP(Java Server Pages)是指:
在HTML中嵌入Java脚本代码
由应用服务器中的JSP引擎来编译和执行嵌入的Java脚本代码
然后将生成的整个页面信息返回给客户端
Jsp和html的区别:jsp动态网页,可以传递数据html:静态网页,获取不到数据
JSP执行过程
web容器处理JSP文件请求需要经过3个阶段:
? 翻译阶段:JSP文件会被Web容器中的JSP引擎转换成Java源码
? 编译阶段:Java源码会被编译成可执行的字节码
? 执行阶段:容器接受了客户端的请求后,执行编译成字节码的JSP文件;处理完请求后,容器把生成的页面反馈给客户端进行显示
JSP与Servlet的关系
? JSP技术是出现在Servlet之后,由于servlet输出HTML标签太麻烦,为了方便程序员编写动态网页,sun公司对servlet做了一些改进,对于网页中不会变化的部分,还是用HTML代码来书写,而对于需要根据请求动态生成的内容,才使用java程序来书写。这就是JSP技术,实际JSP是serlvet的衍生,JSP本质还是serlvet,Servlet是JSP技术的基础。
? JSP与Servlet的技术是相同的,表面上看jsp类似html,servlet类似java类。Jsp是往html里面插入java代码,servlet是往java中插入html标签。
? 页面中java的多,就用servlet,如果静态html的多,就用jsp,一般一个项目中jsp和servlet搭配使用
JSP的页面组成
? 一个JSP页面由元素和模板数据组成。一个JSP页面中可以包括HTML静态文本、指 令、表达式、小脚本、声明、标准动作、注释等内容。
? 一个JSP页面:
? <%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=GBK" pageEncoding="GBK"%> 指令
? <html>
? <head>
? <title>输出当前日期</title> 静态内容
? </head>
? <!-- 这是HTML注释(客户端可以看到源代码)--> 注释
? <%-- 这是JSP注释 (客户端不可以看到源代码) --%>
? <body>
? <%
? Int a=10;
? %>
? 表达式
? </body>
? </html>
指令元素
? 指令元素主要用于为转换阶段提供整个JSP页面的相关信息,指令不会产生任何的输出。JSP中的指令元素有page指令、include指令、taglib指令。
?
page指令,通过设置内部的多个属性来定义整个页面的属性。
语法:<%@ page 属性1="属性值" 属性2="属性值1,属性值2"… 属性n="属性值n"%>
page指令常用属性
<%@ page language="java" import="java.util.*" contentType="text/html; charset=gb2312" pageEncoding="ISO-8859-1" extends = "" session ="true|false" buffer = "none|sizekb"
autoFlush="true|false" isThreadSafe="true|safe" info="info_text" errorPage = "error_url" isErrorPage = "true|false"
isELIgnored = "true|false" deferredSyntaxAllowedAsLiteral= "true|false" trimDirectiveWhitespaces = "true|false"
%>
指令元素之include指令
include指令用于在JSP页面中静态包含一个文件,该文件可以是JSP页面、HTML网页、文本文件或一段Java代码。使用了include指令的JSP页面在转换时,JSP容器会在其中插入所包含文件的文本或代码。
语法:<%@ include file="file URL"%>
file URL写相对于当前JSP页面的URL。
可以将一些共性的内容写入一个单独的文件中,然后通过include指令引用该文件,从而降低代码的冗余问题,也便于修改共性内容。
例子:想用代码实现访问控制,没登录不允许看到主页,这个功能就可以使用include指令来简化。
? 创建登录验证文件 checklogin.jsp
<%@ page import="s2jsp.sg.ch07.User"%>
<%
User user = (User) session.getAttribute("LOGINED_USER");
if (user == null) {
response.sendRedirect(“login.html");
}
%>
? 在后台首页面(index.jsp)中使用include指令引用登录验证文件
<%@ include file="checklogin.jsp"%>
指令元素之taglib指令
taglib指令允许页面使用用户定制的标签。用来引入标签库。
语法:
<%@ taglib uri="URIToTagLibrary" prefix="tagPrefix" %>
其中uri属性用来指定标签库的存放位置,prefix属性用来指定该标签库使用的前缀。
JSP脚本及动作元素
JSP脚本元素
JSP 脚本元素是用来嵌入Java代码的,主要用来实现页面的动态请求
JSP 脚本元素包括:
小脚本 表达式 声明
JSP 脚本元素之表达式
表达式是对数据的表示,系统将其作为一个值进行计算和显示
语法:<% = Java表达式/变量 %>
注意:在书写表达式的时候,一定不要在表达式后面添加任何的标点符号。
例子:
<html>
<body>
<%=30*20%>
</body>
</html>
使用表达式显示数据。显然,表达式更有利于在HTML中显示数据。
使用小脚本也可以显示数据
<html>
<%
out.println(30*20);
%>
</html>
JSP 脚本元素之声明
声明脚本元素用于声明在JSP页面的脚本中使用的变量和方法。声明必须是完整的声明语句,遵循Java语言的语法。
语法: < % ! Java 代码 %>
JSP动作元素
动作元素为请求处理阶段提供信息。JSP2.0规范中定义了20个标准动作元素。
<jsp:userBean>
<jsp:setProperty>
<jsp:getProperty>
<jsp:param>
<jsp:include= “url” flush = “true|false”>
<jsp:forward>
<jsp:plugin>
<jsp:params>
<jsp:fallback>
<jsp:element>
<jsp:attribute>
<jsp:forward>
<jsp:body>
<jsp:text>
<jsp:output>
<jsp:invoke>
<jsp:doBody>
<jsp:root>
<jsp:declaration>
<jsp:scriptlet>
动作元素之访问JavaBean
<jsp:userBean>
<jsp:setProperty>
<jsp:getProperty>
动作元素之param
<jsp:param>
动作元素之include
<jsp:include= “url” flush = “true|false”>
静态include和动态include的区别
include指令是编译阶段的指令,即include所包含的文件的内容是编译的时候插入到JSP文件中,JSP引擎在判断JSP页面未被修改,否则视为已被修改。由于被包含的文件是在编译时才插入的,因此如果只修改了include文件内容,而没有对JSP修改,得到的结构将不会改变,所以直接执行已经存在的字节码文件,而没有重新编译。因此对不经常变化的内容,用include指令是合适的,如果需要的内容是经常变化的,则需要动作元素<jsp:include>.
(15)include指令
include可以在JSP页面转换成Servlet之前,将JSP代码插入其中。它的主要优点是功能强大,所包含的代码可以含有总体上影响主页面的JSP构造,比如属性、方法的定义和文档类型的设定。它的缺点是难于维护只要被包含的页面发生更改,就得更改主页面,这是因为主页面不会自动地查看被包含的页面是否发生更改。
语法:<%@ include file="sample.jsp" %>
2.include动作
jsp:include动作是在主页面被请求时,将次级页面的输出包含进来。尽管被包含的页面的输出中不能含有JSP,但这些页面可以是其他资源所产生的 结果。服务器按照正常的方式对指向被包含资源的URL进行解释,因而这个URL可以是Servlet或JSP页面。服务器以通常的方式运行被包含的页面, 将产生的输出放到主页面中,这种方式与RequestDispatcher类的include方法一致。它的优点是在被包含的页面发生更改时,无须对主页 面做出修改。它的缺点是所包含的是次级页面的输出,而非次级页面的实际代码,所以在被包含的页面中不能使用任何有可能在整体上影响主页面的JSP构造。
语法: <jsp:include page="sample.jsp" flush="true"> <jsp:param
name="name" value="value"/> </jsp:include>
其中参数设置可以没有,如果没有参数设置,则必须采用<jsp:include page="sample.jsp" flush="true"/>形式。
<%@include%>和<jsp:include>的区别
例题:有以下四个文件:a.jsp、c.jsp、abc/b.jsp、abc/c.jsp
动作元素之forward
<jsp:forward>
动作元素之
<jsp:plugin>
<jsp:params>
<jsp:fallback>
JSP注释
合理、详细的注释有利于代码后期的维护和阅读
在JSP文件的编写过程中,共有三种注释方法:
HTML的注释:<!-- html注释-->
JSP注释:<%-- JSP注释--%>
在JSP脚本中注释:
<% //单行注释 %>
<% /*多行注释 */ %>
JSP隐含对象及作用范围
JSP 内置对象是 Web 容器创建的一组对象,是可以直接在JSP页面使用的对象 ,无需使用“new”获取实例,JSP 内置对象的名称是 JSP 的保留字。
在JSP中共有九个隐含对象,分别是:request、response、application、session、out、PageContext、page、config、exception。
隐含对象之request
request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。
该对象封装了用户提交的信息,通过调用该对象相应的方法可以获取封装的信息,即使用该对象可以获取用户提交信息。
常用方法:
隐含对象之response
response表示HttpServletResponse对象,并提供了几个用于设置送回 浏览器的响应的方法(如cookies,头信息等)
对客户的请求做出动态的响应,向客户端发送数据。
常用方法:
隐含对象之out
out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。
Out对象是一个输出流,用来向客户端输出数据。Out对象用于各种数据的输出。
常用方法:
(1)out.print():输出各种类型数据。
(2)out.newLine():输出一个换行符。
(3)out.close():关闭流。
隐含对象之pageContext
pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。
隐含对象之session
session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存储用户的状态信息 。
常用方法:
隐含对象之application
applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息 。
服务器启动后就产生了这个application对象,当客户再所访问的网站的各个页面之间浏览时,这个application对象都是同一个,直到服务器关闭。但是与session不同的是,所有客户的application对象都是同一个,即所有客户共享这个内置的application对象。
常用方法:
隐含对象之config
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。
隐含对象之page
page表示从该页面产生的一个servlet实例
隐含对象之exception
exception:表示一个异常
JSP中的作用范围
JSP中一共有四个作用范围
1) request:
2) page:
3) session:
4) application:
通用方法:
1、向作用范围内添加一个对象:void setAttribute(String key,Object obj);
2、从作用范围内取得一个对象:Object getAttribute(String key);
3、从作用范围内删除一个对象:void removeAttribute(String key);
作用范围之request
request是请求级别
有效范围为:从一个请求开始,到这个请求处理结束。而且只要刷新页面,request也将失效。
作用范围之page
page是页面级别
有效范围为:当前jsp页面,离开本页面page范围就会失效。
如果把变量放到pageContext里,就说明它的作用范围是page。
作用范围之session
session是会话级别
有效范围为:当前会话 。从打开浏览器 向服务器发送一个请求开始,到关闭浏览器 (或卸载session、或session超时)为止。
作用范围之application
application是服务器级别
有效范围为:当前应用程序。从服务器启动,到服务器关闭
四种作用范围的对比
request 临时用的数据,请求之后就不用了
session 与用户有关的
application 大家都需要访问的
EL表达式
EL表达式语法
EL 存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。因为我们并没有指定哪一个范围的username,所以它的默认值会先从Page 范围找,假如找不到,再依序到Request、Session、Application范围。假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。
自动所搜范围如下:
Page-------------PageScope
Request---------RequestScope
Session----------SessionScope
Application-----ApplicationScope
指定搜索范围如下标准写法
${ PageScope .username}:取出page范围的username的变量
${ RequestScope }:取出request范围的username的变量
${ SessionScope }:取出session范围的username的变量
${ ApplicationScope }:取出application范围的username的变量
表达式语言
${sessionScope.user.name}等同于${sessionScope.user["name"]}
两种方式比较:
(1) 当要存取的属性名称中包含一些特殊字符,如 . 或 – 等并非字母或数字的符号,就一定要使用 [ ],例如:
${user.My-Name } 上述是不正确的方式,应当改为:${user["My-Name"] }
(2) 我们来考虑下列情况:
${sessionScope.user[data]}。此时,data 是一个变量,假若data的值为"sex"时,那上述的例子等于${sessionScope.user.sex};假若data 的值为"name"时,它就等于${sessionScope.user.name}。因此,如果要动态取值时,就可以用上述的方法来做,但 . 无法做到动态取值。
算术操作符
在EL中,有5个算术操作符。
+ :${23+5}
— :${23-5}
* :${23*5}
/(或div) :${23/5}或${23 div 5}
%(或mod) :${23%5}或${23 mod 5}
关系操作符
= = (或eq) :${23 = = 5}或${23 eq 5}
!=(或 ne) :${23 != 5}或${23 ne 5}
<(或It) :${23<5}或${23 It 5}
>(或gt) :${23>5}或${23gt 5}
<=(或le) :${23<=5}或${23 le 5}
>=(或ge) :${23>=5}或${23 ge 5}
逻辑操作符
&& :同java
|| :同java
! :同java
Empty操作符
是一个前缀操作符,用于检测一个值是否为null或者为empty。例如:变量A不存在,则${empty A}返回的结果为true。
条件操作符
“?:” 例:${A?B:C}
操作符的优先级
EL中操作符的优先级如下所示,从高到低,从左到右。
[ ] .
( )
- (负)、not、!、empty
*、/、div、%、mod
+、- (减)
<、>、<=、>=、lt、gt、le、ge
= =、!=、eq、ne
&&、and
||、or
${ A ? B : C}
EL中的隐含对象
EL中定义了11个隐含对象。
1. 与范围有关的隐含对象
applicationScope
sessionScope
requestScope
pageScope
2. 与输入有关的隐含对象
param
paramValues
3. 其他隐含对象
cookie
header
headerValues
initParam
pageContext
EL保留关键字
JSTL简介
JSTL的目标是为了简化JSP页面的设计。JSTL是由5个不同功能的标签库所组成。
配置JSTL
使用JSTL,需要导入2个jar包到项目中,分别是jstl.jar和standard.jar。