03_servlet

Servlet

B站-动力节点课程笔记

Servlet规范

  1. servlet规范来自于JAVAEE规范中的一种
  2. 作用:
    1. 在Servlet规范中,指定【动态资源文件】开发步骤
    2. 在Servlet规范中,指定Http服务器调用动态资源文件规则
    3. 在Servlet规范中,指定Http服务器管理动态资源文件实例对象规则

Servlet接口实现类

  1. Servlet接口来自于Servlet规范下一个接口,这个接口存在Http服务器所提供jar包中
  2. Tomcat服务器下lib文件有一个servlet-api.jar存放Servlet接口(javax.servlet.Servlet接口)
  3. 只有Servlet接口的实现类才是动态资源文件

Servlet接口内容:

image-20210226142302312

Servlet继承关系

image-20210226130105170

Servlet接口实现开发步骤

实现Servlet步骤:

第一步:创建一个Java类继承HttpServlet父类,使之成为一个Servlet接口实现类

第二步:重写HttpServlet父类两个方法。doGetdoPost

至于何时调用上面的方法,父类HttpServlet中的service方法已经处理了。(模板设计模式)

第三步:将Servlet接口实现类信息注册到Tomcat服务器

注册:就是告诉Tomcat,哪些是动态资源文件。并把文件交给Tomcat管理。

网站
web
WEB-INF
web.xml
<servlet>
    <!--声明一个变量存储servlet接口实现类类路径-->
    <servlet-name>oneServlet</servlet-name>
    <!--声明servlet接口实现类类路径-->
    <servlet-class>com.OneServlet</servlet-class>
</servlet>

<!--为了降低用户访问Servlet接口实现类难度,需要设置简短请求别名-->
<servlet-mapping>
    <servlet-name>oneServlet</servlet-name>
    <url-pattern>/one</url-pattern><!--设置简短请求别名,别名在书写时必须以"/"为开头-->
</servlet-mapping>

现在浏览器向Tomcat索要OneServlet时地址
http://localhost:8080/myWeb/one

Tomcat调用Servlet实现类:

  1. Tomcat有权创建Servlet接口实现类实例对象
  2. Tomcat调用实例对象的service方法
OneServlet oneServlet = new OneServlet();
oneServlet.service();

Servlet对象生命周期:

  1. 网站中所有的Servlet接口实现类的实例对象,只能由Http服务器负责额创建。开发人员不能手动创建Servlet接口实现类的实例对象。

    • 默认情况下,Http服务器接收到对于当前Servlet接口实现类第一次请求时自动创建这个Servlet接口实现类的实例对象。
    • 手动配置情况下,要求Http服务器在启动时自动创建某个Servlet接口实现类的实例对象。
<servlet>
<servlet-name>mm</servlet-name> <!--声明一个变量存储servlet接口实现类类路径-->
<servlet-class>com.bjpowernode.controller.OneServlet</servlet-class>
<load-on-startup>30<load-on-startup><!--填写一个大于0的整数即可-->
</servlet>
  1. 在Http服务器运行期间,一个Servlet接口实现类只能创建出一个实例对象

  2. 在Http服务器关闭时刻,自动将网站中所有的Servlet对象进行销毁

HttpServletResponse接口【响应对象】

介绍:

  1. HttpServletResponse接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar
  2. HttpServletResponse接口实现类由Http服务器负责提供
  3. HttpServletResponse接口负责将doGet/doPost方法执行**结果写入到【响应体】**交给浏览器。
  4. 开发人员习惯于将HttpServletResponse接口修饰的对象称为==【响应对象】==

主要功能:

  1. 将执行结果以二进制形式写入到【响应体】
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    int result = 50;
    // 1.通过响应对象,向Tomcat取得输出流
    PrintWriter writer = response.getWriter();
    // 2.通过输出流,将执行结果写入到输出流
    writer.print(result);
}

  1. 设置响应头中【content-type】属性值,从而控制浏览器使用对应编译器将响应体二进制数据编译为【文字,图片,视频,命令】
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String resul = "aa<br>bb<br>cc";

    // 设置响应头ContentType为html
    response.setContentType("text/html");

    // 用输出流输出
    PrintWriter writer = response.getWriter();
    writer.print(resul);
}

  1. 设置响应头中【location】属性,将一个请求地址赋值给location从而控制浏览器向指定服务器发送请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String result = "www.baidu.com";
    response.sendRedirect(result);		//[响应头 ocation="http://www.baidu.com"]
}

