您的位置:首页 > 理论基础 > 计算机网络

Http与Servlet数据传输全流程

2017-05-11 14:54 351 查看
1
课程回顾
Http协议:
1)http协议:
对浏览器客户端和服务器端之间数据传输的格式规范。
2)http请求:浏览器->服务器端

格式:

请求行(请求方式(GET/POST)
请求资源(URI)
http协议版本(http1.1))

请求头(键值对形式存在。 host、user-agent、referer)

一个空行

实体内容(POST提交的参数)
HttpServletRequest对象:
请求对象。获取请求信息。

请求行:request.getMethod() request.getRequestURI/getRequestURL() request.getProtocol();

请求头: request.getHeader("name") request.getHeaderNames()

实体内容: request.getInputStream()

获取参数数据:(GET或POST)
request.getParameter("name")
一个值的参数
request.getParameterValues("name");
多个值的参数
request.getParameterNames()
所有参数

3)http响应:
服务器->浏览器端

格式:

响应行(http协议版本
状态码
描述)

常用的状态码: 200 302 404 500

响应头( location(结合302状态码完成请求重定向功能)、
refresh(定时刷新)、content-type、
content-disiposition(以下载方式打开))

一个空行

实体内容
HttpServletResponse对象:
响应对象。设置响应信息。

响应行: response.setStatus();

响应头: response.setHeader("name","value")

实体内容:
(PrintWriter) response.getWriter().writer();
字符内容

(OutputStream)response.getOutputStream().writer();
字节内容

作业:
通讯录程序

功能:

添加联系人

修改联系人

删除联系人

查询所有联系人

要求:
1)console控制
2)数据保存在xml

今天的目标: servlet编程

第一天:
入门
第二天: http协议
第三天:
如何写servlet程序

Servlet学习的大纲:
l
1. servlet概念及相关接口简介
l
2. servet 执行过程
l
3. servlet路径映射
l
4. 缺省servlet --应用
l
5. servlet生命周期(重点)
--理解(重点)
l
6. Servlet自动加载
l
7. Servlet线程安全
l
8. servletConfig对象
l
9. Servlet相关接口详解
l
10. ServletContext对象 --知识点
1
如何开发一个Servlet
1.1
步骤:
1)编写java类,继承HttpServlet类
2)重新doGet和doPost方法
3)Servlet程序交给tomcat服务器运行!!
3.1 servlet程序的class码拷贝到WEB-INF/classes目录
3.2
在web.xml文件中进行配置

<!-- 配置一个servlet -->

<!-- servlet的配置 -->

<servlet>

<!-- servlet的内部名称,自定义。尽量有意义 -->

<servlet-name>FirstServlet</servlet-name>

<!-- servlet的类全名: 包名+简单类名 -->

<servlet-class>gz.itcast.a_servlet.FirstServlet</servlet-class>

</servlet>

<!-- servlet的映射配置 -->

<servlet-mapping>

<!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->

<servlet-name>FirstServlet</servlet-name>

<!-- servlet的映射路径(访问servlet的名称) -->

<url-pattern>/first</url-pattern>

</servlet-mapping>
问题:访问次URL: http://localhost:8080/day10/first
前提: tomcat服务器启动时,首先加载webapps中的每个web应用的web.xml配置文件。 http://: http协议
localhost:
到本地的hosts文件中查找是否存在该域名对应的IP地址
127.0.0.1
8080:
找到tomcat服务器
/day10
在tomcat的webapps目录下找
day10的目录
/first
资源名称。
1)在day10的web.xml中查找是否有匹配的url-pattern的内容(/first)
2)如果找到匹配的url-pattern,则使用当前servlet-name的名称到web.xml文件中查询是否相同名称的servlet配置
3)如果找到,则取出对应的servlet配置信息中的servlet-class内容:

字符串:
gz.itcast.a_servlet.FirstServlet

通过反射:
a)构造FirstServlet的对象
b)然后调用FirstServlet里面的方法
2 Servlet的映射路径

<servlet-mapping>

<!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->

<servlet-name>FirstServlet</servlet-name>

<!-- servlet的映射路径(访问servlet的名称) -->

<url-pattern>/first</url-pattern>

