JavaWeb核心

作者: zhl 分类: JavaWeb 发布时间: 2023-10-13 16:41

一、使用Servlet做一个单表的CRUD操作

第一步:创建数据库表
第二步:准备一套HTML页面中的链接,使业务都能跑通,实现页面流转
第三步:分析系统包括的功能(CRUD)
第四步:在IDEA中搭建环境
创建一个webapp,向webapp中添加连接数据库的jar包(放在WEB-INF目录下的lib包内),JDBC工具类
第五步:实现第一个功能:查看部门列表

  • 从前端开始,从用户点击按钮开始
    • 第一:将查看部门列表的超链接修改为请求路径名,请求路径以 / 开始,带上项目名
      <a href="/oa/dept/list">查看部门列表</a>
    • 第二:编写web.xml文件
      <servlet>
      <servlet-name>listDept</servlet-name>
      <servlet-class>com.mysite.oa.web.action.DeptListServlet</servlet-class>
      </servlet>
      <servlet-mapping>
      <servlet-name>listDept</servlet-name>
      <url-pattern>/dept/list</url-pattern>
      </servlet-mapping>
    • 第三:编写DeptListServlet类继承HttpServlet类,重写doGet方法
    • 第四:连接数据库,查询所有的部门,动态的展示部门列表页面
      • 分析list.html页面中哪部分是固定的,哪部分是动态的
    • 第五:实现第一个功能:查看部门列表
    • 第六:查看部门详情功能:
      • 建议:从前端往后端一步一步实现
      • 技巧:将部门编号的信息放在地址栏,在detailDept 中获取地址栏的参数信息即可。这里不能在DeptListServlet 类中设置缓存(应用域或请求域)数据可能不是实时的。
        out.print("<a href='"+contextPath+"/dept/detail?deptno="+deptno+"'>详情</a>");
        //动态获取项目的根路径使用 String contextPath = request.getRequestContextPath();
    • 第七:删除部门
      • 在前端页面上写JS代码,来提示用户是否删除
        
        删除
    • 第八:新增部门
      • 注意:最后保存成功之后,转发到/dept/list的时候,会出现405,为什么?
      • 1.保存用的是post请求,底层要执行doPost方法
      • 2.转发是一次请求,之前是post,之后还是post,因为它是一次请求
      • 3./dept/list Servlet当中只有一个doGet方法
      • 解决方法
      • (1)在/dept/list Servlet中添加doPost方法,然后再doPost方法中调用doGet
      • (2)重定向
    • 第九:跳转到修改部门的页面
    • 第十:修改部门

二、重定向与转发

在web应用中完成资源的跳转有两种方式 转发和重定向

  • 转发:
    //获取请求转发器对象,传入需要转发的Servlet路径,不带项目名
    //转发的时候是一次请求,不管转发多少次,都是一次请求,都在同一个request域中
    request.getRequestDispatcher("/dept/list").forward(request,response);
  • 重定向
    //注意路径上要加一个项目名
    //这里是浏览器向服务器又发送了一个请求  所以 需要加项目名
    response.sendRedirect("/oa/dept/list");

转发和重定向的区别:

  • 转发(一次请求)
    在浏览器地址栏上发送的请求是:http://localhost:8080/servlet09/a,最终请求结束之后,浏览器地址栏上的地址不变。
  • 重定向(两次请求)
    在浏览器地址栏上发送的请求是:http:localhost:8080/servlet09/a,最终在浏览器地址栏上显示的地址是:http:localhost:8080/servlet09/b

转发和重定向的本质区别?

  • 转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。
  • 重定向:是由浏览器来完成的。具体跳转到哪个资源,是由重定向的位置(location)决定的

转发和重定向应该如何选择?

如果在上一个Servlet当中向request域中绑定了数据,希望从下个Servlet当中把request域里面的数据取出来,使用转发机制,剩下的所有请求均使用重定向。(重定向使用较多)

三、会话 (session)

会话(session)指用户打开浏览器,进行一系列操作,最终将浏览器关闭,这整个过程叫做一次会话。一次会话中可以包含多个请求。

由于Http协议是一种无状态协议,所以需要使用session 保存会话状态

无状态指请求的时候,B和S 是连接的,但是请求结束之后,连接(通道)就断了。

