Servlet

Servlet 简介


  • Servlet 是 Java提供的一门动态web资源开发技术

  • Servlet 是JavaEE 规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。

  • 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet


用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:

  1、编写一个Java类,实现servlet接口。

  2、把开发好的Java类部署到web服务器中。

Servlet 运行过程

Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:

①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。

  ②装载并创建该Servlet的一个实例对象。

  ③调用Servlet实例对象的init()方法。

  ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。

  ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

Servlet 生命周期

  • 对象的声明周期指一个对象从被创建到被销毁的整个过程

  • Servlet运行在Servlet 容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:

  1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
  2. 初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件,创建连接等初始化的工作。该方法只调用一次
  3. 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。
  4. 服务终止:当需要释放内存或容器关闭时,容器会调用Servlet示例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

通过配置改变Servlet实例化时机

@WebServlet(rulPatterns = "/demo",loadOnStartup = 1)
// 1 负整数:第一次被访问时创建Servlet对象
// 2 0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
public class ServletDemo1 implements Servlet{ }

Servlet 快速入门


  1. 导入坐标
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
  1. 创建一个Java类实现servlet接口
package com.itheima.web;

import javax.servlet.*;
import java.io.IOException; @WebServlet("/demo1") /*3.配置访问路径*/
public class ServletDemo1 implements Servlet{
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hallo Servlet~");
}
}
  1. 在原本的访问地址后面加上刚刚配置的路径

查看控制台会发现执行了刚刚我们写在java类中的service方法

Servlet 方法介绍


  • 初始化方法,在Servlet被创建时执行,只执行一次
void init(ServletConfig config)
  • 提供服务方法,每次Servlet被访问,都会调用该方法
void service(ServletRequset req,ServletResponse res)
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy()
  • 获取ServletConfig对象
ServletConfig getServletConflg()
  • 获取Servlet信息
String getServletInfo()

Servlet 体系结构


package com.itheima.web;

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("/demo1")
public class ServletDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}

总结:

  • HttpServlet 使用步骤
  1. 继承HttpServlet
  2. 重写doGet和doPost方法
  • HttpServlet 原理

    获取请求方法,并根据不同的请求方式,调用不同的doXxx方法

Servlet urlPatter配置


  • Servlet 要想被访问,必须配置其访问路径(urlPattern)

一个Servlet,可以配置多个 urlPattern

WebServlet(urlPatterns={"/demo1","/demo2"})

urlPattern 配置规则

① 精确匹配:

@WebServlet("/user/select") //配置路径
// 访问路径:localhost:8080/web-demo/user/select

② 目录匹配:

@WebServlet("/user/*") //配置路径
// 访问路径:localhost:8080/web-demo/user/aaa
// 访问路径:localhost:8080/web-demo/user/bbb

精确匹配的优先级比目录匹配是要高的

③ 匹配名匹配:

@WebServlet("*.do*") //配置路径
// 访问路径:localhost:8080/web-demo/aaa.do
// 访问路径:localhost:8080/web-demo/bbb.do

注意:匹配名匹配的配置路径中不得以/开头,否则就会报错

④ 任意匹配:

