Servlet主要知识点
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
Servlet的实现
Servlet 是 Server 与 Applet 的缩写,是服务端小程序的意思。使用 Java 语言编写的服务器端程序,可以生成动态的 WEB 页,Servlet 主要运行在服务器端,并由服务器调用执行, 是一种按照 Servlet 标准来开发的类。 是 SUN 公司提供的一门用于开发动态 Web 资源的技术。要实现 web 开发,需要实现 Servlet 标准。
- 什么是Servlet? ,Servlet 本质上也是 Java 类,但要遵循 Servlet 规范进行编写,没有 main()方法,它的创建、使用、销毁都由 Servlet 容器进行管理(如 Tomcat)。;
- Servlet是和 HTTP 协议是紧密联系的,其可以处理 HTTP 协议相关的所有内容。这也是 Servlet 应用;
广泛的原因之一。 - 在 web项目中实现Servlet,步骤如下 :
创建一个web项目
设置项目存放路径及项目名称
引入jar包依赖
创建一个类并且继承HttpServlet
点击 “src” —> “new” —> “package”,创建一个文件包
在包下面创建 Java 类文件,点击包名 —> “New” —> "Java Class
然后继承 HttpServlet
这样一个web项目就实现了servlet.
Servlet的工作流程
- 通过请求头获知浏览器访问的是哪个主机
- 再通过请求行获取访问的是哪个一个web应用
- 再通过请求行中的请求路径获知访问的是哪个资源
- 通过获取的资源路径在配置中匹配到真实的路径,
- 服务器会创建servlet对象,(如果是第一次访问时,创建servlet实例,并调用init方法进行初始化
操作) - 调用service(request, response)方法来处理请求和响应的操作
- 调用service完毕后返回服务器 由服务器讲response缓冲区的数据取出,以http响应的格式发送给浏览器。
Servlet的生命周期
Servlet没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控制和调度。 生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调用其方法进行请求的处理、 何时并销毁其实例的整个过程。
- 实例和初始化时机
当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例并进行初始化。- 就绪/调用/服务阶段
有请求到达容器,容器调用 servlet 对象的 service()方法,处理请求的方法在整个生命周期中可以被多次调用; HttpServlet 的 service()方法,会依据请求方式来调用 doGet()或者 doPost()方法。- 销毁时机
当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。
上述的生命周期可以通过 Servlet 中的生命周期方法来观察。
- init 方法,在 Servlet 实例创建之后执行
public void init(ServletConfig config) throws ServletException {
System.out.println("实例初始化");
}
- service 方法,每次有请求到达某个 Servlet 方法时执行,用来处理请求.
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("请求被响应,执行服务");
}
- destroy 方法,Servlet 实例销毁时执行
public void destroy() {
System.out.println("实例被销毁了");
}
HttpRequest对象
HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息。
- 接收请求–常用方法
常用方法 | 方法介绍 |
---|---|
getRequestURL() | 获取客户端发出请求时的完整url |
getRequestURI() | 获取请求行中的资源部分的名称(从项目名称开始) |
getQueryString | 获取请求行中的参数部分 |
geMethod() | 获取请求行中的参数部分 |
getProtocol() | 获取Http版本号 |
geContextPath() | 获取webapp名称 |
- 获取请求参数
常用方法 | 方法介绍 |
---|---|
getParameter(name) | 获取指定名称的参数 |
getParameterValues(String name) | 获取指定名称参数的所有值 |
请求乱码问题处理
请求乱码问题分为get请求和post请求两种情况(Tomacat 8.0版本及以上,get请求不会出现乱码)。
针对post请求乱码:request.setCharacterEncoding("UTF-8");
get请求乱码:
new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
请求转发
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
代码实例:request.getRequestDispatcher(url).forward(request,response);
request的作用域(范围)
request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。
HttpServletResponse对象
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。
request 和 response 对象代表请求和响应:获取客户端数据,需要通过 request 对象;向客户端输出数据,需要通过 response 对象。
HttpServletResponse 的主要功能用于服务器对客户端的请求进行响应,将 Web 服务器处理后的结果返回给客户端。service()方法中形参接收的是 HttpServletResponse 接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
响应数据
接收到客户端请求后,可以通过 HttpServletResponse 对象直接进行响应,响应时需要获取输出流。有两种形式(两者不能同时使用):
getWriter()方法: 获取字符流(只能响应回字符);
getOutputStream()方法: 获取字节流(能响应一切数据)
举一个例子:// 字符输出流 PrintWriter writer = response.getWriter();p writer.write("Hello World"); writer.write("<p>Hello World</p>");
// 字节输出流 ServletOutputStream out = response.getOutputStream(); out.write("Hello World".getBytes()); out.write("<p>Hello World</p>".geptBytes());
响应乱码问题
对于 getWriter()方法 获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。告知服务器编码:
response.setCharacterEncoding("UTF-8");
指定客户端解码:
response.setHeader("content-type", "text/html;charset=UTF-8")
保证收发端的编码方式一致,一句代码解决:
response.setContentType("text/html;charset=UTF-8");
同理对于getOutputStream()字节乱码解决方式也是一样,解决方法类似,就不在这里赘述。
一句代码:response.setContentType("text/html;charset=UTF-8")
页面重定向
重定向是一种服务器指导,客户端的行为。例子:
// 重定向跳转到login.jsp response.sendRedirect("login.jsp");
请求转发与页面重定向的区别(两者都用于跳转)
请求转发:req.getRequestDispatcher().forward()
页面重定向:resp.sendRedirect()
请求转发 | 页面重定向 |
---|---|
一次请求,数据在request作用域中共享 | 两次请求,request作用域中的数据不共享 |
服务端行为 | 客户端行为 |
地址栏不发生变化 | 地址栏改变 |
Cookie对象
Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保存在客户端,或者在客户端进行处理的数据,放在本地的计算机上,不需要通过网络传输,因而提高网页处理的效率,并且能够减少服务器的负载,但是由于 Cookie 是服务器端保存在客户端的信息, 所以其安全性也是很差的(常见的记住密码则可以通过 Cookie 来实现)。
有一个专门操作Cookie的类 javax.servlet.http.Cookie。随着服务器端的响应发送给客户端,保存在浏览器。当下次再访问服务器时把Cookie再带回服务器。
Cookie 的格式:键值对用“=”链接,多个键值对间通过“;”隔开。
Cookie的创建和发送
通过 new Cookie(“key”,“value”);来创建一个 Cookie 对象,要想将 Cookie
随响应发送到客户端,需要先添加到 response 对象中,response.addCookie(cookie);此时该 cookie对象则随着响应发送至了 客户端。在浏览器上可以看见。
// 创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
// 发送Cookie对象
response.addCookie(cookie)
Cookie的获取
使用getCookies()方法用来获取客户端回传的所有cookie组成的一个数组。
Cookie设置到期时间(失效时间)
默认情况下当前浏览器关闭cookie即失效。我们可以手动设定 cookie 的有效时间(通过到期时间计算),通过 setMaxAge(int time);方法设定 cookie 的最大有效时间,以秒为单位。
setMaxAge(int time) ,time参数(到期时间)的取值。
负整数:若为负数,表示不存储该 cookie。cookie 的 maxAge 属性的默认值就是-1,表示只在浏览器内存中存活,一旦关闭浏览器窗口,那么 cookie 就会消失。
正整数:若大于 0 的整数,表示存储的秒数。表示 cookie 对象可存活指定的秒数。当生命大于 0 时,浏览器会把 Cookie 保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie 也会存活相应的时间。
零:若为 0,表示删除该 cookie。cookie 生命等于 0 是一个特殊的值,它表示 cookie 被作废!也就是说,如果原来浏览器已经保存了这个 Cookie,那么可以通过 Cookie 的setMaxAge(0)来删除这个 Cookie。 无论是在浏览器内存中,还是在客户端硬盘上都会删除这个 Cookie。
指定失效时间:
// 创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
// 指定Cookie 2天后失效
cookie.setMaxAge(2 * 24 * 60 * 60);
// 发送Cookie对象
response.addCookie(cookie);
Cookie的注意事项
- Cookie保存在当前浏览器,在其它浏览器或者电脑上找不到。
- Cookie存中文问题:Cookie 中不能出现中文,如果有中文则通过URLEncoder.encode()来进行编码,获取时通过URLDecoder.decode()来进行解码。
- 同名Cookie问题:如果服务器端发送重复的Cookie那么会覆盖原有的Cookie。
- 浏览器存放的Cookie的数量是有限制的,不同的浏览器限制个数不同。
HttpSession对象
HttpSession对象是 javax.servlet.http.HttpSession 的实例,是一个纯粹的接口( session 本身就属于HTTP 协议的范畴)。
session 无论客户端还是服务器端都可以感知到,若重新打开一个新的浏览器,则无法取得之前设置的 session,因为每一个 session 只保存在当前的浏览器当中,并在相关的页面取得。
Session 的作用就是为了标识一次会话,或者说确认一个用户;并且在一次会话(一个用户的多次请求)期间共享数据。我们可以通过request.getSession()方法,来获取当前会话的 session 对象。
// 如果session对象存在,则获取;如果session对象不存在,则创建
HttpSession session = request.getSession();
Session域对象
Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在。
- 向Session域对象添加数据---->setAttribute(name,value) 方法
- 向Session域对象获取数据—>getAttribute(name) 方法
- 向Session域对象删除数据—> removeAttribute(name) 方法
// 获取session对象
HttpSession session = request.getSession();
// 设置session域对象
session.setAttribute("uname","admin");
// 获取指定名称的session域对象
String uname = (String) request.getAttribute("uname");
// 移除指定名称的session域对象
session.removeAttribute("uname");
Session的生命周期
- 默认情况下:
当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min,即你不操作界面的时间,一旦有操作,session 会重新计时。 - 手动修改设定生命周期
通过session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。
// 获取session对象
HttpSession session = request.getSession();
// 设置session的最大不活动时间
session.setMaxInactiveInterval(15); // 15秒
- 关闭浏览器时,cookie失效,session底层依赖于赖 cookie 实现。所以当关闭浏览器时,session也相当于失效了。
- 关闭服务器时,session销毁。
ServletContext对象
每一个 web 应用都有且仅有一个ServletContext 对象,又称 Application 对象。在 WEB 容器启动的时候,会为每一个 WEB 应用程序创建一个对应的
ServletContext 对象。
该对象有两大作用,
第一、作为域对象用来共享数据,此时数据在整个应用程序中共享;
第二、该对象中保存了当前应用程序相关信息。
-通过 getServerInfo() 方法获取当前服务器信息,getRealPath(String path) 获取资源的真实路径等。// 获取项目存放的真实路径 String realPath = request.getServletContext().getRealPath("/"); // 获取当前服务器的版本信息 String serverInfo = request.getServletContext().getServerInfo();
ServletContext对象的获取
获取 ServletContext 对象的途径有很多。
通过 request 对象获取
ServletContext servletContext = request.getServletContext();
通过 session 对象获取
ServletContext servletContext = request.getSession().getServletContext();
通过 servletConfig 对象获取
ServletConfig servletConfig = getServletConfig(); ServletContext servletContext = servletConfig.getServletContext();
直接获取,Servlet 类中提供了直接获取 ServletContext 对象的方法
ServletContext servletContext = getServletContext();
ServletContext域对象
ServletContext 也可当做域对象来使用,通过向 ServletContext 中存取数据,可以使得整个应用程序共享某些数据。不建议存放过多数据,因为 ServletContext 中的数据一旦存储进去没有手动移除将会一直保存。
// 获取ServletContext对象
ServletContext servletContext = request.getServletContext();
// 设置域对象
servletContext.setAttribute("name","zhangsan");
// 获取域对象
String name = (String) servletContext.getAttribute("name");
// 移除域对象
servletContext.removeAttribute("name");
Servlet的三大域对象
- request域对象
在一次请求中有效。请求转发有效,页面重定向失效。 - session域对象
在一次会话中有效。请求转发和页面重定向都有效,session销毁后失效。 - servletContext域对象
在整个应用程序中有效。服务器关闭后失效。