为什么不使用request对象保存会话状态?为什么不使用ServletContext对象保存会话状态?

  • ServletContext对象是服务器启动的时候创建的,服务器关闭的时候销毁,这个ServletContext对象只有一个
  • request < session < application (请求域 < 会话域 < 应用域)

session 对象的实现原理

  • HttpSession session = request.getHttpSession();
    • 从服务器中获取当前的session 对象
    • 如果没有获取到任何session对象,则新建
  • HttpSession session = request.getSession(false);
    • 从服务器中获取当前session对象
    • 如果获取不到session,则不会创建,返回一个null

session对象是由服务器创建的,存储在服务器端,Web服务器中有一个session集合,类似于map集合, key对应sessionid, value对应session对象。

session 的创建过程

  • 用户发送第一次请求:服务器会创建一个新的session对象,同时生成一个对应的 sessionid,服务器会将 sessionid 发送给浏览器,浏览器将 sessionid 保存在浏览器的缓存中。
  • 用户发送第二次请求:会自动将浏览器缓存中的 sessionid 自动发送给服务器,服务器获取到的 sessionid,然后从 session 集合中找到对应的 session对象。

为什么关闭浏览器,会话就结束了?

  • 关闭浏览器之后,浏览器缓存中保存的sessionid失效,下次重新打开浏览器之后,浏览器缓存中没有这个sessionid,自然找不到服务器中的session对象。session对象找不到等同于会话结束。

session对象什么时候销毁?

  • 超时销毁
  • 手动销毁

四、Cookie

session 的识别依赖于 Cookie,session 会将 session 对象对应的 sessionid 告诉 Cookie,比如 JSESSIONID=xxx,Cookie 存储了当前 session对象的 sessionid。

Cookie 通常保存在浏览器的运行内存中的,只要浏览器不关闭,用户再次发送请求的时候,会给将运行内存中的 Cookie 一起发送给服务器,服务器是根据JSESSIONID对应的 sessionid 来找到对应的session对象。

Cookie 保存在浏览器上,可以保存在运行内存中。(浏览器关闭cookie就消失了),也可以保存在硬盘文件中(永久保存)。

cookie和session机制都是为了保存会话的状态,因为HTTP协议是无状态协议,所以需要使用session和cookie机制

如果Cookie禁用了,session还能找到吗?

  • Cookie禁用后无法保存sessionid 到浏览器,不能找到对应的 session对象,每次请求都会创建新的 session对象

cookie禁用后,session机制还能实现吗?

  • 可以。需要使用URL重写机制,把 session 信息拼接到 url 路径上,
    如: http://localhost:8080/servlet11/test/session;jsessionid=7ECA8308439C94F9FC6301ACBBF210A

五、过滤器

在项目中每个Servlet执行之前都是需要判断用户是否登录了。判断用户是否登录的代码是固定的,需要在每一个Servlet类中都实现,代码过于冗余,复用性差。可以使用Servle规范中的Filter过滤器来解决。

Filter可以在Servlet这个目标程序执行之前添加代码。也可以在目标Servlet执行之后添加代码。之前之后都可以添加过滤规则。

自定义 Filter过程:

  • 第一步:编写一个java类实现一个接口:javax.servlet.Filter。并且实现这个接口中的所有方法
    • init方法:在Filter对象第一次被创建之后调用,并且只调用一次
    • doFilter方法:只要用户发送一次请求,则执行一次。发送N次请求。则执行N次。在这个方法中编写过滤规则。
    • destroy方法:在Filter方法被释放/销毁之前调用,并且只调用一次.
  • 第二步:在web.xml文件中对Filter进行配置。

注意:

  • Servlet对象默认情况下,在服务器启动的时候不会新建对象。
  • Filter对象默认情况下,在服务器启动的时候会新建对象。
  • Servlet是(伪)单例的。Filter也是单例的。(单实例)

Filter的生命周期和Servlet对象生命周期一致,唯一的区别就是在默认情况下,Filter在服务器启动时就实例化

Filter过滤器的的实现体现了责任链设计模式。在程序编译阶段不会确定调用顺序,因为Filter的调用顺序是配置到web.xml文件中的。只要修改web.xml配置文件中filter-mapping的顺序就可以调整Filter的执行顺序。Filter的执行顺序是在程序运行阶段动态组合的。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注