u HTTP协议原理 (掌握HTTP遵循请求/响应模型,HTTP是无状态的协议,端口号为80)
u HTTP协议处理流程
1、客户端和Web服务器建立连接
2、客户端发送HTTP请求
3、服务器生成HTTP响应回发
4、关闭连接
u HTTP协议请求和响应信息格式
请求信息:
分为请求行、请求头、空行、消息体(POST)
响应信息:
u WEB服务器缺陷:
只能发送静态页面。解决方法是增加辅助应用,CGI是WEB服务器和外部应用通讯的标准。可使用多种语言开发。但每次请求开启进程,极大消耗服务器资源,JAVA使用WEB容器加servlet解决辅助应用。每次请求开启线程,所有线程共享WEB容器所在的进程
u WEB容器作用
Web容器负责管理和运行Servlet
容器对Servlet的支持包括
1、 通信支持
2、 servlet生命周期管理
3、 多线程支持
4、 JSP支持
5、 处理安全性
WEB-INF里面的内容是不能被客户端直接访问。一般用于存放一些比较隐密的信息
u Tomcat目录结构(
bin目录(tomcat启动和关闭目录)
conf(tomcat配置目录)
webapps(web 应用程序放置目录)
work(主要用作JSP翻译和编译目录)
)
--------------------------------------------------------------------------------------------
u Servlet类结构
按照sun公司的规范,每个servlet类都必须实现servlet接口。其中service()方法是提供给用户实现的业务方法。GenericServlet对servlet和servletConfig(用于servlet配置的接口)作了简单实现,但没有实现service方法。该方法用它的子类根据自己不同协议的特点进行实现。HttpServlet是GenericServlet的子类。专门针对Http协议实现了service()方法。针对不同的请求类型调用doXX()方法。所以我们在书写servlet类的时候,一般只需要继承HttpServlet,并重写doXX()方法就行了。
u Servlet的编码和部署
public classTestServlet extends HttpServlet {
public void doGet(HttpServletRequestrequest,HttpServletResponse response) throws IOException,ServletException{
}
servlet只有在web容器 注册之后,才能被容器所识别
Servlet3标准中可以使用@webServlet(urlpatterns="/test")注册
u Servlet URL映射路径
1、精确匹配 /abc 以abc请求可以找到该servlet
2、扩展匹配 *.do 以.do结尾请求都可找到该servlet
3、路径匹配 /abc/* 以/abc/目录请求都可找到该servlet
u 加上斜杠后,回到webapps根目录,这时,请求路径必须加入布署名
// 在当前目录下查找
u Servlet生命周期
1、容器启动,会读取conf/server.xml文件,以确定启动端口和WEB应用存放的路径
2、WEB容器启动会读取每个WEB应用的web.xml文件配置信息,并解析web.xml文件。得到servlet配置信息。
3、 容器加载并实例化Servlet
(web.xml文件配置servlet时有个
4、 容器调用init()方法初始化
5、 每次请求调用service()方法完成逻辑
6、 容器丢弃servlet调用destroy()方法
其中1、2、3、4、6只执行一行,只有5是每次请求都会执行。而且在整个生命周期中,servlet 对象只有一个,单实例多线程。
u Servlet的配置对象:ServletConfig 可以读取
u Servlet全局对象:ServletContext 作用于整个WEB应用
作用:1、可使用getRealPath()获得资源真实路径
2、可使用getAttribute()、和setAttribute()方法共享全局变量。
3、可以读取
---------------------------------------------------------------------------------------------------------
u HTTP状态码
HTTP状态码:
100-199:表示信息性代码,标示客户端应该采取的其他动作,请求正在进行。
200-299:表示客户请求成功。
300-399:表示用于已经移走的资源文件,指示新的地址。
400-499:表示由客户端引发的错误。
500-599:表示由服务器端引发的错误。
设置状态码sendError(code,”Resource Not Found”);
按照响应信息的格式,先有状态行,再有消息体,所以注意在使用PrintWriter向客户端输出信息之前,设置状态码
u 设置HTTP响应头
目的用于告诉客户端
发送回来的内容的类型
有多少内容被正被发送
发送内容的服务器的类型
设置响应头的方法:setHeader()或setHeaders()。注意:设置响应头只能是HTTP协议。所以setHeader和setHeaders()都是HttpServletResponse中的方法
u 设置HTTP消息体
response.getWriter()获得打印字符流,可以输出文本
response.getOutputStream()获得输出字节流,可以发送二进制数据。
u 重定向原理
重定向调用方法response.sendRedirect("http://127.0.0.1:8080/lovobook/bar.html");
1,浏览器向服务器发送HTTP请求。
2,服务器接收到请求后,如果调用response.sendRedirect()方法,表示资源已被移走。则发送一个302的状态码和location的响应头。在location响应头指明要转发的地址。
3,浏览器在接收到302状态码后,会读取location响应头的内容,并将地址栏的值赋为location响应头的内容。从而再向服务器发出第二次请求。由于是二次请求,所以重定向不能获得封装在request中的属性信息
------------------------------------------------------------------
u 为什么要进行状态管理
HTTP协议使用的是无状态的连接
对容器而言,每一个请求都来自于一个新的客户
解决方案:
1、 隐藏表单域
2、 Cookie
3、 Session
4、 URL重写
u Cookie
客户端向服务器发出请求,服务器接收请求之后,如果调用response.addCookie()方法。则服务器向客户端发送set-cookie响应头,从而将文本信息放置在客户端的Cookie中。当客户端再次向服务器发送请求时,则又会将Cookie的内容以Cookie请求头的方式发送给服务器,服务器可根据Cookie的内容判断是否是同一客户发出的请求。
Cookie由于放置在客户端,并以文本形式发送,所以容易超成一些[张安浩1] 隐私问题。Cookie分两种,一种放在客户端浏览器缓存中,一种放在客户端的文件中。
u Session
Session是放置在服务器端的一个对象。用于保存客户端用户信息。
Session工作原理:
先由客户端向服务器发出一个请求,服务器在接收到这个请求的时候就给客户端分配一个session对象同时给这个session分配唯一的标识JSessionID,当完成这一过程的时候就把这个id和session对象保存在一个map集合中,并把这个session的id以cookie方式发给客户端。当客户端再次发送请求的时候,就会把这个session的id以请求头的方式发送给服务器,然后服务器通过这个session的id从Map集合中找到相应的session对象。
Session和cookie区别:
1、session的数据是放置在服务器端,而cookie信息放在客户端。
2、Session是服务器端的一个对象,封装的数据是对象。而cookie的数据是文本。
Session 对象的获取:
获取session是通过request.getsession(boolean)方法。参数为真如果没有会话对象则创建一个会话对象,如果有会话对象则直接返回,但是为false的话,表示的是如果有会话对象就直接返回,如果没有回话对象就返回null。值得注意的是没有参数的时候和getsession(true)是一样的效果。
Session生命周期:
在一个会话范围内。产生Session对象时,该对象就和客户端浏览器进行绑定,只要不关闭浏览器,在超时时间内该session都会有效。关闭浏览器,重开一个浏览器,则服务器会分配置新的Session对象。
由于Session是放置在服务器端的对象。所以当客户端关闭浏览器,并不意味着Session对象的销毁。所以到一定时间,一定要对Session对象进行销毁,以释放服务器内存资源。
·销毁会话的几种方式:
1、设置会话的超时时间
setMaxInactiveInterval(int)对于对话指定客户请求的最大间隔时间,以秒为单位,
在web.xml中配置
值得注意的是这里的15是分钟
2、调用session的invalidate()方法
3、应用程序结束,或服务器崩溃
u URL重写
由于Cookie存在不安全的因素,会使得一些客户端禁用掉Cookie。因为Session(主要是指Session的ID)也是用Cookie方式传递的,当用户禁用Cookie后,SessionID就不能到达服务器。从而服务器也不能维持和客户端的状态。这时可以用URL重写的方式将会话的ID强加在的每一个URL地址末尾,从而保证在该问服务器时,能将SessionID发送给服务器。
调用response对象的encodeURL()方法编译URL,将 sessionID附加在URL后面。
------------------------------------------------------------------------
作用域对象 |
属性操作方法 |
作用域范围说明 |
ServletContext(上下文) |
void setAttribute(String, Object) Object getAttribute(Sting) void removeAttribute(String) Enumeration getAttributeNames() |
整个Web应用程序 |
HttpSession(会话) |
一个会话交互过程 |
|
ServletRequest(请求) |
一次请求过程 |
监听器概述
1、监听session,request,servletContext这三个对象里存取数据的变化
2、监听器对象可以在事情发生前、发生后可以做一些必要的处理
3、Servlet监听器主要目的是给Web应用增加事件处理机制,以便更好地监视和控制Web应用的状态变化
监听器实现步骤:
1、 确定事件源。事件源:servletContext,session,request
2、 确定监听者。监听器必须实现监听器接口,并在监听器接口中实现逻辑方法
3、 注册
监听器只有注册之后,才能被容器所识别。
com.lovobook.MyServletContextListener
Servlet3标准中可以使用@WebListener注册
监听器类型
1、ServletContextListener:用于监听ServletContext对象创建和销毁的事件。
void contextInitialized(ServletContextEventsce) ——上下文对象创建时,触发
void contextDestroyed(ServletContextEventsce) ——上下文对象销毁时触发
2、HttpSessionListener接口:监听HttpSession的创建和销毁。
sessionCreated(HttpSessionEvent se)方法——创建HttpSession触发。
sessionDestroyed (HttpSessionEvent se)——销毁HttpSession触发
3、HttpSessionBindingListener :唯一不需要注册的接口
当一个类实现了HttpSessionBindingListener接口后,只要对象加入Session范围(即调用HttpSession对象的setAttribute方法的时候)或从Session范围中移出(即调用HttpSession对象的removeAttribute方法的时候或Session Time out的时候)时,容器分别会自动调用下列两个方法:
valueBound(HttpSessionBindingEvent event)——绑定到session时触发
valueUnbound(HttpSessionBindingEvent event)——移除session时触发
-------------------------------------------------------------------------
u 过滤器概念
过滤器是一个中间组件,用于拦截源数据和目的数据之间的消息
过滤二者之间传递的数据
u 过滤器实现步骤:
1、书写过滤器类
过滤器类都必须实现javax.servlet.Filter接口
public classHelloWorldFilter implements Filter {
private FilterConfig filterConfig;
publicvoid init(FilterConfig filterConfig) {//初始化方法
this.filterConfig = filterConfig;
}
publicvoid doFilter(
ServletRequest request, ServletResponseresponse,//请求和响应均不是基于Http协议的
FilterChain filterChain //将请求继续向后面的过滤器或目标资源发送
) throws ServletException, IOException {//业务方法,书写过滤内容
PrintWriter pw = response.getWriter();
……
filterChain.doFilter(request,response);
}
publicvoid destroy() {//销毁方法
}
}
在调用filterChain.doFilter方法后,将请求继续向目标资源发送。这时,也不能再做重定向和内部转发,否则抛出异常
2、完成过滤器在容器中的注册
在Servlet3标准中,可以使用@webFilter(urlpattern="/test")注册
u 过滤器类型
u 过滤器链
用多个过滤器处理在同一个请求
l 使用多个
l 首先调用匹配请求URI的过滤器
l 再查找用Servlet名匹配请求URI的所有过滤器
l 过滤器的执行顺序按照它们在部署描述文件中出现的顺序排序
-----------------------------------------------------------------------------------------------------
u Servlet的缺陷
– Servlet的编码、部署和调试任务繁琐
– 生成动态网页繁琐,不利于项目分工
u JSP是为了解决servlet缺陷而产生的。让我们编写输出内容时,可以象普通网页一样编写。
u JSP生命周期
1、Web容器第一次接收到对某个JSP页面的请求后,首先自动将该JSP页面翻译为java代码 。
Tomcat将翻译后的代码放在Tomcat安装目录的/work子目录下
Tomcat的/conf子目录下 有以下描述
. . . . . .
2、Web容器负责将Servlet代码编译为字节码。与源文件放在同一个目录下,在JSP生命周期中,整个翻译和编译步骤只发生一次
3、Web容器装载新生成的servlet类
4、第一次请求到达时,Web容器创建servlet实例对象。整个生命中,只有一个对象
5、Web容器调用Servlet示例的jspInit()方法,JSP页面装载资源
6、每次请求到达都执行_jspService()方法,输出内容
7、容器调用生成的servlet对象的jspDestroy()方法,销毁装载的资源
u 按JSP规范所有JSP类都必须实现HttpJspPage接口,而这个接口是servlet子接口,所以JSP本质是servlet
u JSP是servlet类,所以可以在JSP中书写JAVA代码,但不要嵌入过多的JAVA代码,增加阅读和维护难度。JSP重在显示,而Servlet重在逻辑实现。
JSP隐式对象
在翻译好的类中,在_jspService()中有九个局部变量,并都做了初始化。由于我们在JSP中书写的内容都是丰富_jspService()方法,所以可以直接使用这些局部变量,这就是隐式对象
四个作用域:
pageContext:作用于页面
request:作用于请求
session:作用于会话
application:作用于全局(类型是ServletContext)
二个输出:
response:响应对象
out:打印字符流,类型为JspWriter
一个配置对象
config:类型为ServletConfig
一个当前对象
page:指当前翻译好的类的对象
一个异常对象
exception:类型为Throwable
JSP脚本元素
脚本元素 |
脚本语法 |
声明 |
<%! 声明 %>用于JSP翻译好的类中,定义成员变量、静态变量和方法 |
Scriplet |
<% 代码 %>丰富_jspService方法,是普通JAVA代码 |
脚本表达式 |
<%= 脚本表达式 %>相当于out.print但是注意后面不能加分号 |
指令
u 在JSP中,有三种类型的指令
page指令为当前页面提供处理指令
contentType 设置向客户端输出的MIME类型和字符编码
import 在当前JSP类中导入包
include指令用于把另一个文件包含在JSP中
格式:<%@ include file="relativeURL"%>
静态包含,编译时发生。将被包含文件的内容拷贝在包含文件中。所以两个页面不能有相同的变量。包含的是内容,只能包含文件
taglib指令指定如何包含和访问自定义标签库
<%@taglibprefix=”c” uri=”http://java.sun.com/jsp/jstl/core”%>
动作
u
语法格式为:
page:表示一个相对路径
动态包含,包含的是结果,在请求时发生,所以两页面可以有相同的变量,可包含文件也可包含servlet输出的结果,并可传递参数。但效率比指令包含低
被包含页面可以通过request.getParameter(“abc”)将值取出来
语法格式为:
Jsp注释:
<%-- --%>jsp注释,容器不会翻译,只在源代码可见,服务器和客户端均不可见。最为安全。
html注释,容器会将html注释输出到客户端,服务器和客户端均可见。不能注释动态脚本代码。
// /* */ java代码注释。只在服务器可见。
javaBean规范:
JavaBean 类必须是一个公共类,并将其访问属性设置为 public。
JavaBean 类必须有一个空的构造函数
一个JavaBean类不应有公共实例变量,类变量都为private。要访问这些类变量,应该通过一组存取方法(getXxx 和 setXxx)来访问,不能以大写字母开始命名成员变量,前两个字母都不能是大写
JavaBean应该是可序列化(serializable)的,即实现java.io.Serializable 接口
三层架构:
持久层(dao模式):创建实体类和数据库表进行映射。也就是哪个表对应哪个类,哪个属性对应哪个列,而持久层的作用是就是完成对象数据和关系数据的转换。
业务层(事务脚本):将客户端请求的数据封装成一个方法。该方法中根据业务需要可能会调用多次数据更新操作。必须保证这些操作同时成功,同时失败。不允许部分成功部分失败而导致的数据混乱。
表现层(MVC):
M:模型,也就是实体bean。用于封装、传输数据
V:视图,也就是html和jsp。用于数据的展示
C:控制,也就是Servlet。用于调用业务类的业务方法,并控制操作的流程。
第十章
EL表达式:
我的狗的名字是:${person.dog.name},需要注意,通过EL表达式取属性值时,调用的是get方法,所以如果没有该属性,但是有get方法,同样可以通过EL表达式取出数据。
从pageContext、request、session、ServletContext中查找属性值,从小作用域向大作用域查找,找到之后不再查找。
可以采用EL表达式隐式对象减少搜索范围${requestScope.name}
EL隐式对象作用域
pageScope 与page作用域属性的名称和值相关联的 Map 类
requestScope 与request作用域属性的名称和值相关联的 Map 类
sessionScope 与session作用域属性的名称和值相关联的 Map 类
applicationScope 与application作用域属性的名称和值相关联的 Map 类
EL表达式也可支持运算。${1+2}在页面上显示3 ${3>2}在页面上显示true
JSTL标准标签库(重点)
需要两个JAR文件。第一个文件是jstl.jar,它为JSTL标记库提供API类。第二个文件是standard.jar,它提供了标记库的实现类 。
JSTL分为五种:核心库Core,XML库,SQL库,I18N库,函数库。核心库最为常用
在JSP页面上导入标准标签库
通过<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c” %>引入到JSP
判断标签:条件为真,执行标签体中的内容
${x}
循环标签
遍历Collection集合
${man.id} ${man .name}
遍历Map集合
键对象:${bean .key} 值:${bean.value .name}
AJAX
AJAX涉及到7项技术, Javascript、XMLHttpRequest、Dom、XML、CSS,XHTML,及服务器相关的API
这章内容以操作为主
XMLHttpRequest对象的创建
var xmlHttp = null;
function setXmlHttp(){
if (window.ActiveXObject) {//IE
xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest){//firefox
xmlHttp = newXMLHttpRequest();
}
}
xmlHttpRequest常用属性和方法
//当准备状态发生变化时,调用press方法,以便监控对象,得到响应信息
xmlHttp.onreadystatechange= press;
Get方式发送请求
//第一个参数为提交方式,第二个参数表示请求URL,第三个参数为true表示异步传输,同时表示当响应信息未到达客户端不向下执行代码
//这一步是设置请求行
//xmlHttp.open("GET","checkServlet?name="+userName,true);
//这一步设置消息体,同时向服务器发送请求
//xmlHttp.send(null);
POST方式发送请求
xmlHttp.open("POST","checkServlet",true);
//设置请求头为普通表单格式提交
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//POST方式,消息体内容为请求参数
xmlHttp.send("name="+userName);
//回调函数
functionpress(){
//当xmlHttp的readyState属性为4的时候,表示XmlHttpRequest对象将响应信息返回
if(xmlHttp.readyState== 4){
//xmlHttp.status表示获得响应信息的状态码
if(xmlHttp.status== 200){
//调用服务器返回消息体的信息
varinfo = xmlHttp.responseText;
}
}
}
使用jquery发送AJAX请求
get请求
$.get("test",{ name: "John", time: "2pm" },
function(data){
alert("Data Loaded:" + data);
},"json");
post请求
$.post("cutPage",{pageNO:2},
function(content){
$("#dataDiv").html(content);
},"json");
[张安浩1]