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. Java多线程开发系列之五:Springboot 中异步请求方法的使用

    Springboot 中异步线程的使用在过往的后台开发中,我们往往使用java自带的线程或线程池,来进行异步的调用.这对于效果来说没什么,甚至可以让开发人员对底层的状况更清晰,但是对于代码的易读性和可 ...

  2. Excel 统计函数(五):MINIFS 和 MAXIFS

    MINIFS [语法]MINIFS(min_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...) [参数] min ...

  3. Excel 统计函数(二):COUNTIF 和 COUNTIFS

    COUNTIF [语法]COUNTIF(range, criteria) [作用]range 为统计的范围,criteria 是统计的条件. [题目]统计 A1 到 A10 范围内,出现"你 ...

  4. Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

    Spring事务处理方式 方式1:注解式事务 使用@Transactional注解完成事务控制,此注解可添加到类上,则对类中所有方法执行事务的设定,注解添加到方法上,则对该方法执行事务处理 @Tran ...

  5. 搭建eBackup对接NFS服务

    环境准备 两个虚拟机需要是仅主机并且同一网段 先搭建一个eBackup环境虚拟机 搭建步骤可访问:(https://www.cnblogs.com/zhengyan6/p/16220774.html) ...

  6. HBase集群部署与基础命令

    HBase 集群部署 安装 hbase 之前需要先搭建好 hadoop 集群和 zookeeper 集群.hadoop 集群搭建可以参考:https://www.cnblogs.com/javammc ...

  7. Windows平台Unity3d播放多路RTMP或RTSP流

    好多开发者在做AR.VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大.而且周期长,不适合快速出产 ...

  8. 从Spring中学到的【1】--读懂继承链

    最近看了一些 Spring 源码,发现源码分析的文章很多,而底层思想分析的文章比较少,这个系列文章准备总结一下Spring中给我的启示,包括设计模式思想.SOLID设计原则等,涉及一些编程的基本原则, ...

  9. Exchange 2019中启用自动转发到外部域

    今天遇到一个用户反映自动转发的邮件规则没有生效.检查了一下,邮件规则配置没有问题.用户邮箱也能正常收到邮件,但是就是没有转发出去.仔细检查邮件规则,转发的收件人是外部邮箱.Exchange出于安全考虑 ...

  10. 在CentO7系统上配置Springboot项目jar包开机自启动

    官方文档地址:https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html#deployment-ins ...