@WebServlet("/") //配置路径
@WebServlet("/*") //配置路径
// 访问路径:localhost:8080/web-demo/hehe
// 访问路径:localhost:8080/web-demo/haha
  • / 与 /*的区别:

    • 当我们的项目中的Servlet 配置了 "/",会覆盖掉tomcat中的DefaultServlet,当其他的 url-pattern都匹配不上时都会走着个Servlet

    • 当我们项目中配置了"/*",意味着匹配任意访问路径

基本不用:因为很危险

XML 配置方式编写 Servlet


  • Servlet 从3.0版本后开始支持使用注解配置,3.0版本前只支持 XML 配置文件的配置方式

  • 步骤:

    • 1.编写Servlet类
    • 2.在web.xml中配置该Servlet
<servlet>
<servlet-name>demo5<servlet-name>
<servlet-class>com.itheima.web.servlet.ServletDemo5<servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo5</servlet-name>
<url-pattern>/demo5</url-pattern>
</servlet-mapping>

这是旧版的配置方式了解就好

Request(请求) &Response(响应)




Web浏览器发送HTTP请求到Web服务器,而请求数据就是一些字符串,字符串会被Tomcat解析,解析完后其实tomcat就会将数据存在request对象中

requset对象保存了请求解析后的数据

在处理完请求的数据后,我们需要对用户进行响应,然后浏览器接受将数据展示在页面上。Tomcat会发送一些响应的字符串,而这些响应的字符串就在 respons中

response对象保存了响应时的数据

于是将来我们就可以拿来做一些事情:

  • Requset:获取请求数据
  • Response:设置响应数据

Requset(请求)

Requset 继承体系


  1. Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
  2. 使用request对象,查阅javaEE API文档的HttpServletRequest接口

Requset 获取请求数据


请求数据分为三部分:

  1. 请求行:GET/request-demo/req1?username=zhangsan HTTP/1.1

    • String getMethod(); 获取请求方式:GET
    • String getContextPath(); 获取虚拟目录(项目访问路径):/request-demo
    • StringBuffer getRequestURL(); 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
    • String getRequestURL(); 获取URL(统一资源标识符):/request-demo/req1
    • String getQueryString(); 获取请求参数(GET方式):username=zhangsan&password=123
  2. 请求头:User-Agent:Mozilla/5.0 Chorme/91.0.4472.106

    • String getHeader(String name):根据请求头名称,获取值
  3. 请求体:username=superbaby&password=123

    • ServletinputStream getinputStream():获取字节输入流
    • BufferedReader getReader():获取字符输入流

Requset 通用获取请求参数的方式

当HTTP请求发送过来时,系统会自动帮我们将数据截断,放入一个键值队Map数据里,且对于相同键的数据不会覆盖,而是以数组的形式存储,所以这个Map 定义为 Map<String,String[]>我们可以通过这个Map获取到我们想要的数据

  • Map<String,string[]> getParameterMap():获取所以参数Map集合
  • String[] getparameterValues(String name):根据名称获取参数值(数组)
  • String getParameter(String name):根据名称获取参数值(单个值)

Requset 中文乱码解决方案

  • 请求参数存在中文数据,则会乱码

  • 乱码原因:编解码字符集不一致

  • URL编码

    1.将字符串按照编码方式转为二进制

    2.每个字符转为2个16进制数并在前面加上%

  • 解决方案:

    • POST:设置输入流的编码
    req.setCharacterEncoding("UTF-8");
    • 通用方式(GET/POST):先解码,再编码
    new String(username.getBytes("ISO-8859-1"),"UTF-8");
  • URL编码实现方式:

    • 编码
    URLEncoder.encode(str,"utf-8");
    • 解码
    URLDecoedr.decode(s,"ISO-8859-1");

Tomcat8 之后其实就已经解决了中文乱码问题

Request 请求转发

说的是一种在服务器内部的资源跳转方式

  • 实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用Request对象

    • void setAttribute(String name,Object o):存储数据到 request 域中
    • Object getAttribute(String name):根据 key,获取值
    • void removeAttribute(String name):根据key,删除该键值对
  • 请求转发特点:

    • 浏览器资源栏路径不发生变化
    • 只能转发到当前服务器的内部资源
    • 一次请求,可以在转发的资源间使用request共享数据

Response(响应)

Response 设置响应数据功能

  • 响应数据分为3部分:

    • 响应行:HTTP/1.1 200 OK
    void setStatus(int sc); //设置响应状态码
    • 响应头:Content-Type:text/html
    void setHeader(String name,String value); //设置响应头键值对
    • 响应体:<html><head><body></body></head></html>
    PrintWriter getWriter(); //获取字符输出流
    ServletOutputStream getOutputStream(); //获取字节输出流

Response 重定向

说的是一种资源调整方式:当服务器处理不了浏览器的请求,但其他资源可以处理请求时,会返回状态码以及其他资源的响应头给浏览器。浏览器拿到状态码和资源路径就会将请求发送给指定资源处理

实现方式:

// 1.设置响应状态码
resp.setStatus(302);
// 2.设置响应头
resp.setHeader("location","资源B的路径"); // 简化写法
resp.sendRedirect("资源B的路径");

会化跟踪技术


  • 会话:用户打开浏览器,访问web浏览器的资源,会话建立,直到有一方断开连接,会话结束,在一次会话中可以包含多次请求和响应

  • 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多个请求间共享数据

  • Http协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享

  • 实现方式:

    1.客户端会话跟踪技术:Cookie

    2.服务端会话跟踪技术:Session

Cookie


客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问

Cookie 基本使用

  • 发送Cookie
// 1. 创建Cookie对象,设置数据
Cookie cookie = new Cookle("key","value"); // 2. 发送Cookie到客户端:使用response对象
response.addCookle(cookie);
  • 获取Cookie
// 1. 获取客户端携带的所有Cookie,使用request对象
Cookie[] cookies=request.getCookies(); // 2. 遍历数组,获取每个Cookie对象:for
// 3. 使用Cookie对象方法获取数据
cookie.getName();
cookie.getValue();

Cookie 原理

Cookie 的实现是基于HTTP协议的

  • 响应头:set-cookie
  • 响应体:cookie

Cookie 使用细节

  • Cookie 存活时间

    • 默认情况下,Cookie 存储在浏览器内存中,当然浏览器关闭,内存释放,则Cookie销毁
    • setMaxAge(int seconds):设置Cookie存活时间

      1.正数:将 Cookie写入浏览器所在电脑的硬盘,持久化存储,到时间自动删除

      2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁

      3.零:删除对应 Cookie

Cookie 不能直接存储中文,如果需要存储,则需要进行转码:URL 转码

String value="张三";
//URL编码
value = URLEncoder.encode(value,"UTF-8"); Cookie cookie = new Cookie("username",value); //URL解码
value = URLDecoder.decode(value,"UTF-8");

Session


服务端会话跟踪技术,将数据保存到服务端,这其实是一种比较不安全的方式。因为数据往返频繁有被截取拦截的风险。

JavaEE 提供 HttpSession接口,来实现一次会话的多次请求间数据的共享功能

//1.获取Session对象
HttpSession session =request.getSession();
//2.Session对象功能:
void setAttribute(String name,Object o);//存储数据到 session 域中
Object getAttribute(String name);//根据 key,获取值
void removeAttribute(String name);//根据 key,删除该键值对

Seesion 原理

Seesion 的实现是基于cookie

Seesion 使用细节

Filter

Filter 概念


Filter 表示过滤器,是Javaweb 三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。过滤器一般完成一些通用的操作,比如:权限控制、统一编码处理、敏感字处理等等...

Filter 快速入门


//1. 定义类,实现 Filter接口,并重写其所有方法
public class FilterDemo implements Filter{
public void init(FilterConfig filterConfig)
public void doFilter(ServletRequest request)
public void destroy(){}
// 核心方法:doFilter 每次访问Filter时都会执行
} //2. 配置Filter拦截资源的路径:在类上定义@WebFilter 注解
@WebFilter("/*")
public class FilterDemo implements Filter{ //3. 在doFilter方法中输出一句话,并放行
public void doFilter(ServletRequest request,Ser){
System.out.println("filter 被执行了...");
//放行
chain.doFilter(request,response);
}

Filter 执行逻辑


  • 执行放行前逻辑 -> 放行 -> 访问资源 -> 执行放行后逻辑

Filter 使用细节


Filter 拦截路径配置

  • Filter 可以根据需求,配置不同的拦截路径
@WebFilter("/*")
public class FilterDemo // 拦截具体的资源:/index.jsp:只访问index.jsp时才会被拦截
// 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
// 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
// 拦截所有:/*:访问所有资源,都会被拦截

Filter 过滤器链

一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤链



注释配置的Filter,优先级按照过滤器类名(字符串)的自然排序

Listener

Listener 介绍


Listener 表示监听器,是JavaWeb三大组件(Servlet、Filter、Listener)之一。监听器可以监听就是application,session,request三个对象创建、销毁、或者往其中添加修改删除属性时自动执行代码的功能组件

Listener 分类


监听器分类 监听器名称 作用
ServletContext监听 ServletContextListener 用于对ServletContext对象进行监听(创建、销毁)
ServletContextAttributeListener 对ServletContext对象中属性的监听(增删改属性)
Session监听 HttpSessionListener 对Session对象的整体状态的监听(创建、销毁)
HttpSessionAttributerListener 对Session对象中的属性监听(增删改属性)
HttpSessionBindingListener 监听对象于Session的绑定和解除
HttpSessionActivationListener 对Session数据的钝化和活化的监听
Request监听 ServletRequestListener 对Request对象中属性进行监听(创建、销毁)
ServletRequestAttributeListener 对Request对象中属性的监听(增删改属性)

ServletContextListener 使用

监听器主要就是使用这个监听器

//2.在类上添加@WebListener注解
@WebListener
public class ContextLoaderListener implements ServletContextListener{
//1. 定义类,实现ServletContextListener接口
/**
* ServletContext 对象被创建:整个web应用发布成功
* @param sce
*/
public void contextInitialized(ServletContextEvent sce) {}
/**
* ServletContext 对象被销毁:整个web应用卸载
* @param sce
*/
public void contextDestroyed(ServletContextEvent sce) {}
}