HttpServletRequest接口【请求对象】

介绍:

  1. HttpServletRequest接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar
  2. HttpServletRequest接口实现类由Http服务器负责提供
  3. HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中信息
  4. 开发人员习惯于将HttpServletRequest接口修饰的对象称为==【请求对象】==

主要作用:

  1. 可以读取Http请求协议包中【请求行】信息

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.通过请求对象,读取【请求行】中【url】信息
        String url = req.getRequestURL().toString();
    
        //2.通过请求对象,读取【请求行】中【method】信息
        String method = req.getMethod();
    
        //3.通过请求对象,读取【请求行】中uri信息
        /*
         * URI:资源文件精准定位地址,在请求行并没有URI这个属性。
         *      实际上URL中截取一个字符串,这个字符串格式"/网站名/资源文件名"
         *      URI用于让Http服务器对被访问的资源文件进行定位
         */
        String uri = req.getRequestURI();
    
        System.out.println("URL " + url);
        System.out.println("method " + method);
        System.out.println("URI " + uri);
    }
    /*
    URL http://localhost:8080/05/one
    method GET
    URI /05/one
    */
    
  2. 可以读取保存在Http请求协议包中【请求头】或【请求体】中请求参数信息

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  // 1.通过请求对象获得请求头中所有请求参数名称
  String username = req.getParameter("username");
  System.out.println("get: username = " + username);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  // 设置post方式解析用的字符集
  req.setCharacterEncoding("utf-8");
  String username = req.getParameter("username");
  System.out.println("post: username = " + username);
}
  1. 可以代替浏览器向Http服务器申请资源文件调用

post和get传递参数对比

postget
参数保存在请求体参数保存在请求头
默认使用【ISO-8859-1】字符集(中文乱码)默认使用【utf-8】字符集
参数不显示在url中参数显示在url中
  • post中文乱码解决方法:

    在读取请求体之前,通知请求体使用utf-8对请求体内容重新解码

请求对象&响应对象生命周期

image-20210301000710318

  1. 在Http服务器接收到浏览器发送的Http请求协议包之后,自动为当前的【Http请求协议包】生成一个【请求对象】和一个【响应对象】
  2. 在Http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行。
  3. 在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】销毁
  4. 【请求对象】和【响应对象】生命周期贯穿一次请求的处理过程
  5. 【请求对象】和【响应对象】相当于用户在服务端的代言人

欢迎资源文件

默认欢迎资源文件:

用户发送了一个针对某个网站的【默认请求】时,

此时由Http服务器自动从当前网站返回的资源文件

正常请求: http://localhost:8080/myWeb/index.html

默认请求: http://localhost:8080/myWeb/

Tomcat对于默认欢迎资源文件定位规则

  1. 规则位置:Tomcat安装位置/conf/web.xml

  2. 规则命令:

    <!-- ==================== Default Welcome File List ===================== -->
    <!-- When a request URI refers to a directory, the default servlet looks  -->
    <!-- for a "welcome file" within that directory and, if present, to the   -->
    <!-- corresponding resource URI for display.                              -->
    <!-- If no welcome files are present, the default servlet either serves a -->
    <!-- directory listing (see default servlet configuration on how to       -->
    <!-- customize) or returns a 404 status, depending on the value of the    -->
    <!-- listings setting.                                                    -->
    <!--                                                                      -->
    <!-- If you define welcome files in your own application's web.xml        -->
    <!-- deployment descriptor, that list *replaces* the list configured      -->
    <!-- here, so be sure to include any of the default values that you wish  -->
    <!-- to use within your application.                                       -->
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    

设置当前网站的默认欢迎资源文件规则

  1. 规则位置:WEB-INF/web.xml

  2. 规则命令:

    <!--自定义默认欢迎文件-->
    <welcome-file-list>
        <welcome-file>user/find</welcome-file><!--动态资源文件做默认欢迎文件-->
    	<welcome-file>login.html</welcome-file>
    </welcome-file-list>
    

http状态码

02_HTTP服务器.md 的内容相同

介绍:

  1. 由三位数字组成的一个符号。

  2. Http服务器在推送响应包之前,根据本次请求处理情况
    将Http状态码写入到响应包中【状态行】上

  3. 如果Http服务器针对本次请求,返回了对应的资源文件。
    通过Http状态码通知浏览器应该如何处理这个结果如果Http服务器针对本次请求,无法返回对应的资源文件
    通过Http状态码向浏览器解释不能提供服务的原因

