(1)创建:构造方法
(2)初始化:init()
默认:第一次访问时,完成创建和初始化。
1
(3)执行:service() 客户端发起请求时执行
(4)销毁:destroy() 服务器关闭时,Servlet被销毁
问题1:Servlet对象创建、初始化并使用完后会销毁吗?
显然,Servlet对象在创建、初始化并使用后不应该销毁。如果使用完(请求处理完)就销毁,那么下次过来请求又得去创建Servlet对象,这样效率并不高!!
我们自始至终都使用同一个Servlet对象去处理请求,如果同时有10个请求过来访问Tomcat服务器,服务器会创建10个线程来处理请求,因为service方法不涉及到全局变量的修改操作,所以也不会有线程安全问题的。
问题2:Servlet对象会被创建及初始化几次?
由问题1,我们可以了解到,Servlet对象只会被创建及初始化一次。之后会驻留在内存当中。
问题3:Servlet对象是在什么时候创建及初始化的?
Servlet的创建与初始化的时机有两个:
Servlet在第一次被浏览器访问的时候创建与初始化的(目前我们的代码用的就是这种方式,默认就是这种)
Servlet在启动服务器的时候被创建与初始化的(该方式需要做一些配置,告诉Tomcat服务器在启动的时候就创建Servlet对象)
问题4:Servlet对象什么时候销毁?
Servlet对象是由Tomcat服务器创建的,之后就一直驻留在内存中处理请求。直到服务器停止后,Servlet才会被销毁!
/UserServlet
*.do
/user/UserServlet
/*
/
hello.html
(1)获取请求方式
req.getMethod();
(2)获取URI
req.getRequestURI();
(3)获取协议及版本号
req.getProtocol();
(4)获取请求头中的数据
req.getHeader(请求头中的key);
(5)获取请求头中的所有key的值
req.getHeaderNames();
(6)获取客户端的IP
req.getRemoteHost();
(7)获取客户端的端口号
req.getRemotePort();
※(8)获取请求参数
req.getParameter(key值);
※(9)获取请求参数,同一个key值对应了多个value
req.getParameterValues(key值);
※(10)获取所有请求参数key值
req.getParameterNames();
※(11)获取请求参数的Map集合
req.getParameterMap();
※(12)设置编码格式
req.setCharacterEncoding("utf-8");
※(13)设置响应体内容类型
resp.setContentType("text/html;charset=utf-8");
| Type | Meaning |
|---|---|
| application/postscript | PostScript file |
| application/vnd.lotus-notes | Lotus Notes file |
| application/vnd.ms-excel | Excel spreadsheet |
| application/vnd.ms-powerpoint | PowerPoint presentation |
| application/x-gzip | Gzip archive |
| application/x-java-archive | JAR file |
| application/x-java-serialized-object | Serialized Java object |
| application/x-java-vm | Java bytecode (.class) file |
| application/zip | Zip archive |
| audio/basic | Sound file in .au or .snd format |
| audio/midi | MIDI sound file |
| audio/x-aiff | AIFF sound file |
| audio/x-wav | Microsoft Windows sound file |
| image/gif | GIF image |
| image/jpeg | JPEG image |
| image/png | PNG image |
| image/tiff | TIFF image |
| image/x-xbitmap | X Windows bitmap image |
| text/css | HTML cascading style sheet |
| text/html | HTML document |
| text/plain | Plain text |
| text/xml | XML |
| video/mpeg | MPEG video clip |
| video/quicktime | QuickTime video clip |
| application/msword | Microsoft Word document |
| application/octet-stream | Unrecognized or binary data |
| application/pdf | Acrobat (.pdf) file |
设置响应头的信息
//修改响应头
resp.setHeader("key", "value");
//添加响应头
resp.addHeader("name", "value");
//下面两行代码是等价的
resp.setContentType("text/html;charset=utf-8");//设置响应的数据类型及解码方式
resp.setHeader("Content-Type", "text/html;charset=utf-8");//设置响应的数据类型及解码方式
//向req对象中存储数据
req.setAttribute("key","value");
//从req对象中获取数据
req.getAttribute("key");
//请求转发
req.getRequestDispatcher("/Servlet2").forward(req,resp);
特点:
请求转发是一次请求,地址栏地址不变,还是访问第一个Servlet的地址
请求转发是一次请求,所以转发内的各个Servlet共享一个request对象
请求转发是Tomcat服务器内部的行为,用户是看不到的
可以使用req.setAttribute(key,value)和getAttribute(key)实现请求转发内的Servlet的数据的流转
总结:请求转发可以实现在后端Servlet之间的相互调用,一个请求由一个Servlet处理,转变为了多个Servlet的协同处理。
resp.sendRedirect(req.getContextPath() + "/MainServlet");
特点:
重定向是两次请求,地址栏信息改变,地址会变成第二次请求的地址
重定向的地址是浏览器收到第一次请求响应回来的地址,自动跳转的,用户不参与
重定向的两次请求,request对象是不同的
请求转发是一次请求,是Tomcat服务器内部的行为,共享同一个request对象。浏览器只需要发一次请求即可将业务处理完毕。
重定向是两次请求,地址栏信息会改变。一般用户的增删改请求会使用重定向的方式来处理请求。目的是保护第一次请求,避免用户因刷新页面造成表单重复提交。
总结:不论是请求转发还是请求重定向,都会涉及到多个Servlet。如果你需要将A Servlet的处理结果要带到B Servlet中去使用,那就使用请求转发。如果A Servlet的处理结果不需要带到B Servlet中去使用,那就使用重定向。
浏览器在发起请求的时候,请求达到服务器,服务器认为本次请求携带的数据比较常用,以后的请求也会用得上,那么服务器就会在响应的时候告诉浏览器,把本次请求的数据给保存起来。然后浏览器以后每次发送请求访问服务器的时候都给带上!而存储这样数据的对象就是Cookie。
服务器决定哪些数据是以后的请求也会用到的
服务器以响应的方式告诉浏览器将常用的这些数据存储起来,存储在浏览器端
浏览器以后每次发送请求的时候需要带上这些存储起来的数据
Cookie是浏览器端的数据存储技术
浏览器每次发起请求的时候,请求信息中就包含了Cookie中存储的数据
Cookie不适合大量数据的存储(每个Cookie存储的数据不超过4KB)
不安全,不适合存储重要的数据到浏览器端
//创建Cookie对象
Cookie cookie = new Cookie("username", username);
//将创建好的Cookie对象创建到响应中
resp.addCookie(cookie);//其他servlet获取Cookie
Cookie[] cookies = req.getCookies();/* 设置Cookie对象的存活时间
正数:表示在指定的秒数后过期
负数:表示浏览器一关,Cookie就会被删除(默认是-1)
零:表示马上删除Cookie */
cookie.setMaxAge(60);//设置可以获取到该Cookie对象的路径范围,若abc为文件夹则只有abc下的资源能访问,若abc为一个资源则只有abc资源能访问
cookie.setPath(req.getContextPath()+"/abc");
//设置域名只要是baidu.com结尾的二级域名都可以访问
cookie.setDomain("baidu.com");
解决Http协议无状态,实现方式是将数据存储在服务器的Session对象中,将Session的唯一标识JSESSIONID存储到浏览器中的Cookie对象中;一般只存放用户登录的信息或者错误信息。
Session技术解决用户发送不同请求时数据共享的问题
一个用户在服务器中只会创建一个Session对象。不同用户的Session对象之间是互相独立的
在服务器中创建Session对象,创建完成后会将Session对象的Id(JSESSIONID)以Cookie的形式保存在客户端(浏览器),用户再次发请求时,会携带该Cookie,也就是JSESSIONID到服务器,服务器会根据该id找到用户的Session对象
用户JSESSIONID的Cookie丢失或者服务器中存储的Session对象被销毁,服务器接收到用户的请求后,如果找不到对应的Session对象,会重新创建,并将新的JSESSIONID以Cookie的形式保存到浏览器中
存储JSESSIONID的Cookie不需要手动创建,Session对象创建完成,Tomcat服务器会自动创建Cookie, 将JESSIONID存储在Cookie中响应回浏览器。
Cookie默认的有效期为一次会话,浏览器关闭,Cookie即失效
Session对象在Tomcat服务器的默认有效期为30分钟
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
总结:综上所述,默认情况下,浏览器关闭后Cookie被删除,那么再次访问时就不能对应到Session,如果没有关闭浏览器,但是浏览器30分钟内没有操作,那么该Session对象被销毁了,那么存在浏览器中的Cookie也就失去了意义。
- package com.bjsxt.controller;
-
- import com.bjsxt.pojo.TUser;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
-
- @WebServlet("/test")
- public class TestServlet extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- TUser user = new TUser();
- /*
- * 浏览器第一次请求服务器,Cookie中没有JSESSIONID
- * 执行req.getSession();,会创建Session对象,自动将Session对象得到JSESSIONID以Cookie形式存储到浏览器中,再返回session
- *
- * 浏览器再次请求服务器,Cookie中携带JSESSIONID,
- * 执行req.getSession(),会根据JSESSIONID寻找Session对象
- * 1.找到,直接返回session
- * 2.没找到,会创建Session对象,自动将Session对象得到JSESSIONID以Cookie形式存储到浏览器中,再返回session
- *
- * Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。
- * 用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
- * */
-
- HttpSession session = req.getSession();
-
- //向Session对象中存储数据
- session.setAttribute("user",user);
- //从Session对象中获取数据
- session.getAttribute("user");
- //获取JSESSIONID
- String id = session.getId();
- //获取创建时间
- long creationTime = session.getCreationTime();
- //获取最后一次访问时间
- long lastAccessedTime = session.getLastAccessedTime();
- //设置最大不操作时间,单位是秒
- session.setMaxInactiveInterval(600);
- //获取最大不操作时间
- int maxInactiveInterval = session.getMaxInactiveInterval();
-
- /*
- * 销毁HttpSession对象
- * 1.默认浏览器没有操作30分钟后销毁,可通过配置web.xml文件修改默认销毁的时间
- * <session-config>
- * <!--设置Session的超时时间,单位是分钟-->
- * <session-timeout>10</session-timeout>
- * </session-config>
- * 2.通过invalidate()方法手动销毁
- * */
-
- session.invalidate();
-
- }
- }
Cookie数据存储在客户端,而HttpSession中的数据存储在服务器
Cookie不安全,而HttpSession是安全的
单个cookie保存的数据不能超过4KB,很多浏览器都限制一个域名保存cookie的数量
HttpSession没有容量以及数量的限制, 随着Session中存储的内容增多,会比较占用服务器内存, Session不存放业务数据
Cookie的数据都以字符串的形式保存。Session中可以保存对象
Cookie实现, 如: 记住我 最近浏览商品 网页皮肤 等
Session实现, 如: 登录信息 错误信息 购物车 等
Session依赖于Cookie
存储不同的用户也可能会用到相同的数据。
ServletContext对象由Tomcat服务器在启动加载项目的时候完成创建
ServletContext对象一个项目中只有一个,以任意方式获取到的都是同一个
ServletContext对象中保存的数据是所有共享的
- package com.bjsxt.controller;
-
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
-
- @WebServlet("/contextServlet")
- public class ContextServlet extends HttpServlet {
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- //获取ServletContext对象
- ServletContext servletContext = getServletContext();
- ServletContext servletContext1 = this.getServletContext();
- ServletContext servletContext2 = super.getServletContext();
- ServletContext servletContext3 = req.getServletContext();
- ServletContext servletContext4 = req.getSession().getServletContext();
-
- //往ServletContext对象中存数据,键值对的方式
- servletContext.setAttribute("name", "root");
-
- //从ServletContext对象中获取数据
- String name = (String)servletContext.getAttribute("name");
-
- /*
- * 可以在web.xml中配置一些参数,可以通过ServletContext对象获取。经常出现在框架的底层。
- * <!--配置上下文参数-->
- * <context-param>
- * <param-name>name</param-name>
- * <param-value>admin</param-value>
- * </context-param>
- * */
- String name1 = servletContext.getInitParameter("name");
-
- }
- }
什么是域对象
域对象类似于map集合,可以存放键值对的数据。不同的是域对象中数据的使用有一定的区域范围限制。
三大域对象
request域 对应HttpServeltRequest对象 也叫请求域
Session域 对应HttpSession对象 也叫会话域
application域 对应ServletContext对象 也叫应用域
常用API
setAttribute(key, value) 向域中添加/修改数据,无则添加,有则修改
getAttribute(key) 获取域中的数据
removeAttribute(key) 从域中移除指定key的数据
需要对请求进行相关处理, 处理完成后, 在访问请求的资源。
创建一个类,实现过滤器接口(Filter)
实现接口中的方法,编写自己的代码
在web.xml中配置过滤器或通过注解配置
- package com.bjsxt.controller;
-
- import javax.servlet.*;
- import javax.servlet.annotation.WebFilter;
- import java.io.IOException;
-
- @WebFilter("/*")
- public class CharacterFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
-
- }
-
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- servletRequest.setCharacterEncoding("utf-8");
- servletResponse.setContentType("text/html;charset=utf-8");
- //请求之前会经过
- //放行
- filterChain.doFilter(servletRequest,servletResponse);
- //响应之前会经过
- }
-
- @Override
- public void destroy() {
-
- }
- }
(1)作用
监听三大域对象的创建、销毁及数据的变更。
(2)特点
监听方法由tomcat根据监听结果来调用执行
监听方法中的逻辑代码由我们根据需要编写
(3)使用方式
监听器的使用步骤:
创建一个类,实现监听器接口(Listener)
实现里面的方法
在web.xml中配置监听器或通过注解配置
com.bjsxt.listener.MyListener
@WebListener
监听器接口:
ServletRequestListenter 监听request对象的创建销毁
ServletRequestAttributeListener监听request域中数据的变更
HttpSessionListener 监听Session对象的创建销毁
HttpSessionAttributeListener 监听Session对象中数据的变更
ServletContextListener 监听ServletContext对象的创建销毁
ServletContextAttributeListener监听ServletContext对象中数据的变更
- package com.chen.listener;
-
- import javax.servlet.*;
- import javax.servlet.annotation.WebListener;
- import javax.servlet.http.HttpSessionAttributeListener;
- import javax.servlet.http.HttpSessionBindingEvent;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
-
- @WebListener
- public class MyListener implements ServletRequestListener, ServletRequestAttributeListener,
- HttpSessionListener, HttpSessionAttributeListener, ServletContextListener, ServletContextAttributeListener {
- //监听ServletContext对象中数据的添加
- @Override
- public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
-
- }
- //监听ServletContext对象中数据的删除
- @Override
- public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
-
- }
- //监听ServletContext对象中数据的修改
- @Override
- public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
-
- }
- //监听ServletContext对象的初始化
- @Override
- public void contextInitialized(ServletContextEvent servletContextEvent) {
-
- }
- //监听ServletContext对象的销毁
- @Override
- public void contextDestroyed(ServletContextEvent servletContextEvent) {
-
- }
- //监听ServletRequest对象中数据的添加
- @Override
- public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
- System.out.println("request对象中添加的数据!");
- }
- //监听ServletRequest对象中数据的删除
- @Override
- public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
- System.out.println("request对象中删除了数据!");
- }
- //监听ServletRequest对象中数据的修改
- @Override
- public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
- System.out.println("request对象中修改了数据!");
- }
- //监听ServletRequest对象中数据的销毁
- @Override
- public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
- System.out.println("request对象被销毁!");
- }
- //监听ServletRequest对象的初始化
- @Override
- public void requestInitialized(ServletRequestEvent servletRequestEvent) {
- System.out.println("request对象被初始化!");
- }
- //监听HttpSession对象中数据的添加
- @Override
- public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
-
- }
- //监听HttpSession对象中数据的删除
- @Override
- public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
-
- }
- //监听HttpSession对象中数据的修改
- @Override
- public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
-
- }
- //监听HttpSession对象的创建
- @Override
- public void sessionCreated(HttpSessionEvent httpSessionEvent) {
-
- }
- //监听HttpSession对象的销毁
- @Override
- public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
-
- }
- }