【JavaWeb】学习笔记——Servlet、Filter、Listenter的更多相关文章

  1. JavaWeb学习笔记--Servlet代码集

    目录: 登录系统提交表单数据打开PDFCookieURL传递参数URL重写跟踪会话使用HttpSession对象跟踪会话Servlet间协作过滤器Filter 登录系统 <!DOCTYPE HT ...

  2. JavaWeb学习笔记总结 目录篇

    JavaWeb学习笔记一: XML解析 JavaWeb学习笔记二 Http协议和Tomcat服务器 JavaWeb学习笔记三 Servlet JavaWeb学习笔记四 request&resp ...

  3. javaweb学习笔记整理补课

    javaweb学习笔记整理补课 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务器端 * 在用户本地有一个客户端 ...

  4. JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...

  5. JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下)

    JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下) Reference

  6. (转)JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...

  7. JavaWeb学习——了解Servlet

    JavaWeb学习——了解Servlet 摘要:本文主要学习了什么是Servlet,以及如何使用Servlet进行开发. 基础知识 背景 随着互联网技术的发展,基于HTTP和HTML的web应用急速增 ...

  8. Javaweb学习笔记——(二十一)——————过滤器

    过滤器     过滤器概述         1.什么是过滤器:             过滤器javaweb三大组件之一,它与Serlvet很相似,不过它过滤器是用来拦截请求的,而不是处理       ...

  9. javaweb学习之Servlet开发(二)

    javaweb学习总结(六)--Servlet开发(二) 一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个< ...

  10. 【JAVAWEB学习笔记】13_servlet

    JavaWeb核心之Servlet 教学目标 案例一.完成用户登录功能 案例二.记录成功登录系统的人次 一.Servlet简介 1.什么是Servlet Servlet 运行在服务端的Java小程序, ...

