• Servlet详解


    一、Servlet的生命周期

    (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的创建与初始化的时机有两个:

    1. Servlet在第一次被浏览器访问的时候创建与初始化的(目前我们的代码用的就是这种方式,默认就是这种)

    2. Servlet在启动服务器的时候被创建与初始化的(该方式需要做一些配置,告诉Tomcat服务器在启动的时候就创建Servlet对象)

    问题4:Servlet对象什么时候销毁?

    Servlet对象是由Tomcat服务器创建的,之后就一直驻留在内存中处理请求。直到服务器停止后,Servlet才会被销毁!

    二、web.xml配置Servlet的几种方式

            
            /UserServlet

           
            *.do

           
            /user/UserServlet

           
            /*

           
            /

            

            
                hello.html
            

    三、HttpServletResponse的使用

    (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");

    TypeMeaning
    application/postscriptPostScript file
    application/vnd.lotus-notesLotus Notes file
    application/vnd.ms-excelExcel spreadsheet
    application/vnd.ms-powerpointPowerPoint presentation
    application/x-gzipGzip archive
    application/x-java-archiveJAR file
    application/x-java-serialized-objectSerialized Java object
    application/x-java-vmJava bytecode (.class) file
    application/zipZip archive
    audio/basicSound file in .au or .snd format
    audio/midiMIDI sound file
    audio/x-aiffAIFF sound file
    audio/x-wavMicrosoft Windows sound file
    image/gifGIF image
    image/jpegJPEG image
    image/pngPNG image
    image/tiffTIFF image
    image/x-xbitmapX Windows bitmap image
    text/cssHTML cascading style sheet
    text/htmlHTML document
    text/plainPlain text
    text/xmlXML
    video/mpegMPEG video clip
    video/quicktimeQuickTime video clip
    application/mswordMicrosoft Word document
    application/octet-streamUnrecognized or binary data
    application/pdfAcrobat (.pdf) file

    四、HttpServletResponse的使用

     设置响应头的信息

    //修改响应头

    resp.setHeader("key", "value");

    //添加响应头

    resp.addHeader("name", "value");

    //下面两行代码是等价的
    resp.setContentType("text/html;charset=utf-8");//设置响应的数据类型及解码方式
    resp.setHeader("Content-Type", "text/html;charset=utf-8");//设置响应的数据类型及解码方式

    五、请求转发和请求重定向

    (1)请求转发

    //向req对象中存储数据

    req.setAttribute("key","value");

    //从req对象中获取数据

    req.getAttribute("key");

    //请求转发

    req.getRequestDispatcher("/Servlet2").forward(req,resp);

    特点:

    1. 请求转发是一次请求,地址栏地址不变,还是访问第一个Servlet的地址

    2. 请求转发是一次请求,所以转发内的各个Servlet共享一个request对象

    3. 请求转发是Tomcat服务器内部的行为,用户是看不到的

    4. 可以使用req.setAttribute(key,value)和getAttribute(key)实现请求转发内的Servlet的数据的流转

     总结:请求转发可以实现在后端Servlet之间的相互调用,一个请求由一个Servlet处理,转变为了多个Servlet的协同处理。

    (2)请求重定向

    resp.sendRedirect(req.getContextPath() + "/MainServlet");

    特点:

    1. 重定向是两次请求,地址栏信息改变,地址会变成第二次请求的地址

    2. 重定向的地址是浏览器收到第一次请求响应回来的地址,自动跳转的,用户不参与

    3. 重定向的两次请求,request对象是不同的

    (3)转发和重定向的区别

    请求转发是一次请求,是Tomcat服务器内部的行为,共享同一个request对象。浏览器只需要发一次请求即可将业务处理完毕。

    重定向是两次请求,地址栏信息会改变。一般用户的增删改请求会使用重定向的方式来处理请求。目的是保护第一次请求,避免用户因刷新页面造成表单重复提交。

    总结:不论是请求转发还是请求重定向,都会涉及到多个Servlet。如果你需要将A Servlet的处理结果要带到B Servlet中去使用,那就使用请求转发。如果A Servlet的处理结果不需要带到B Servlet中去使用,那就使用重定向。

    六、Cookie对象

    (1)用处

    浏览器在发起请求的时候,请求达到服务器,服务器认为本次请求携带的数据比较常用,以后的请求也会用得上,那么服务器就会在响应的时候告诉浏览器,把本次请求的数据给保存起来。然后浏览器以后每次发送请求访问服务器的时候都给带上!而存储这样数据的对象就是Cookie。

    (2)总结

    1. 服务器决定哪些数据是以后的请求也会用到的

    2. 服务器以响应的方式告诉浏览器将常用的这些数据存储起来,存储在浏览器端

    3. 浏览器以后每次发送请求的时候需要带上这些存储起来的数据

     (3)性质

    1. Cookie是浏览器端的数据存储技术

    2. 浏览器每次发起请求的时候,请求信息中就包含了Cookie中存储的数据

    3. Cookie不适合大量数据的存储(每个Cookie存储的数据不超过4KB)

    4. 不安全,不适合存储重要的数据到浏览器端

     (4)使用方式

    //创建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");

    七、HttpSession对象

    (1)作用

    解决Http协议无状态,实现方式是将数据存储在服务器的Session对象中,将Session的唯一标识JSESSIONID存储到浏览器中的Cookie对象中;一般只存放用户登录的信息或者错误信息。

    (2)特点

    1. Session技术解决用户发送不同请求时数据共享的问题

    2. 一个用户在服务器中只会创建一个Session对象。不同用户的Session对象之间是互相独立的

    3. 在服务器中创建Session对象,创建完成后会将Session对象的Id(JSESSIONID)以Cookie的形式保存在客户端(浏览器),用户再次发请求时,会携带该Cookie,也就是JSESSIONID到服务器,服务器会根据该id找到用户的Session对象

    4. 用户JSESSIONID的Cookie丢失或者服务器中存储的Session对象被销毁,服务器接收到用户的请求后,如果找不到对应的Session对象,会重新创建,并将新的JSESSIONID以Cookie的形式保存到浏览器中

    5. 存储JSESSIONID的Cookie不需要手动创建,Session对象创建完成,Tomcat服务器会自动创建Cookie, 将JESSIONID存储在Cookie中响应回浏览器。

    6. Cookie默认的有效期为一次会话,浏览器关闭,Cookie即失效

    7. Session对象在Tomcat服务器的默认有效期为30分钟

    8. Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。

    总结:综上所述,默认情况下,浏览器关闭后Cookie被删除,那么再次访问时就不能对应到Session,如果没有关闭浏览器,但是浏览器30分钟内没有操作,那么该Session对象被销毁了,那么存在浏览器中的Cookie也就失去了意义。

    (3)使用方式

    1. package com.bjsxt.controller;
    2. import com.bjsxt.pojo.TUser;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. import java.io.IOException;
    10. @WebServlet("/test")
    11. public class TestServlet extends HttpServlet {
    12. @Override
    13. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    14. TUser user = new TUser();
    15. /*
    16. * 浏览器第一次请求服务器,Cookie中没有JSESSIONID
    17. * 执行req.getSession();,会创建Session对象,自动将Session对象得到JSESSIONID以Cookie形式存储到浏览器中,再返回session
    18. *
    19. * 浏览器再次请求服务器,Cookie中携带JSESSIONID,
    20. * 执行req.getSession(),会根据JSESSIONID寻找Session对象
    21. * 1.找到,直接返回session
    22. * 2.没找到,会创建Session对象,自动将Session对象得到JSESSIONID以Cookie形式存储到浏览器中,再返回session
    23. *
    24. * Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。
    25. * 用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
    26. * */
    27. HttpSession session = req.getSession();
    28. //向Session对象中存储数据
    29. session.setAttribute("user",user);
    30. //从Session对象中获取数据
    31. session.getAttribute("user");
    32. //获取JSESSIONID
    33. String id = session.getId();
    34. //获取创建时间
    35. long creationTime = session.getCreationTime();
    36. //获取最后一次访问时间
    37. long lastAccessedTime = session.getLastAccessedTime();
    38. //设置最大不操作时间,单位是秒
    39. session.setMaxInactiveInterval(600);
    40. //获取最大不操作时间
    41. int maxInactiveInterval = session.getMaxInactiveInterval();
    42. /*
    43. * 销毁HttpSession对象
    44. * 1.默认浏览器没有操作30分钟后销毁,可通过配置web.xml文件修改默认销毁的时间
    45. * <session-config>
    46. * <!--设置Session的超时时间,单位是分钟-->
    47. * <session-timeout>10</session-timeout>
    48. * </session-config>
    49. * 2.通过invalidate()方法手动销毁
    50. * */
    51. session.invalidate();
    52. }
    53. }

    (4)Cookie和Session的区别

    1. Cookie数据存储在客户端,而HttpSession中的数据存储在服务器

    2. Cookie不安全,而HttpSession是安全的

    3. 单个cookie保存的数据不能超过4KB,很多浏览器都限制一个域名保存cookie的数量

      HttpSession没有容量以及数量的限制, 随着Session中存储的内容增多,会比较占用服务器内存, Session不存放业务数据

    4. Cookie的数据都以字符串的形式保存。Session中可以保存对象

    5. Cookie实现, 如: 记住我 最近浏览商品 网页皮肤 等

    6. Session实现, 如: 登录信息 错误信息 购物车 等

    7. Session依赖于Cookie

     八、ServletContext对象

    (1)作用

    存储不同的用户也可能会用到相同的数据。

    (2)特点

    1. ServletContext对象由Tomcat服务器在启动加载项目的时候完成创建

    2. ServletContext对象一个项目中只有一个,以任意方式获取到的都是同一个

    3. ServletContext对象中保存的数据是所有共享的

    (3)使用方式

    1. package com.bjsxt.controller;
    2. import javax.servlet.ServletContext;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import java.io.IOException;
    9. @WebServlet("/contextServlet")
    10. public class ContextServlet extends HttpServlet {
    11. @Override
    12. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. //获取ServletContext对象
    14. ServletContext servletContext = getServletContext();
    15. ServletContext servletContext1 = this.getServletContext();
    16. ServletContext servletContext2 = super.getServletContext();
    17. ServletContext servletContext3 = req.getServletContext();
    18. ServletContext servletContext4 = req.getSession().getServletContext();
    19. //往ServletContext对象中存数据,键值对的方式
    20. servletContext.setAttribute("name", "root");
    21. //从ServletContext对象中获取数据
    22. String name = (String)servletContext.getAttribute("name");
    23. /*
    24. * 可以在web.xml中配置一些参数,可以通过ServletContext对象获取。经常出现在框架的底层。
    25. * <!--配置上下文参数-->
    26. * <context-param>
    27. * <param-name>name</param-name>
    28. * <param-value>admin</param-value>
    29. * </context-param>
    30. * */
    31. String name1 = servletContext.getInitParameter("name");
    32. }
    33. }

    九、域对象

    什么是域对象

    域对象类似于map集合,可以存放键值对的数据。不同的是域对象中数据的使用有一定的区域范围限制。

    三大域对象

    request域        对应HttpServeltRequest对象   也叫请求域

    Session域       对应HttpSession对象               也叫会话域

    application域   对应ServletContext对象          也叫应用域

    常用API

    setAttribute(key, value) 向域中添加/修改数据,无则添加,有则修改

    getAttribute(key) 获取域中的数据

    removeAttribute(key) 从域中移除指定key的数据

    十、过滤器(Filter)

    (1)使用场景

     需要对请求进行相关处理, 处理完成后, 在访问请求的资源。

    (2)使用方式

    1. 创建一个类,实现过滤器接口(Filter)

    2. 实现接口中的方法,编写自己的代码

    3. 在web.xml中配置过滤器或通过注解配置

    1. package com.bjsxt.controller;
    2. import javax.servlet.*;
    3. import javax.servlet.annotation.WebFilter;
    4. import java.io.IOException;
    5. @WebFilter("/*")
    6. public class CharacterFilter implements Filter {
    7. @Override
    8. public void init(FilterConfig filterConfig) throws ServletException {
    9. }
    10. @Override
    11. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    12. servletRequest.setCharacterEncoding("utf-8");
    13. servletResponse.setContentType("text/html;charset=utf-8");
    14. //请求之前会经过
    15. //放行
    16. filterChain.doFilter(servletRequest,servletResponse);
    17. //响应之前会经过
    18. }
    19. @Override
    20. public void destroy() {
    21. }
    22. }

    十一、 监听器(Listener)

    (1)作用

    监听三大域对象的创建、销毁及数据的变更。

    (2)特点

    1. 监听方法由tomcat根据监听结果来调用执行

    2. 监听方法中的逻辑代码由我们根据需要编写

    (3)使用方式 

    监听器的使用步骤:

    1. 创建一个类,实现监听器接口(Listener)

    2. 实现里面的方法

    3. 在web.xml中配置监听器或通过注解配置



        com.bjsxt.listener.MyListener

    @WebListener

    监听器接口:

    1. ServletRequestListenter 监听request对象的创建销毁

    2. ServletRequestAttributeListener监听request域中数据的变更

    3. HttpSessionListener 监听Session对象的创建销毁

    4. HttpSessionAttributeListener 监听Session对象中数据的变更

    5. ServletContextListener 监听ServletContext对象的创建销毁

    6. ServletContextAttributeListener监听ServletContext对象中数据的变更

    1. package com.chen.listener;
    2. import javax.servlet.*;
    3. import javax.servlet.annotation.WebListener;
    4. import javax.servlet.http.HttpSessionAttributeListener;
    5. import javax.servlet.http.HttpSessionBindingEvent;
    6. import javax.servlet.http.HttpSessionEvent;
    7. import javax.servlet.http.HttpSessionListener;
    8. @WebListener
    9. public class MyListener implements ServletRequestListener, ServletRequestAttributeListener,
    10. HttpSessionListener, HttpSessionAttributeListener, ServletContextListener, ServletContextAttributeListener {
    11. //监听ServletContext对象中数据的添加
    12. @Override
    13. public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
    14. }
    15. //监听ServletContext对象中数据的删除
    16. @Override
    17. public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
    18. }
    19. //监听ServletContext对象中数据的修改
    20. @Override
    21. public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
    22. }
    23. //监听ServletContext对象的初始化
    24. @Override
    25. public void contextInitialized(ServletContextEvent servletContextEvent) {
    26. }
    27. //监听ServletContext对象的销毁
    28. @Override
    29. public void contextDestroyed(ServletContextEvent servletContextEvent) {
    30. }
    31. //监听ServletRequest对象中数据的添加
    32. @Override
    33. public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    34. System.out.println("request对象中添加的数据!");
    35. }
    36. //监听ServletRequest对象中数据的删除
    37. @Override
    38. public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    39. System.out.println("request对象中删除了数据!");
    40. }
    41. //监听ServletRequest对象中数据的修改
    42. @Override
    43. public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    44. System.out.println("request对象中修改了数据!");
    45. }
    46. //监听ServletRequest对象中数据的销毁
    47. @Override
    48. public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
    49. System.out.println("request对象被销毁!");
    50. }
    51. //监听ServletRequest对象的初始化
    52. @Override
    53. public void requestInitialized(ServletRequestEvent servletRequestEvent) {
    54. System.out.println("request对象被初始化!");
    55. }
    56. //监听HttpSession对象中数据的添加
    57. @Override
    58. public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
    59. }
    60. //监听HttpSession对象中数据的删除
    61. @Override
    62. public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
    63. }
    64. //监听HttpSession对象中数据的修改
    65. @Override
    66. public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
    67. }
    68. //监听HttpSession对象的创建
    69. @Override
    70. public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    71. }
    72. //监听HttpSession对象的销毁
    73. @Override
    74. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    75. }
    76. }
  • 相关阅读:
    笙默考试管理系统-SMExamination.Model.Notice展示
    Github的一个奇技淫巧
    你真的会使用PDF注释功能吗?PDF注释功能正确使用方法
    C++基础语法——类和对象
    清能股份2MW热电联供系统成功下线
    VM虚拟机三种网络配置详解(桥接、NAT、仅主机)
    Spring Cloud Gateway3.x自定义Spring Cloud Loadbalancer负载均衡策略以及实现动态负载均衡策略的方案
    中南林业科技大学数据库实验七:存储过程和触发器
    maven中 depedencyManagement的作用
    js 阻止事件冒泡
  • 原文地址:https://blog.csdn.net/weixin_53455615/article/details/126828151