***Servlet笔记***

Servlet本质

开发步骤
  • 在webapps目录下新建一个目录:(webapp的根)
  • 在webapp的根下新建一个目录:WEB-INF(Servlet规范,必须大写)
  • 在WEB-INF目录下新建一个目录:classes(存放java编译后的class文件)
  • 在WEB-INF目录下新建一个目录:lib(可以存放第三方的jar包)
  • 在WEB-INF目录下新建一个目录:web.xml(必须存在,配置了请求路径和Servlet类之间的对照关系)
  • 编写java小程序,实现Servlet接口(Tomcat服务器实现了Servlet规范,Servlet接口不在JDK当中,是Oracle提供的,是JavaEE规范中的一员)从JakartaEE9开始,Servlet接口的全名变为:jakarta.servlet.Servlet
Servlet规范
  • 规范了哪些接口
  • 规范了哪些类
  • 规范了一个web应用中应该有哪些配置文件
  • 规范了一个web应用中配置文件的名字
  • 规范了一个web应用中配置文件存放的目录
  • 规范了一个web应用中配置文件的内容
  • 规范了一个合法有效的web应用他的目录结构应该是怎样的
Servlet对象的生命周期
          什么是Servlet对象的生命周期

                * Servlet对象什么时候被创建
                * Servlet对象什么时候被创建
                * Servlet对象创建了几个
                * Servlet对象的生命周期:Servlet对象从出生到死亡

          Servlet对象是由谁来维护的

                * Servlet对象的创建,对象上方法的调用,对象的销毁,Javaweb程序员是无法干涉的
                * Servlet对象的生命周期是由Tomcat服务器(WEB Servlet:WEB容器)全权负责
                * 自己创建的Servlet对象是不受WEB容器管理的

          Servlet对象的创建

                * 默认情况下,服务器在启动时Servlet并不会被实例化,当用户发送第一次请求时Servlet对象被创建(这个设计是合理的,如果提前创建会消耗内存,并且创建出来的Servlet一直不进行访问,就没有用处)
                * Servlet对象被创建出来以后,Tomcat服务器马上调用Servlet对象的init()方法,然后马上调用service()方法
                * 让服务器启动的时候创建Servlet对象,就必须添加0,标签中的整数越小,优先级越高,越早创建
                * 用户再次请求时,Servlet对象不会新建,直接用创建好的Servlet对象调用service()方法
                        1.Servlet是单实例的,但Servlet类并不符合单例模式,是假单例(Tomcat只创建了一个,所以导致单例。真单例模式构造方法是私有化的)
                        2.无参数构造方法,init方法只在第一次用户发送请求的时候执行,也就是说无参构造只执行一次,init方法也只被Tomcat调用一次
                * Servlet的无参构造器和init方法都是在第一次创建的时候被创建且调用一次,但并不可用无参构造代替init方法因为:Servlet规范中不建议手动编写构造方法,因为很容易让无参构造方法消失,可能会导致Servlet对象无法实例化,所以init存在是有必要的

          Servlet对象的销毁

                * Servlet的destroy方法制备Tomcat服务器调用一次
                * 在服务器关闭的时候要销毁Servlet对象的内存,在销毁之前,Tomcat会自动调用Servlet对象的destroy方法

          Servlet对象的使用

                * init方法:通常做初始化操作,并且只需执行一次
                * service方法:处理用户请求的核心方法
                * destroy方法:进行资源的关闭,资源保存

存在问题
@Override
public void init(ServletConfig servletConfig) throws ServletException {}

@Override
public ServletConfig getServletConfig() {return null;}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse)
       throws ServletException, IOException {}

@Override
public String getServletInfo() {return null;}

@Override
public void destroy() {}

这五个方法在每次实现时都需要重写,但我们只需要service方法
——————————————————————————————————————————————

解决办法(GenericServlet抽象类,有一个抽象方法service)
  • 实现Servlet接口,是一个适配器,以后的Servlet继承GenericServlet,只需重写service方法
public class ServletStart extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) 
            throws ServletException, IOException {}
}
  • Tomcat服务器创建了ServletConfig对象,调用init方法,将ServletConfig对象传给init方法
public void init(ServletConfig config) throws ServletException {
    this.config = config;
}
  • 但是重写了init方法后config可能会为空
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

public void init() throws ServletException {
}
  • 以后重写的都是无参的init方法
ServletConfig
  • ServletConfig是一个接口,Servlet规范中的一员,Tomcat服务器实现了ServletConfig接口
  • 一个Servlet对象只有一个ServletConfig对象,ServletConfig是Servlet对象的配置信息对象,一个Servlet对象就有一个配置信息对象
  • ServletConfig对象中封装了标签中的配置信息
  • ServletConfig接口中的方法
String getServletName();

ServletContext getServletContext();

String getInitParameter(String var1);

Enumeration<String> getInitParameterNames();
  • 以上方法在Servlet类当中,都可以使用this调用,因为GenericServlet实现了ServletConfig接口
ServletContext(应用域)
  • 一个Servlet对象对应一个ServletConfig,但在同一个webapp中,只要在同一个应用,所有的Servlet对象都共享同一个ServletContext对象
  • ServletContext对象在服务期启动阶段创建,在服务器关闭的时候销毁,是应用级对象
  • ServletContext对象被称为Servlet上下文对象(Servlet对象的四周环境对象)
  • 一个ServletContext对象通常对应一个web.xml文件
  • ServletContext是一个接口,Tomcat服务器对ServletContext接口进行实现
  • ServletContext常用方法
String getInitParameter(String var1);//通过初始化参数的name获取value

Enumeration<String> getInitParameterNames();//获取初始化参数的name

String getContextPath();//动态获取应用的根路径