随机推荐

  1. 就在明天,Apache DolphinScheduler Meetup 2021 如约而至!

    点击上方 蓝字关注我们 社区的小伙伴们,Apache DolphinScheduler Meetup 2021 如约而至,就在明天,等你来玩! 在此次 Meetup 线上直播中,不仅将有来自 Bigo ...

  2. LuoguP1240 诸侯安置

    本来是来练组合的,不知怎么又开始水普及DP了 #include <cstdio> #include <iostream> #include <cstring> #i ...

  3. Luogu2869 [USACO07DEC]美食的食草动物Gourmet Grazers (贪心,二分,数据结构优化)

    贪心 考场上因无优化与卡常T掉的\(n \log(n)\) //#include <iostream> #include <cstdio> #include <cstri ...

  4. Spring源码 18 IOC refresh方法13

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  5. 常用类--String

    一.String 1.1 String是不可变对象 String的底层是一个 char类型字符数组 String类是final修饰的,不能被继承,不能改变,但引用可以重新赋值 String采用的编码方 ...

  6. CSS 子节点继承父节点(祖先节点)的样式

    CSS 有些属性可以让子节点从父节点或祖先节点继承,文本.字体.列表属性等样式都可以被子节点继承.子节点没有自身的样式,子节点将继承父节点或祖先节点的样式. <ul class="co ...

  7. 有意思的方向裁切 overflow: clip

    本文将介绍一个新特性,从 Chrome 90 开始,overflow 新增的一个新特性 -- overflow: clip,使用它,轻松的对溢出方向进行控制. overflow: clip 为何 首先 ...

  8. 「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心)

    题面 来源 「 雅 礼 集 训 2017 D a y 7 」 跳 蚤 王 国 的 宰 相   传 统 2000   m s 1024   M i B {\tt「雅礼集训 2017 Day7」跳蚤王国的 ...

  9. 简单创建一个SpringCloud2021.0.3项目(三)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上俩篇教程 3. Gateway集成sentinel,网关层做熔断降级 1. 超时熔断降级 2. 异常熔断 3. 集成sentine ...

  10. 宝塔面板服务器ip地址修改域名

    参考博客:请点击百度 今天登录宝塔面板是突然忘记了服务器IP地址,从而导致了以下这种情况. 其实我以前是买过一个域名的,但是并没有绑定到宝塔上面.从而就一直拿IP登录宝塔面版.现在用命令方式更换域名, ...