分类:(100—599;分为5个大类)

  1. 1XX(100)

    最有特征 100;通知浏览器本次返回的资源文件,不是一个独立的资源文件,需要浏览器在接收响应包之后,继续向Http服务器索要依赖的其他资源文件。

  2. 2XX(200)

    最有特征200,通知浏览器本次返回的资源文件是一个完整独立资源文件,浏览器在接收到之后不需要索要其他关联文件。(一切正常)

  3. 3xx(302)

    通知浏览器本次返回的不是一个资源文件内容而是一个资源文件地址,需要浏览器根据这个地址自动发起请求来索要这个资源文件

    8 response, sendRedirect("资源文件地址") // 写入到响应头中location
    // 而这个行为导致Tomcat将302状态码写入到状态行
    
  4. 4XX

    404:通知浏览器,由于在服务端没有定位到被访问的资源文件因此无法提供帮助

    405:通知浏览器,在服务端已经定位到被访问的资源文件(Servlet)但是这个Servlet对于浏览器采用的请求方式不能处理

  5. 5XX

    在服务端已经定位到被访问的资源文件(Servlet)这个Servlet可以接收浏览器采用请求方式,但是Servlet在处理请求期间,由于Java异常导致处理失败

多个Servlet之间调用规则

某些来自于浏览器发送请求,往往需要服务端中多个Servlet协同处理。但是浏览器一次只能访问一个Servlet,导致用户需要手动通过浏览器发起多次请求才能得到服务。这样增加用户获得服务难度。

为了减少用户手动发送请求的次数,有2种解决方案:

  1. 重定向解决方案
  2. 请求转发解决方案

重定向解决方案

工作原理

image-20210302161412056

用户第一次通过【手动方式】通知浏览器访问OneServlet。OneServlet工作完毕后,将TwoServlet地址写入到响应头location属性中,导致Tomcat将302状态码写入到状态行。

在浏览器接收到响应包之后,会读取到302状态。此时浏览器自动根据响应头中location属性地址发起第二次请求,访问TwoServlet去完成请求中剩余任务

实现命令
// 将地址写入到响应包中响应头中location属性
response.sendRedirect("请求地址")
特征:
  1. 请求地址:

既可以把当前网站内部的资源文件地址发送给浏览器 (/网站名/资源文件名)也可以把其他网站资源文件地址发送给浏览器(http://ip地址:端口号/网站名/资源文件名)

  1. 请求次数:

    浏览器至少发送2次请求,但是只有第一次请求是用户手动发送。后续请求都是浏览器自动发送的。

  2. 请求方式:

重定向解决方案中,通过地址栏通知浏览器发起下一次请求,因此通过重定向解决方案调用的资源文件接收的请求方式一定是【GET】

  1. 缺点:

重定向解决方案需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间

请求转发解决方案

工作原理

image-20210302165205319

  1. 用户第一次通过手动方式要求浏览器访问OneServlet。

  2. OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet。

  3. Tomcat在接收到这个请求之后,自动调用TwoServlet来完成剩余任务

实现命令
//1.通过当前请求对象生成资源文件申请报告对象
RequestDispatcher report = request.getRequestDispatcher("/资源文件名");// 一定要以"/"为开头
//2.将报告对象发送给Tomcat
report.forward(当前请求对象,当前响应对象)
优点
  1. 无论本次请求涉及到多少个Servlet,用户只需要手动通过浏览器发送一次请求
  2. Servlet之间调用发生在服务端计算机上,节省服务端与浏览器之间往返次数增加处理服务速度
特征
  1. 请求次数

    在请求转发过程中,浏览器只发送一次请求

  2. 请求地址

    只能向Tomcat服务器申请调用当前网站下资源文件地址request.getRequestDispathcer("/资源文件名") 不要写网站名

  3. 请求方式

    在请求转发过程中,浏览器只发送一个了个Http请求协议包。参与本次请求的所有Servlet共享同一个请求协议包,因此这些Servlet接收的请求方式与浏览器发送的请求方式保持一致(get/post都可能)

两种解决方式特征对比汇总

重定向转发
请求次数浏览器发起多次请求浏览器发起一次请求
请求方式getget/post都行,与浏览器发送的请求方式保持一致(详细了解)
请求地址可以请求外部资源只能请求当前网站下的资源
时间成本时间开销大时间开销小

多个Servlet之间数据共享

Servlet规范中提供四种数据共享方案

1.ServletContext接口

2.Cookie类

3.HttpSession接口

4.HttpServletRequest接口

ServletContext接口:

介绍
  1. 来自于Servlet规范中一个接口。在Tomcat中存在servlet-api.jar在Tomcat中负责提供这个接口实现类

  2. 如果两个Servlet来自于同一个网站。彼此之间通过网站的ServletContext实例对象实现数据共享

  3. 开发人员习惯于将ServletContext对象称为==【全局作用域对象】==

工作原理:

image-20210302234435735

  1. 每一个网站都存在一个全局作用域对象。
  2. 这个全局作用域对象相当于一个Map.
  3. 在这个网站中OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他Servlet此时都可以从全局作用域对象得到这个数据进行使用
生命周期
  1. 在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象
  2. 在Http服务器运行期间,一个网站只有一个全局作用域对象
  3. 在Http服务器运行期间,全局作用域对象一直处于存活状态
  4. 在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理

全局作用域对象生命周期贯穿网站整个运行期间

命令实现
  • 存入值
public void doGet(HttpServletRequest request,HttpServletResponse response){
	//1.通过【请求对象】向Tomcat索要当前网站中【全局作用域对象】
	ServletContext application = request.getServletContext();
	//2.将数据添加到全局作用域对象作为【共享数据】
	application.setAttribute("key1",数据)
}
  • 获取值
public void doGet(HttpServletRequest request,HttpServletResponse response){
	//1.通过请求对象向Tomcat索要当前网站全局作用域对象
	ServletContext application = request.getServletContext();
	//2.从全局作用域对象得到指定关键字对应的值
	Integer money=(Integer)application.getAttribute("key1");
}
  • 潜规则:ServletContext对象都叫application
  • 取出是Object类型,要转型
注意的问题
  • 如果不加节制向全局作用域对象中写入数据,会严重占用服务器资源。
  • 开发中只有高级工程师才有资格决定哪些关键数据可以写入ServletContext

Cookie

介绍
  1. Cookie来自于Servlet规范中一个工具类,存在于Tomcat提供servlet-api.jar中
  2. 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享
  3. Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量
  4. 在现实生活场景中,Cookie相当于用户在服务端得到【会员卡】
工作原理

Cookie原理

  1. Web客户端通过浏览器向Web服务器发送连接请求,通过HTTP报文请求行中的URL打开某一Web页面。
  2. Web服务器接收到请求后,根据用户端提供的信息产生一个Set-Cookies Header
  3. 将生成的Set-Cookies Header通过Response Header存放在HTTP报文中回传给Web客户端,建立一次会话连接。
  4. Web客户端收到HTTP应答报文后,如果要继续已建立的这次会话,则将Cookies的内容从HTTP报文中取出,形成一个Cookies文本文件储存在客户端计算机的硬盘中或保存在客户端计算机的内存中。
  5. 当Web客户端再次向Web服务器发送连接请求时,Web客户端首先根据要访问站点的URL在本地计算机上寻找对应的Cookies文本文件或在本地计算机的内存中寻找对应的Cookies内容。如果找到,则将此Cookies内容存放在HTTP请求报文中发给Web服务器
  6. Web服务器接收到包含Cookies内容的HTTP请求后,检索其Cookies中与用户有关的信息,并根据检索结果生成一个客户端所请求的页面应答传递给客户端。
实现命令
  • 数据存入Cookie
public void doGet(HttpServletRequest request,HttpServletResponse resp){
    //1.创建一个cookie对象,保存共享数据(当前用户数据)
    Cookie card = new Cookie("key1","abc");
    Cookie card1= new Cookie("key2","efg");

    //2.将cookie写入到响应头,交给浏览器
    resp.addCookie(card);
    resp.addCookie(card1);
}

cookie相当于一个map

一个cookie中只能存放一个键值对

这个键值对的key与value只能是String

键值对中key不能是中文

  • 从Cookie取出数据
public void doGet(HttpServletRequest request,HttpServletResponse resp){
    // 1. 调用【请求对象】从【请求头】得到浏览器返回的Cookie
    Cookie[] cookieArray = request.getCookies();
    // 2. 循环遍历数据,得到每一个cookie的key和value
    for(Cookie cookie: cookieArray){
		String key = cookie.getName();
		String value = cookie.getValue();
    }
}
生命周期
  • 默认情况:浏览器关闭,Cookie对象销毁
  • 手动情况:Cookie可以持久化存在硬盘上。

设置生命周期:

cookie.setMaxAge(60)  // 60秒

HttpSession接口

介绍
  1. HttpSession接口来自于Servlet规范下一个接口。存在于Tomcat中servlet-api.jar其实现类由Http服务器提供。Tomcat提供实现类存在于servlet-api.jar

  2. 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于HttpSession对象进行数据共享(条件与Cookie一样)

  3. 开发人员习惯于将HttpSession接口修饰对象称为==【会话作用域对象】==

HttpSession 与 Cookie 区别:【面试题】
HttpSessionCookie
存储位置存放在服务端计算机内存存放在客户端计算机
数据类型可以存储任意类型的共享数据Object只能是String
数据数量HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据一个Cookie对象只能存储一个共享数据
参照物
命令实现
  • 存入数据
public void doGet(HttpServletRequest request,HttpServletResponse response){
    //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
    HttpSession session = request.getSession();
    //2.将数据添加到用户私人储物柜
    session.setAttribute("key1",共享数据)
}
  • 取出数据
public void doGet(HttpServletRequest request,HttpServletResponse response){
	//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
	HttpSession session = request.getSession();
	//2.从会话作用域对象得到OneServlet提供的共享数据
	Object 共享数据 = session.getAttribute("key1");
}
Http服务器如何将用户与HttpSession关联起来

image-20210304012022615

  • tomcat创建一个HttpSession时,也生成一个对应的id,并将id保存到Cookie中
  • Cookie: JSESSIONID=XXXX
  • 下次访问时通过Cookie来判断是哪个HttpSession

所以:如果知道一个Session的id,就可以在另一个浏览器中访问到共享的数据。

getSession() 与 getSession(false)
  • 俩个方法在有HttpSession时都返回HttpSession

  • 在没有HttpSession时,getSession()创建一个HttpSession。getSession(false)不创建HttpSession返回null

HttpSession销毁时机
  • Cookie丢失时,用户与HttpSession的关系切断。但HttpSession不会立即销毁。
  • HttpSession有一个空闲时间,默认30分钟。
HttpSession空闲时间手动设置

在当前网站/web/WEB-INF/web.xml

<session-config>
	<session-timeout>5</session-timeout> <!--当前网站中每一个session最大空闲时间5分钟-->
</session-config>

HttpServletRequest接口

介绍
  1. 在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用,彼此之间共享同一个请求协议包。

    而一个请求协议包只对应一个请求对象因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享

  2. 在请求对象实现Servlet之间数据共享功能时,开发人员将请求对象称为==【请求作用域对象】==

命令实现
  • 写入数据
public void doGet(HttpServletRequest req,HttpServletResponse response){
	//1.将数据添加到【请求作用域对象】中attribute属性
	req.setAttribute("key1",数据); //数据类型可以任意类型Object
	//2.向Tomcat申请调用TwoServlet
	req.getRequestDispatcher("/two").forward(req,response)
}
  • 取出数据
public void doGet(HttpServletRequest req,HttpServletResponse response){
	//从当前请求对象得到OneServlet写入到共享数据
	Object 数据 = req.getAttribute("key1");
}

最大空闲时间5分钟–>




### HttpServletRequest接口

#### 介绍

1. 在同一个网站中,如果两个Servlet之间通过【请求转发】方式进行调用,彼此之间共享同一个请求协议包。

	而一个请求协议包只对应一个请求对象因此servlet之间共享同一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享

2. 在请求对象实现Servlet之间数据共享功能时,开发人员将请求对象称为==【请求作用域对象】==



#### 命令实现

- 写入数据

```java
public void doGet(HttpServletRequest req,HttpServletResponse response){
	//1.将数据添加到【请求作用域对象】中attribute属性
	req.setAttribute("key1",数据); //数据类型可以任意类型Object
	//2.向Tomcat申请调用TwoServlet
	req.getRequestDispatcher("/two").forward(req,response)
}
  • 取出数据
public void doGet(HttpServletRequest req,HttpServletResponse response){
	//从当前请求对象得到OneServlet写入到共享数据
	Object 数据 = req.getAttribute("key1");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

。君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值