String getRealPath(String var1);//获取文件的绝对路径
  • 如果所有的用户共享一份数据,并且这个数据很少被修改,数据量很少,可以放在ServletContext域中
    1.不是共享的没有意义,只有共享的数据放进去才有意义
    2.数据量太大的话,太占用堆内存,并且这个对象的生命周期比较长,服务器关闭时,对象才会被销毁,大量数据会影响服务器的性能
    3.共享数据,如果涉及修改,必然会存在线程并发所带来的安全问题
PrintWriter out = servletResponse.getWriter();
out.print(servletConfig);//org.apache.catalina.core.StandardWrapperFacade@33914ac2
ServletContext servletContext = this.getServletContext();
out.print(servletContext);//org.apache.catalina.core.ApplicationContextFacade@3d56a2c0

在编写Servlet类的时候,实际上是不会直接继承GenericServlet的,基于HTTP传输协议,在Servlet规范中,提供了HttpServlet,我们编写的Servlet要继承HttpServlet

public interface Servlet(接口)
public abstract class GenericServlet implements Servlet(抽象类)
public abstract class HttpServlet extends GenericServlet(抽象类)
HTTP协议
  • 协议:一套规范,就是一套标准
  • HTTP协议:W3C(万维网联盟组织)制定的一种超文本传输协议(通信协议:发送消息的模板提前被创建好)
  • 超文本:不是普通文本,比如:声音,视频,图片等
  • 浏览器 —> WEB服务器:请求(request)
  • WEB服务器 —> 浏览器:响应(response)
HTTP的请求协议(B–>S)
  • 请求包括:请求行,请求头,空白行,请求体
  • 请求行
    1.第一部分:请求方式
               get ,post ,delete ,put ,head ,options ,trace
    2.第二部分:URI
               URI:统一资源标识符。代表某个资源的名字,无法定位资源
               URL:统一资源定位符。代表某个资源,可以定位资源(包括URI)
    3.第三部分:HTTP协议版本号
  • 请求头
        请求的主机,主机的端口,浏览器信息,平台信息等
  • 空白行:区分请求头与请求体
  • 请求体:向服务器发送的具体数据
HTTP的响应协议(S–>B)
  • 响应包括:状态行,响应头,空白行,响应体
  • 状态行
    1.第一部分:协议版本号(HTTP/1.1)
    2.第二部分:状态码(不同的响应结果对应不同的码)
               200:响应成功,正常结束
               404:访问资源不存在,路径错误或者没有对应资源
               405:前端发送的请求方式与后端请求处理的方式不一致
               500:服务器端的错误
    3.第三部分:状态的描述信息
  • 响应头
        响应的内容类型,内容长度,时间等
  • 空白行:区分响应头与响应体
  • 响应体:响应的正文,长字符串,会被浏览器渲染,解释并执行
发送请求
  • 到目前为止,只有在form表单上设置method="post"时,才能发送post请求
  • 在地址栏输入url,点击超链接,method=“get”…发送get请求
  • get与post区别
        get请求发送的数据会显示在浏览器上(get在请求头上发送数据)
        post请求发送数据在请求体中发送,不会回显在浏览器的的地址栏是上
        get只能发送普通的字符串,长度有限制,无法发送大数据量,比较适合从服务器端获取数据
        post可以发送任何类型的数据,大数据量,适合向服务器获取数据
HttpServlet
  • HttpServlet是专门为HTTP协议准备的
  • HttpServlet对象中封装了:HttpServletRequest,HttpServletResponse(封装了请求协议中的全部内容)
  • Tomcat服务器将请求协议中的数据全部解析出来,封装到request对象
    WEB-INF:存放的资源是受保护的,不能在浏览器上通过路径直接访问
HttpServletRequest接口
  • HttpServletRequest接口是Servlet规范中的一员
  • HttpServletRequest接口的父接口:ServletRequest
public interface HttpServletRequest extends ServletRequest{}
  • Tomcat服务器实现了HttpServletRequest接口,封装了HTTP的请求协议
  • request对象只在当前请求中有效,一次请求对应一个request
  • 常用方法
String getParameter(String var1);//获取这个一维数组的第一个元素

Enumeration<String> getParameterNames();//获取Map集合中的所有Key

String[] getParameterValues(String var1);//根据key获取Map集合中的value

Map<String, String[]> getParameterMap();//获取Map
两个Servlet共享数据
  • 将数据放到ServletContext应用域当中,但是范围太大,占用资源太多,不建议
  • 将数据放到request域当中,使用转发(转发的下一个资源不一定是Servlet,只要是合法资源,都可以跳转)
  • 转发时不加项目名,以"/"开始
String getParameter(String var1);//获取用户在浏览器上提交的数据

Object getAttribute(String var1);//获取请求域当中绑定的数据
req.getRemoteAddr();//获取客户端IP地址
req.setCharacterEncoding("UTF-8");//设置字符集
req.getContextPath();//获取应用的根路径
req.getMethod();//获取请求方式
req.getServletPath();//获取Servlet路径
资源跳转

转发 ,重定向

  • 转发(一次请求)
req.getRequestDispatcher(req.getServletPath()).forward(req,resp);
//转发是一次请求,都在同一个request当中
//调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet
  • 重定向(两次请求)
resp.sendRedirect(req.getContextPath()+req.getServletPath());
//请求路径要添加项目名,浏览器会自发地向服务器发送一次全新的请求
  • 本质区别
    1.转发:由WEB服务器控制,跳转由Tomcat服务器内部完成
    2.重定向:浏览器完成
  • 如果Servlet当中向request域当中绑定了数据,希望从下一个Servlet中把request域里面的数据取出来,使用转发,其余使用重定向
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值