servlet相关概念
Servlet 为创建基于 web 的应用程序提供了基于组件、独立于平台的方法,可以不受 CGI 程序的性能限制。Servlet 有权限访问所有的 Java API,包括访问企业级数据库的 JDBC API.
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
架构图:
Servlet任务
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
servlet执行原理
- 当服务器接收到客户端浏览器的请求后,会解析请求url路径,获取访问的servlet的资源路径
- 查找web.xml文件,是否有对应的
标签体内容 - 如果有,则找到对应的
全类名 - tomcat会将字节码文件加载进内存,并且创建其对象
- 调用方法
Servlet 生命周期
Servlet生命周期可被定义为从创建到毁灭的整个过程.以下是Servlet遵循的过程:
Servlet 通过调用 init () 方法进行初始化。
- servlet的init方法只执行一次,说明一个servlet在内存中只存在一个对象,servlet是单例的 多个用户同时访问时可能会出现线程安全的问题
- 解决:尽量不要在servelt中定义成员变量,即使定义了成员变量也不要对其修改值
Servlet 调用 service() 方法来处理客户端的请求。
Servlet 通过调用 destroy() 方法终止(结束)。
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的
Servlet 表单数据:
很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。
http协议:
基本概念:
http: Hyper Text Transfer Protocol 超文本传输协议
传输协议:定义了,客户端和服务端通信时,发送数据的格式
- 特点:
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求/响应模型的:一次请求对应一次响应
- 无状态的:每次请求之间相互独立,不能交互数据
- 历史版本:
- 1.0: 每一次请求都会建立新的连接
- 1.1:复用连接
请求消息数据格式:
请求行
请求方式 请求url 请求协议/版本
GET /login.html HTTP/1.1
- 请求方式:
- http协议有七种请求方式,常用的有两种
- GET:
- 请求参数在请求行中,在url后
- 请求的url长度是有限制的
- 不太安全的
- POST:
- 请求参数在请求体中
- 请求的url的长度是没有长度的
- 相对安全的
- GET:
- http协议有七种请求方式,常用的有两种
- 请求方式:
请求头
- 作用:客户端浏览器告诉服务器一些信息
请求头名称: 请求头值
常见的请求头:
- User-Agent: 浏览器告诉服务器,我访问你使用的浏览器版本信息 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
- referer:http://localhost/login.html 告诉服务器我(当前请求)从哪儿来?
- 作用:
- 防盗链:
- 统计工作:
请求空行
空行,分割请求头和请求体
请求体(正文)
封装post请求消息的请求参数的
响应消息数据格式:
- 响应行
- 组成:协议/版本 响应状态码 状态码描述
- HTTP/1.1 200 OK
- 响应状态码: 服务器告诉客户端浏览器请求和响应的一个状态
- 状态码都是三位数字
- 分类:
- 一百多:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送一百多的状态码
- 二百多:成功
- 三百多:302:重定向 304: 访问缓存
- 四百多:客户端错误 404:请求路径没有对应的资源 405:请求方式没有对应的doxxx方法
- 五百多:服务器端错误
- 组成:协议/版本 响应状态码 状态码描述
- 响应头
- 组成:响应头名称: 响应头值
- 常见的响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- Content-disposition:服务器告诉客户端以什么样的格式打开响应体数据
- 值:
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体,文件下载
- 值:
- 响应空行
- 响应体:传输的数据
HTTP协议工作流程:
- 地址解析(,解析URL,DNS解析)
- 封装HTTP请求(这一步把上面写的 URL 以及本机的一些信息封装成一个 HTTP 请求数据包)
- 封装TCP包(第三步就是封装 TCP 包 , 建立 TCP 连接 , 也就是常说的”三次握手” . 由于HTTP位于最上层的应用层 , 所以HTTP在工作之前要由 TCP 和 IP 协议建立网络连接 , 这就是TCP/IP协议族 , 因此互联网又称为 TCP/IP 网络 .)
- 客户端发送请求命令(第四步就是在连接建立之后 , 客户端发送 HTTP 请求到服务端与请求相关的信息都会包含在请求头和请求体中发送给服务器端 )
- 服务器端响应(服务器端在收到请求之后 , 根据客户端的请求发送给客户端相应的信息 , 相关的响应信息都会放在响应头和响应体中 )
- 关闭连接(服务器端在发送完响应之后 , 就会关闭连接 , 如果过客户端的请求的头部信息中有 Connection-alive , 那么客户端在响应完这个请求之后不会关闭连接 , 直到客户端的所有请求都响应完毕 , 才会关闭连接 , 这样大大节省了带宽和 IO 资源 )
GET方法:
GET 方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用 ? 字符分隔,如下所示:
http://www.test.com/hello?key1=value1&key2=value2
GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。
这些信息使用 QUERY_STRING 头传递,并可以通过 QUERY_STRING 环境变量访问,Servlet 使用 doGet() 方法处理这种类型的请求。
post方法:
另一个向后台程序传递信息的比较可靠的方法是 POST 方法。POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。Servlet 使用 doPost() 方法处理这种类型的请求。
request:
request对象和response对象的原理:
- request和response对象是由服务器创建的,我们来使用它们
- request对象是获取请求消息,response对象是用来设置响应消息
request对象继承体系结构:
ServletRequest –接口
| 继承
HttpServletRequest –接口
|实现
org.apache.catalina.connector.RequestFacade类(tomcat)
request功能:
获取请求消息数据
- 获取请求行数据
- GET /day14/demo1?name=zhangsan HTTP/1.1
- 方法:
- 获取请求方式:GET
- String getMethod()
- 获取虚拟目录: /day14
- String getContextPath()
- 获取Servlet路径: /demo1
- String getServletPath()
- 获取get方式的请求参数:name=zhangsan
- String getQueryString()
- 获取请求URL:/day14/demo1
- String getRequestURI :/servlet01/RequestDemo1
- StringBuffer getRequestURL() :http://localhost:8080/servlet01/RequestDemo1
- URL:统一资源定位符 :http://localhost:8080/servlet01/RequestDemo1
- URI:统一资源标识符 :/servlet01/RequestDemo1
- 获取协议及版本:HTTP/1.1
- String getProtocol()
- 获取客户机的IP地址:
- String getRemoteAddr()
- 获取请求方式:GET
- 获取请求头数据
- 方法:
- 通过请求头的名称获取请求头的值
- String getHeader(String name)
- 获取所有的请求头名称
- Enumeration\<String> get HeaderNames()
- 通过请求头的名称获取请求头的值
- 方法:
- 获取请求体数据
- 请求体:只有post请求方式,才有请求体,在请求体中封装了POST请求的请求参数
- 步骤:
- 获取流对象
- BufferedReader getReader():获取字符输入流,只能操作字符数据
- ServletInputStream getInputStream():获取字节输入流,可以操作所有数据类型
- 再从流对象中获取数据
- 获取流对象
- 获取请求行数据
其他功能
获取请求参数通用方式(get和post通用)
- String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
- String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game
- Enumeration\<String> getParameterNames():获取所有请求的参数名称
- Map<String,String[]> getParameterMap():获取所有参数的map集合
中文乱码问题:
get方式:tomcat8已经将get方式乱码问题解决了
post方式:会乱码
解决:在获取参数前,设置request的编码为utf-8
1
request.setCharacterEncoding("utf-8");
请求转发:一种在服务器内部的资源跳转方式
步骤
通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
request.getRequestDispatcher("/RequestDemo6").forward(request,response);
- 特点:
浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中
转发是一次请求
共享数据:
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
- 方法:
void setAttribute(String name,Object obj):存储数据
- Object getAttribute(String name):通过键来获取值
void removeAttribute(String name):通过键来移除键值对
获取ServletContext:
- ServletContext getServletContext()
response:
response对象继承体系结构:
ServletResponse –接口
| 继承
HttpServletResponse –接口
|实现
org.apache.catalina.connector.ResponseFacade@3b2b20f1(tomcat)
功能:设置相应消息
- 设置响应行
- HTTP/1.1 200 OK
- 设置状态码:setStatus(int sc)
- 设置响应头
- setHeader(String name,String value)
- 设置响应体
- 使用步骤:
- 获取输出流
- 字符输出流:PrintWriter getWriter()
- 字节输出流:ServletOutputStream getOutPutStream()
- 使用输出流,将数据输出到客户端浏览器
- 获取输出流
- 使用步骤:
- 设置响应行
案例:
完成重定向(资源跳转的方式):
代码实现
1
2
3
4//1.设置状态码:302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/servlet01/ResponseDemo2");response.sendRedirect("/servlet01/ResponseDemo2");
重定向的特点
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求,不可以使用request对象来共享数据
路径的写法
- 相对路径:通过相对路径不可以确定唯一资源
- 规则:找到当前资源和目标资源之间的相对位置关系
- 以./或../开头或者直接写名称
- 绝对路径:通过绝对路径可以确定唯一资源,以/开头
- 规则:判断定义的路径是给谁用的,判断请求将从哪儿发出
- 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
- 建议虚拟目录动态获取:request.getContextPath()
- \<a>,\<form>,重定向
- 给服务器使用:不需要加虚拟目录
- 转发路径
- 相对路径:通过相对路径不可以确定唯一资源
服务器输出字符数据到浏览器
步骤:
- 获取字符输出流
- 输出数据
注意:
乱码问题:
- PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
- 设置该流的默认编码
- 告诉浏览器应该使用什么编码来解析
解决方法:
简单形式,设置编码,在获取流之前
response.setContentType("text/html;charset=utf-8");
服务器输出字节数据到浏览器
- 步骤:
- 获取字节输出流
- 输出数据
- 步骤:
验证码
- 本质:图片
- 目的:防止恶意表单注册
重定向和转发的区别:
- 从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
- 从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
- 从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
- 从效率来说
forward:高.
redirect:低.
ServletContext对象
概念:代表整个web应用,可以和程序的容器(服务器)来通信
获取:
- 通过request对象获取
- request.getServletContext();
- 通过HtpServlet获取
- this.getServletContext();
- 通过request对象获取
功能
获取MIME类型:
- 在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html image/jpeg
- 获取:String getMimeType(String file)
- 在互联网通信过程中定义的一种文件数据类型
域对象:共享数据
- setAttribute(String name,Object value)
- getAttribute(String name)
- removeAttribute(String name)
- ServletContext对象范围:所有用户所有请求的数据
获取文件的真实路径(服务器路径)
- 方法:String getRealPath(String path)