</servlet-mapping>
url-pattern
浏览器输入
精确匹配 /first http://localhost:8080/day10/first /itcast/demo1 http://localhost:8080/day10/itcast/demo1
模糊匹配 /* http://localhost:8080/day10/任意路径 /itcast/* http://localhost:8080/day10/itcast/任意路径 *.后缀名 http://localhost:8080/day10/任意路径.do *.do
*.action
*.html(伪静态)

注意:
1)url-pattern要么以
/ 开头,要么以*开头。
例如, itcast是非法路径。
2)不能同时使用两种模糊匹配,例如
/itcast/*.do是非法路径
3)当有输入的URL有多个servlet同时被匹配的情况下:
3.1
精确匹配优先。(长的最像优先被匹配)
3.2
以后缀名结尾的模糊url-pattern优先级最低!!!
3 servlet缺省路径
servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。

问题: URL输入http://localhost:8080/day10/index.html
如何读取文件????

1)到当前day10应用下的web.xml文件查找是否有匹配的url-pattern。
2)如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理
3)DefaultServlet程序到day10应用的根目录下查找是存在一个名称为index.html的静态文件。
4)如果找到该文件,则读取该文件内容,返回给浏览器。
5)如果找不到该文件,则返回404错误页面。

结论:
先找动态资源,再找静态资源。
4 Sevlet的生命周期(重点)
4.1
引入
Servlet的生命周期:
servlet类对象什么时候创建,什么时候调用什么方法,什么时候销毁。

以前的对象: new Student();
stu.study(); stu=null;

Servlet程序的生命周期由tomcat服务器控制的!!!!

4.2 Servlet重要的四个生命周期方法

构造方法:
创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象
只调用1次。证明servlet对象在tomcat是单实例的。
init方法:
创建完servlet对象的时候调用。只调用1次。
service方法:
每次发出请求时调用。调用n次。
destroy方法:
销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。

只调用1次。

4.3
伪代码演示servlet的生命周期
Tomtcat内部代码运行:
1)通过映射找到到servlet-class的内容,字符串:
gz.itcast.a_servlet.FirstServlet
2)通过反射构造FirstServlet对象
2.1
得到字节码对象
Class clazz = class.forName("gz.itcast.a_servlet.FirstServlet");
2.2
调用无参数的构造方法来构造对象
Object obj = clazz.newInstance(); ---1.servlet的构造方法被调用
3)创建ServletConfig对象,通过反射调用init方法
3.1
得到方法对象
Method m = clazz.getDeclareMethod("init",ServletConfig.class);
3.2
调用方法
m.invoke(obj,config); --2.servlet的init方法被调用
4)创建request,response对象,通过反射调用service方法
4.1
得到方法对象
Method m =clazz.getDeclareMethod("service",HttpServletRequest.class,HttpServletResponse.class);
4.2
调用方法
m.invoke(obj,request,response); --3.servlet的service方法被调用
5)当tomcat服务器停止或web应用重新部署,通过反射调用destroy方法
5.1
得到方法对象
Method m = clazz.getDeclareMethod("destroy",null);
5.2
调用方法
m.invoke(obj,null); --4.servlet的destroy方法被调用

4.4
用时序图来演示servlet的生命周期



5 Servlet的自动加载

默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。

改变servlet创建对象的时机:
提前到加载web应用的时候!!!

在servlet的配置信息中,加上一个<load-on-startup>即可!!

<servlet>

<servlet-name>LifeDemo</servlet-name>

<servlet-class>gz.itcast.c_life.LifeDemo</servlet-class>

<!-- 让servlet对象自动加载 -->

<load-on-startup>1</load-on-startup> 注意: 整数值越大,创建优先级越低!!

</servlet>
7
有参的init方法和无参的init方法
8 Servlet的多线程并发问题

注意: servlet对象在tomcat服务器是单实例多线程的。

因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

解决办法:
1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)
2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

Servlet学习:
HttpServletRequest
请求对象:获取请求信息
HttpServletResponse
响应对象:
设置响应对象
ServletConfig对象
servlet配置对象
ServletContext对象;
servlet的上下文对象
9 ServletConfig对象
9.1
作用
ServletConfig对象:
主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)
9.2
对象创建和得到

创建时机:
在创建完servlet对象之后,在调用init方法之前创建。

得到对象:
直接从有参数的init方法中得到!!!

9.3 servlet的初始化参数配置

<servlet>

<servlet-name>ConfigDemo</servlet-name>

<servlet-class>gz.itcast.f_config.ConfigDemo</servlet-class>

<!-- 初始参数: 这些参数会在加载web应用的时候,封装到ServletConfig对象中 -->

<init-param>

<param-name>path</param-name>

<param-value>e:/b.txt</param-value>

</init-param>

</servlet>
注意: servlet的参数只能由当前的这个sevlet获取!!!!

ServletConfig的API:
java.lang.String getInitParameter(java.lang.String name)
根据参数名获取参数值
java.util.Enumeration getInitParameterNames() 获取所有参数
ServletContext getServletContext() 得到servlet上下文对象
java.lang.String getServletName()
得到servlet的名称

10 ServletContext对象
10.1
引入
ServletContext对象
,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一
个ServletContext对象。
10.2
对象创建和得到

创建时机:加载web应用时创建ServletContext对象。

得到对象:
从ServletConfig对象的getServletContext方法得到

我们设计:

创建ServletConfig对象
public void init( ServletConfig config,ServletContext
context ){ 多了一个参数

得到ServletConfig对象

得到ServletContext对象;
}

Sun公司设计
1)创建ServletContext对象
ServletContext context = new ServletContext()

2)创建ServletConfig对象
ServetConfig config = new ServletConfig();
config.setServletContxt(context);
class ServletConfig{
ServletContext context;
public ServletContext getServletContxt(){
return contxt;
}
}

public void init( ServletConfig config ){

得到ServletConfig对象

从ServletConfig对象中得到ServletContext对象
SerlvetContext context = config.getServletContext();
}

10.1 ServletContext对象的核心API(作用)

java.lang.String getContextPath() --得到当前web应用的路径

java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()

void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
java.lang.Object getAttribute(java.lang.String name)
void removeAttribute(java.lang.String name)

RequestDispatcher getRequestDispatcher(java.lang.String path) --转发(类似于重定向)

java.lang.String getRealPath(java.lang.String path) --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path)

10.3
得到web应用路径
java.lang.String getContextPath()
用在请求重定向的资源名称中
10.4得到web应用的初始化参数(全局)
java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()

web应用参数可以让当前web应用的所有servlet获取!!!
10.5域对象有关的方法

域对象:作用是用于保存数据,获取数据。可以在不同的动态资源之间共享数据。

案例:
Servlet1 Servlet2
name=eric
response.sendRedirect("/Servlet2?name=eric") String request.getParameter("name");

保存到域对象中
从域对象获取
Student

方案1:
可以通过传递参数的形式,共享数据。局限:只能传递字符串类型。

方案2:
可以使用域对象共享数据,好处:可以共享任何类型的数据!!!!!

ServletContext就是一个域对象!!!!

保存数据:void setAttribute(java.lang.String name, java.lang.Object object)

获取数据: java.lang.Object getAttribute(java.lang.String name)

删除数据: void removeAttribute(java.lang.String name)

ServletContext域对象:作用范围在整个web应用中有效!!!

所有域对象:
HttpServletRequet
域对象
ServletContext域对象
HttpSession
域对象
&n
15aa3
bsp; PageContext域对象

10.6
转发
RequestDispatcher getRequestDispatcher(java.lang.String path)

1)转发
a)地址栏不会改变
b)转发只能转发到当前web应用内的资源
c)可以在转发过程中,可以把数据保存到request域对象中

2)重定向
a)地址栏会改变,变成重定向到地址。
b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。
c)不能再重定向的过程,把数据保存到request中。

结论:
如果要使用request域对象进行数据共享,只能用转发技术!!!

总结:
Servlet编程:
Servlet生命周期(重点)

其他都是应用的东西(敲代码练习)

servlet的继承关系:

定义:自己写并配置在web.xml中的servlet名称为myServlet

继承关系:myServlet-->HttpServlet-->GenericServlet-->Servlet

方法概述:方法主要存在于GenericServlet中,主要用于获取servlet四大对象汇中的方法与信息

servlet的四大对象:

1)HttpServletRequest

作用:获取客户端发送过来的,封装在http的header和body中的全部参数

主要方法:getParameter();

2)HttpServletResponse

作用:设置传递给客户端的数据

主要方法:setContentType();

3)ServletConfig

作用:用于传递配置在web.xml中的参数+init-param/servlet配置对象

方法:
java.lang.String getInitParameter(java.lang.String name)
根据参数名获取参数值
java.util.Enumeration getInitParameterNames()
获取所有参数
ServletContext getServletContext()
得到servlet上下文对象
java.lang.String getServletName()
得到servlet的名称

4)ServletContext

作用:获取当前应用配置在web.xml中的所有信息/sevlet上下文对象

初始化:ServletContext sctx = GenericServlet(以及继承类).getContextPath();

方法:
java.lang.String getContextPath() --得到当前web应用的路径

java.lang.String getInitParameter(java.lang.String name) --得到web应用的初始化参数
java.util.Enumeration getInitParameterNames()

void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法
java.lang.Object getAttribute(java.lang.String name)
void removeAttribute(java.lang.String name)

RequestDispatcher getRequestDispatcher(java.lang.String path) --转发(类似于重定向)

java.lang.String getRealPath(java.lang.String path) --得到web应用的资源文件
java.io.InputStream getResourceAsStream(java.lang.String path)

5)创建顺序:ServletContext早于ServletConfig创建

网络数据传输流程:

1.客户端发送http标准格式的request:

格式如下:

请求行---GET/POST/projectA(项目名称)/first
HTTP/1.1

请求头--- Host:localhost:8080(主机地址)
User-Agent:客户端浏览器类型
.....

一个空行

实体内容(实体内容除了键值对形式是否还有其他形式)

2.截取/projectA,进入Tomcat中webApps目录下projectA的目录
3.截取/first,去projectA的web.xml文件夹下查询是否有匹配的url-pattern
4.如果匹配,就在web.xml文件中查询是否有匹配的servlet配置
5.如果找到,就从projectA拿出该servlet配置中的servlet-class的内容FirstServlet
6.构造FirstServlet对象
7.调用构造方法,通过反射的方式,以web.xml中配置信息为准,先构建SevletContext对象,然后创建ServletConfig对象,ServletConfig对象可以通过getServletContext()方法获取ServletConfig
8.进入Servlet生命周期:调用init(ServletConfig),并创建HttpServletRequest和HttpServletResponse对象
9.调用service(HttPServletRequest
req,HttpServletResponse res)方法,在service方法中,可以通过req拿到http请求中所有的内容,相关方法可以查阅API

而在res方法中,可以设置返回给客户端的所有的相应内容

把response对象解析成响应格式的数据
(PrintWriter) response.getWriter().writer(); ---字符流

(OutputStream)response.getOutputStream().writer();
---字节流

相应内容格式:
响应行:http
1.1 status:200 ok(状态描述)
响应头:location
refresh content-type content-disposition
一个空行
实体内容(使用输出流:字符流和字节流)

10.如果tomcat服务器停止服务,调用destroy方法

提高加载速度的办法<load-on-startup></load-on-startup>:在加载web应用的时候就创建类,这样在启动web应用的时候速度就不会慢

域对象:作用是用于保存数据,获取数据。可以在不同的动态资源之间共享数据。
ServletContext就是一个域对象!!!!

ServletContext对象的方法:

保存数据:void setAttribute(java.lang.String name, java.lang.Object object)

获取数据: java.lang.Object getAttribute(java.lang.String name)

删除数据: void removeAttribute(java.lang.String name)

其他域对象:
HttpServletRequet
域对象
ServletContext域对象
HttpSession
域对象
PageContext域对象

转发
RequestDispatcher getRequestDispatcher(java.lang.String path)

1)转发
a)地址栏不会改变
b)转发只能转发到当前web应用内的资源
c)可以在转发过程中,可以把数据保存到request域对象中

2)重定向
a)地址栏会改变,变成重定向到地址。
b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。
c)不能再重定向的过程,把数据保存到request中。

结论:
如果要使用request域对象进行数据共享,只能用转发技术!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: